Spaces:
Sleeping
Sleeping
File size: 6,810 Bytes
b10b6fd 0ce2aaa b10b6fd 0ce2aaa b10b6fd f72945a b10b6fd 423e2c9 b10b6fd 423e2c9 b10b6fd f72945a b10b6fd 0ce2aaa b10b6fd 0ce2aaa b10b6fd f72945a b10b6fd f72945a b10b6fd 0ce2aaa b10b6fd f72945a b10b6fd f72945a 0ce2aaa f72945a 0ce2aaa b10b6fd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
from typing import *
import httpx
from mcp.server.fastmcp import FastMCP
server = FastMCP(name="streamable-http-mcp-server-test", json_response=False, stateless_http=False)
async def make_request(url: str, method: Literal["GET", "POST"], data: Dict[str, Any] = {}):
headers = {"Accept": "application/json"}
async with httpx.AsyncClient(verify=False) as client:
try:
if method == "GET":
response = await client.get(url, headers=headers)
elif method == "POST":
response = await client.post(url, headers=headers, json=data)
else:
print("Method not allowed !")
return None
response.raise_for_status()
return response.json()
except:
return None
# arXiv
@server.tool()
async def search_academic_papers_arxiv(keyword: str, limit: int = 5) -> str:
"""
Search papers from arXiv database with specified keywords [optional: a limit of papers the user wants]
Args: keyword: string, [optional: limit: integer, set limit to 5 if not specified]
"""
response = await make_request("https://organizedprogrammers-arxiv.hf.space/search", "POST", {"keyword": keyword, "limit": limit})
if not response:
return "Unable to find papers | No papers has been found"
return "\n".join([f"arXiv n°{paper_id} - {paper_meta['title']} by {paper_meta['authors']} : {paper_meta['abstract']}" for paper_id, paper_meta in response['message'].items()])
@server.tool()
async def get_arxiv_pub_text(arxiv_id: str) -> str:
"""
Extract publication PDF via arXiv ID
Returns the full content of the publication
Args: arxiv_id -> string
"""
response = await make_request("https://organizedprogrammers-arxiv.hf.space/extract_pdf/arxiv_id", "POST", {"doc_id": arxiv_id})
if not response:
return "Unable to extract PDF | arXiv PDF not found"
return response["message"]["text"]
# DocFinder
@server.tool()
async def get_document_url(doc_id: str) -> str:
"""
Find technical document or specification from 3GPP / ETSI / GP by a document ID
Returns the URL (also scope + version if doc is a specification [not all specifications have a version or scope])
Arguments: doc_id -> string
"""
response = await make_request('https://organizedprogrammers-docfinder.hf.space/find/single', "POST", {"doc_id": doc_id})
if not response:
return "Unable to find document/specification"
version = response.get('version', 'unavailable')
scope = response.get('scope', 'unavailable')
return f'Downloadable !\nDoc No. {doc_id}\nURL : {response.get("url")}\nVersion : {version}\nScope : {scope}'
@server.tool()
async def search_specifications_with_keywords(keywords: str, threshold: int = 60, source: Literal["3GPP", "ETSI", "all"] = "all", spec_type: Optional[Literal["TS", "TR"]] = None):
"""
Search specifications from 3GPP and/or ETSI with keywoeds (Based off BM25 scoring)
Returns a list of specifications metadata that matches the similarity score threshold, the keywords, the source and specification type
Arguments:
- keywords -> string
- threshold -> integer (by default, set to 60) [between 0-100]
- source -> string (either '3GPP', 'ETSI' or 'all', by default, set to 'all')
- spec_type -> string (either 'TS' or 'TR' or None, by default, set to None)
"""
response = await make_request('https://organizedprogrammers-docfinder.hf.space/search/bm25', "POST", {"keywords": keywords, "threshold": threshold, "source": source, "spec_type": spec_type})
if not response:
return "Unable to search specifications | No specifications has been found"
results = response["results"]
return "\n---\n".join([f"Specification ID: {spec['id']}\nTitle: {spec['title']}\nType: {'Technical Specification' if spec['spec_type'] == 'TS' else 'Technical Report'}\nVersion: {spec.get('version', 'unavailable')}\nScope: {spec.get('scope', 'unavailable')}\nWorking Group: {spec.get('working_group', 'not defined')}\nURL: {spec.get('url', 'unavailable')}" for spec in results])
# SpecSplitter
@server.tool()
async def get_spec_text(spec_id: str) -> str:
"""
Extract specification from 3GPP or ETSI
Returns a dictionary k:v where k is the section (1., 2.2.1, ...) and v, the content of k, or a string if failed
Args: spec_id -> string
"""
response = await make_request('https://organizedprogrammers-specsplitter.hf.space/extract_text/structured', "POST", {"spec_id": spec_id})
if not response:
return "Unable to extract specification text"
return "\n".join([f"{k}: {v}" for k, v in response.keys()])
# SERPent
@server.tool()
async def search_google_patents(queries: List[str], n_results: int) -> str:
"""
Search patents from Google Patents
You can generate multiple queries (at least 1)
Returns a list of patents from queries, for each query, {n_results} patents will be retrieved
Args: queries -> list of string, n_results -> integer [by default: 10]
"""
response = await make_request("https://organizedprogrammers-serpent.hf.space/serp/search_patents", "POST", {"queries": queries, "n_results": n_results})
if not response:
return "Unable to fetch patents"
return "\n".join(f"[Patent ID: {patent['id']} | Title: {patent['title']} | Body: {patent['body']}]" for patent in response.results)
@server.tool()
async def scrap_google_patents(patent_ids: List[str]) -> str:
"""
Scrap patents from one or many patents from Google Patents
Returns a list of patents with their title, abstract, description, claims, field of invention and background
Args: patent_ids -> list of strings corresponding to Google Patent ID [min. 1]
"""
if len(patent_ids) > 1:
response = await make_request("https://organizedprogrammers-serpent.hf.space/scrap/scrap_patents_bulk", "POST", {"patent_ids": patent_ids})
if not response:
return "Unable to scrap patents"
return "\n---\n".join([f"Title: {pat['title']}\nAbstract: {pat['abstract']}\nDescription: {pat['description']}\nClaims: {pat['claims']}\nField of invention{pat['field_of_invention']}\nBackground: {pat['background']}" for pat in response['patents']])
elif len(patent_ids) == 1:
response = await make_request("https://organizedprogrammers-serpent.hf.space/scrap/scrap_patent/"+patent_ids[0], "GET")
if not response:
return "Unable to scrap patent"
return f"Title: {response['title']}\nAbstract: {response['abstract']}\nDescription: {response['description']}\nClaims: {response['claims']}\nField of invention{response['field_of_invention']}\nBackground: {response['background']}"
app = server.streamable_http_app |