Skip to main content
Glama
server.py32.8 kB
from asyncio import to_thread from mcp import types from typing import List, get_origin, Callable, Any import json from mcp.server.fastmcp import FastMCP from mcp.server.fastmcp.tools import Tool from mcp.types import ToolAnnotations import inspect from mcp.server.fastmcp.utilities.func_metadata import ( _get_typed_signature, _get_typed_annotation, ArgModelBase, FuncMetadata, ) from typing import Awaitable from collections.abc import Awaitable, Callable, Sequence from typing import ( Annotated, ) from pydantic import Field, WithJsonSchema, create_model from pydantic.fields import FieldInfo from pydantic_core import PydanticUndefined from mcp.server.fastmcp.exceptions import InvalidSignature from typing import Sequence from tools.tooluniverse import ToolUniverse tn = ToolUniverse() tn.load_tools() class MyFuncMetaData(FuncMetadata): async def call_fn_with_arg_validation( self, fn: Callable[..., Any] | Awaitable[Any], fn_is_async: bool, arguments_to_validate: dict[str, Any], arguments_to_pass_directly: dict[str, Any] | None, ) -> Any: arguments_parsed_dict = arguments_to_validate if fn_is_async: if isinstance(fn, Awaitable): return await fn return await fn(**arguments_parsed_dict) if isinstance(fn, Callable): return fn(**arguments_parsed_dict) raise TypeError("fn must be either Callable or Awaitable") def func_metadata( func: Callable[..., Any], skip_names: Sequence[str] = () ) -> FuncMetadata: """Given a function, return metadata including a pydantic model representing its signature. The use case for this is ``` meta = func_to_pyd(func) validated_args = meta.arg_model.model_validate(some_raw_data_dict) return func(**validated_args.model_dump_one_level()) ``` **critically** it also provides pre-parse helper to attempt to parse things from JSON. Args: func: The function to convert to a pydantic model skip_names: A list of parameter names to skip. These will not be included in the model. Returns: A pydantic model representing the function's signature. """ sig = _get_typed_signature(func) params = sig.parameters dynamic_pydantic_model_params: dict[str, Any] = {} globalns = getattr(func, "__globals__", {}) for param in params.values(): if param.name.startswith("_"): raise InvalidSignature( f"Parameter {param.name} of {func.__name__} cannot start with '_'" ) if param.name in skip_names: continue annotation = param.annotation # `x: None` / `x: None = None` if annotation is None: annotation = Annotated[ None, Field( default=( param.default if param.default is not inspect.Parameter.empty else PydanticUndefined ) ), ] # Untyped field if annotation is inspect.Parameter.empty: annotation = Annotated[ Any, Field(), # 🤷 WithJsonSchema({"title": param.name, "type": "string"}), ] field_info = FieldInfo.from_annotated_attribute( _get_typed_annotation(annotation, globalns), ( param.default if param.default is not inspect.Parameter.empty else PydanticUndefined ), ) dynamic_pydantic_model_params[param.name] = (field_info.annotation, field_info) continue arguments_model = create_model( f"{func.__name__}Arguments", **dynamic_pydantic_model_params, __base__=ArgModelBase, ) resp = MyFuncMetaData(arg_model=arguments_model) return resp # 因为FastMCP的封装add_tool无法指定parameters,所以把一些代码copy出来重写 def from_function( fn: Callable[..., Any], name: str | None = None, description: str | None = None, parameters: Any = None, context_kwarg: str | None = None, annotations: ToolAnnotations | None = None, ) -> Tool: """Create a Tool from a function.""" from mcp.server.fastmcp.server import Context func_name = name or fn.__name__ if func_name == "<lambda>": raise ValueError("You must provide a name for lambda functions") func_doc = description or fn.__doc__ or "" is_async = inspect.iscoroutinefunction(fn) if context_kwarg is None: sig = inspect.signature(fn) for param_name, param in sig.parameters.items(): if get_origin(param.annotation) is not None: continue if issubclass(param.annotation, Context): context_kwarg = param_name break func_arg_metadata = func_metadata( fn, skip_names=[context_kwarg] if context_kwarg is not None else [], ) if parameters is None: parameters = func_arg_metadata.arg_model.model_json_schema() # func_arg_metadata.call_fn_with_arg_validation = call_fn_with_arg_validation # print("model dump", func_arg_metadata.arg_model.model_dump()) return Tool( fn=fn, name=func_name, description=func_doc, parameters=parameters, fn_metadata=func_arg_metadata, is_async=is_async, context_kwarg=context_kwarg, annotations=annotations, ) def get_all_tools(tools: List): all_tools = [] for t in tools: input_schema = t["parameter"] parameters = input_schema tool = from_function( get_func(t["name"]), name=t["name"], description=t["description"], parameters=parameters, ) all_tools.append(tool) return all_tools def get_func(name: str): async def f(**arguments): def run(): result = tn.run( { "name": name, "arguments": arguments, } ) if type(result) != str: result = json.dumps(result) return types.TextContent(type="text", text=str(result)) return await to_thread(run) return f fda_drug_mcp = FastMCP( name="fda_drug_mcp", tools=get_all_tools(tn.tool_category_dicts["fda_drug_label"]), stateless_http=True, ) monarch_mcp = FastMCP( name="monarch_mcp", tools=get_all_tools(tn.tool_category_dicts["monarch"]), stateless_http=True, ) opentargets_mcp = FastMCP( name="opentargets_mcp", tools=get_all_tools(tn.tool_category_dicts["opentarget"]), stateless_http=True, ) @opentargets_mcp.tool() async def get_general_info_by_disease_name(name: str): """ Get disease EFO ID and description by disease name from OpenTargets. Description information will include disease name, EFO ID, disease targets, related drugs and related disease phenotypes. Args: name: The disease name to search for Returns: Dictionary containing disease ID and related information including targets, drugs and phenotypes """ final_result = {} final_result["disease_name"] = name # Get disease EFO ID result = tn.run( { "name": "get_disease_id_description_by_name", "arguments": {"diseaseName": name}, } ) try: efoId = result["data"]["search"]["hits"][0]["id"] final_result["efoId"] = efoId except Exception as e: print(e) return final_result # Get disease targets information raw_target_info = tn.run( { "name": "get_associated_targets_by_disease_efoId", "arguments": {"efoId": efoId}, } ) try: final_result["disease_targets"] = raw_target_info["data"]["disease"][ "associatedTargets" ].get("rows", []) except Exception as e: print(e) final_result["disease_targets"] = [] # Get disease associated drugs information raw_drug_info = tn.run( { "name": "get_associated_drugs_by_disease_efoId", "arguments": {"efoId": efoId, "size": 10}, } ) try: final_result["disease_drugs"] = raw_drug_info["data"]["disease"][ "knownDrugs" ].get("rows", []) except Exception as e: print(e) final_result["disease_drugs"] = [] # Get disease associated phenotypes information raw_phenotype_info = tn.run( { "name": "get_associated_phenotypes_by_disease_efoId", "arguments": {"efoId": efoId}, } ) try: final_result["disease_phenotypes"] = raw_phenotype_info["data"]["disease"][ "phenotypes" ].get("rows", []) except Exception as e: print(e) final_result["disease_phenotypes"] = [] return final_result @opentargets_mcp.tool() async def get_target_ensembl_id(target_name: str): """ Get target Ensembl ID by target name. Args: target_name: The target name to search for """ result = tn.run({ "name": "get_target_id_description_by_name", "arguments": {"targetName": target_name} }) try: return result['data']['search']['hits'][0]['id'] except: return None @opentargets_mcp.tool() async def get_disease_efo_id(disease_name: str): """ Get disease EFO ID by disease name. Args: disease_name: The disease name to search for """ result = tn.run({ "name": "get_disease_id_description_by_name", "arguments": {"diseaseName": disease_name} }) try: return result['data']['search']['hits'][0]['id'] except: return None @opentargets_mcp.tool() async def get_drug_chembl_id_by_name(drug_name: str): """ Find drug ChEMBL ID by drug name. Args: drug_name: The drug name to search for Query example: {"drug_name": "aspirin"} """ result = tn.run({ "name": "get_drug_id_description_by_name", "arguments": {"drugName": drug_name} }) try: return result['data']['search']['hits'][0]['id'] except: return None @opentargets_mcp.tool() async def get_associated_targets_by_disease_name(disease_name: str): """ Find targets associated with a specific disease or phenotype based on its name. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_associated_targets_by_disease_efoId", "arguments": {"efoId": efo_id} }) return result @opentargets_mcp.tool() async def get_associated_diseases_phenotypes_by_target_name(target_name: str): """ Find diseases or phenotypes associated with a specific target. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_associated_diseases_phenotypes_by_target_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_target_disease_evidence_by_name(target_name: str, disease_name: str): """ Explore evidence that supports a specific target-disease association. Input is disease name and target name. Args: target_name: The target name to search for disease_name: The disease name to search for Query example: {"target_name": "BRCA1", "disease_name": "Breast cancer"} """ target_ensembl_id = await get_target_ensembl_id(target_name) efo_id = await get_disease_efo_id(disease_name) if target_ensembl_id is None or efo_id is None: result = 'No target or disease found' else: result = tn.run({ "name": "target_disease_evidence", "arguments": {"ensemblId": target_ensembl_id, "efoId": efo_id} }) return result @opentargets_mcp.tool() async def get_drug_warnings_by_name(drug_name: str): """ Retrieve warnings for a specific drug. Args: drug_name: The drug name to search for Query example: {"drug_name": "aspirin"} """ chembl_id = await get_drug_chembl_id_by_name(drug_name) if chembl_id is None: result = 'No drug found' else: result = tn.run({ "name": "get_drug_warnings_by_chemblId", "arguments": {"chemblId": chembl_id} }) return result @opentargets_mcp.tool() async def get_drug_mechanisms_of_action_by_name(drug_name: str): """ Retrieve the mechanisms of action associated with a specific drug. Args: drug_name: The drug name to search for Query example: {"drug_name": "aspirin"} """ chembl_id = await get_drug_chembl_id_by_name(drug_name) if chembl_id is None: result = 'No drug found' else: result = tn.run({ "name": "get_drug_mechanisms_of_action_by_chemblId", "arguments": {"chemblId": chembl_id} }) return result @opentargets_mcp.tool() async def get_associated_drugs_by_disease_name(disease_name: str): """ Retrieve known drugs associated with a specific disease by disease name. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_associated_drugs_by_disease_efoId", "arguments": {"efoId": efo_id, "size": 10} }) return result @opentargets_mcp.tool() async def get_similar_entities_by_disease_name(disease_name: str): """ Retrieve similar entities for a given disease using a model trained with PubMed. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_similar_entities_by_disease_efoId", "arguments": {"efoId": efo_id, "threshold": 0.2, "size": 10} }) return result @opentargets_mcp.tool() async def get_similar_entities_by_drug_name(drug_name: str): """ Retrieve similar entities for a given drug using a model trained with PubMed. Args: drug_name: The drug name to search for Query example: {"drug_name": "aspirin"} """ chembl_id = await get_drug_chembl_id_by_name(drug_name) if chembl_id is None: result = 'No drug found' else: result = tn.run({ "name": "get_similar_entities_by_drug_chemblId", "arguments": {"chemblId": chembl_id, "threshold": 0.2, "size": 10} }) return result @opentargets_mcp.tool() async def get_similar_entities_by_target_name(target_name: str): """ Retrieve similar entities for a given target using a model trained with PubMed. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_similar_entities_by_target_ensemblID", "arguments": {"ensemblId": target_ensembl_id, "threshold": 0.2, "size": 10} }) return result @opentargets_mcp.tool() async def get_associated_phenotypes_by_disease_name(disease_name: str): """ Find HPO phenotypes asosciated with the specified disease. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_associated_phenotypes_by_disease_efoId", "arguments": {"efoId": efo_id} }) return result @opentargets_mcp.tool() async def get_drug_indications_by_name(drug_name: str): """ Fetch indications (treatable phenotypes/diseases) for a given drug. Args: drug_name: The drug name to search for Query example: {"drug_name": "aspirin"} """ chembl_id = await get_drug_chembl_id_by_name(drug_name) if chembl_id is None: result = 'No drug found' else: result = tn.run({ "name": "get_drug_indications_by_chemblId", "arguments": {"chemblId": chembl_id} }) return result @opentargets_mcp.tool() async def get_target_gene_ontology_by_name(target_name: str): """ Retrieve Gene Ontology annotations for a specific target. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_gene_ontology_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_target_homologues_by_name(target_name: str): """ Fetch homologues for a specific target. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_homologues_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_target_safety_profile_by_name(target_name: str): """ Retrieve known target safety liabilities for a specific target. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_safety_profile_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_biological_mouse_models_by_target_name(target_name: str): """ Retrieve biological mouse models, including allelic compositions and genetic backgrounds, for a specific target. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_biological_mouse_models_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_target_genomic_location_by_name(target_name: str): """ Retrieve genomic location data for a specific target, including chromosome, start, end, and strand. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_genomic_location_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_target_subcellular_locations_by_name(target_name: str): """ Retrieve information about subcellular locations for a specific target. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_subcellular_locations_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_target_synonyms_by_name(target_name: str): """ Retrieve synonyms for specified target, including alternative names and symbols. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_synonyms_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_target_tractability_by_name(target_name: str): """ Retrieve tractability assessments, including modality and values. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_tractability_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_target_classes_by_name(target_name: str): """ Retrieve the target classes associated with a specific target. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_classes_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_target_enabling_packages_by_name(target_name: str): """ Retrieve the Target Enabling Packages (TEP) associated with a specific target. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_enabling_packages_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_target_interactions_by_name(target_name: str): """ Retrieve interaction data for a specific target, including interaction partners and evidence. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_interactions_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_disease_ancestors_parents_by_name(disease_name: str): """ Retrieve the ancestors and parents of a specific disease. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_disease_ancestors_parents_by_efoId", "arguments": {"efoId": efo_id} }) return result @opentargets_mcp.tool() async def get_disease_descendants_children_by_name(disease_name: str): """ Retrieve the descendants and children of a specific disease. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_disease_descendants_children_by_efoId", "arguments": {"efoId": efo_id} }) return result @opentargets_mcp.tool() async def get_disease_locations_by_name(disease_name: str): """ Retrieve the locations of a specific disease. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_disease_locations_by_efoId", "arguments": {"efoId": efo_id} }) return result @opentargets_mcp.tool() async def get_disease_synonyms_by_name(disease_name: str): """ Retrieve synonyms for a specific disease. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_disease_synonyms_by_efoId", "arguments": {"efoId": efo_id} }) return result @opentargets_mcp.tool() async def get_disease_description_by_name(disease_name: str): """ Retrieve the description of a specific disease. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_disease_description_by_efoId", "arguments": {"efoId": efo_id} }) return result @opentargets_mcp.tool() async def get_disease_therapeutic_areas_by_name(disease_name: str): """ Retrieve the therapeutic areas associated with a specific disease. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_disease_therapeutic_areas_by_efoId", "arguments": {"efoId": efo_id} }) return result @opentargets_mcp.tool() async def get_chemical_probes_by_target_name(target_name: str): """ Retrieve chemical probes associated with a specific target. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_chemical_probes_by_target_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_associated_drugs_by_target_name(target_name: str): """ Get known drugs associated with a specific target, including clinical trial phase and mechanism of action of the drugs. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_associated_drugs_by_target_ensemblID", "arguments": {"ensemblId": target_ensembl_id, "size": 10} }) return result @opentargets_mcp.tool() async def get_associated_diseases_by_drug_name(drug_name: str): """ Retrieve the list of diseases associated with a specific drug based on clinical trial data or post-marketed drugs. Args: drug_name: The drug name to search for Query example: {"drug_name": "aspirin"} """ chembl_id = await get_drug_chembl_id_by_name(drug_name) if chembl_id is None: result = 'No drug found' else: result = tn.run({ "name": "get_associated_diseases_by_drug_chemblId", "arguments": {"chemblId": chembl_id} }) return result @opentargets_mcp.tool() async def get_associated_targets_by_drug_name(drug_name: str): """ Retrieve the list of targets linked to a specific drug based on its mechanism of action. Args: drug_name: The drug name to search for Query example: {"drug_name": "aspirin"} """ chembl_id = await get_drug_chembl_id_by_name(drug_name) if chembl_id is None: result = 'No drug found' else: result = tn.run({ "name": "get_associated_targets_by_drug_chemblId", "arguments": {"chemblId": chembl_id} }) return result @opentargets_mcp.tool() async def get_target_constraint_info_by_name(target_name: str): """ Retrieve genetic constraint information for a specific target, including expected and observed values, and scores. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_target_constraint_info_by_ensemblID", "arguments": {"ensemblId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_publications_by_disease_name(disease_name: str): """ Retrieve publications related to a disease name, including PubMed IDs and publication dates. Args: disease_name: The disease name to search for Query example: {"disease_name": "Breast cancer"} """ efo_id = await get_disease_efo_id(disease_name) if efo_id is None: result = 'No disease found' else: result = tn.run({ "name": "get_publications_by_disease_efoId", "arguments": {"entityId": efo_id} }) return result @opentargets_mcp.tool() async def get_publications_by_target_name(target_name: str): """ Retrieve publications related to a target, including PubMed IDs and publication dates. Args: target_name: The target name to search for Query example: {"target_name": "BRCA1"} """ target_ensembl_id = await get_target_ensembl_id(target_name) if target_ensembl_id is None: result = 'No target found' else: result = tn.run({ "name": "get_publications_by_target_ensemblID", "arguments": {"entityId": target_ensembl_id} }) return result @opentargets_mcp.tool() async def get_publications_by_drug_name(drug_name: str): """ Retrieve publications related to a drug, including PubMed IDs and publication dates. Args: drug_name: The drug name to search for Query example: {"drug_name": "aspirin"} """ chembl_id = await get_drug_chembl_id_by_name(drug_name) if chembl_id is None: result = 'No drug found' else: result = tn.run({ "name": "get_publications_by_drug_chemblId", "arguments": {"entityId": chembl_id} }) return result app = FastMCP( name="tooluniverse_mcp", tools=get_all_tools(tn.all_tools), stateless_http=True, )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/GENTEL-lab/OrigeneMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server