ViromeChat MCP server
ViromeChat MCP server
Un servidor FastMCP que posee todo el acceso a los datasets, las llamadas a APIs externas y la lógica de negocio de Viromech@t. El cliente (el backend FastAPI / el frontend React, en el repositorio separado viromechat) nunca toca directamente un dataframe, una credencial de S3 o un nombre de columna; solo se comunica con este servidor por MCP/HTTP, de forma genérica, leyendo las herramientas y los recursos que este publique en cada momento.
Este repositorio es el hogar independiente de ese servidor. No tiene ninguna dependencia del repositorio de la app; el único contrato entre ambos es el conjunto de herramientas/recursos MCP documentado a continuación, que el backend consume mediante su variable de entorno MCP_SERVER_URL.
Ejecutarlo
Requisitos previos: el dataset de taxonomía (data/TAXONOMY.csv, ~327 MB) se almacena mediante Git LFS. Ejecuta git lfs install una vez por máquina antes de clonar, o git lfs pull después de clonar, para materializarlo.
Local (Python)
git lfs pull # fetch data/TAXONOMY.csv
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # fill in your S3 credentials
python server_mcp.pyDocker
cp .env.example .env # fill in your S3 credentials
docker compose up --buildEn cualquier caso se inicia un servidor HTTP en 0.0.0.0:8000, con endpoint MCP en /mcp (http://localhost:8000/mcp; aquí es a donde el backend apunta con MCP_SERVER_URL). Al arrancar:
Carga
data/TAXONOMY.csvcompletamente en memoria comodf_taxo.Carga los dos archivos de descripción de columnas (
data/v@_columns_description.csvydata/TAXONOMY_columns_description.json) que respaldan los dos recursos MCP siguientes.Abre una conexión DuckDB en memoria, instala las extensiones
httpfsyspatial, y registra una vistahostsobre el dataset Parquet en S3 — el archivo Parquet nunca se carga en memoria; cada llamada aquery_host_sqlse traslada a S3 con DuckDB (poda de columnas/grupos de filas).
Pruebas
pip install pytest
pytestLas pruebas auxiliares ejercitan las funciones puras (_ok/_fail, constructores de figuras/tablas, guardas de SQL) y no necesitan una conexión real a S3.
Related MCP server: OpenCode LLM Wiki MCP Server
Integrar un cliente
Cualquier cliente MCP puede consumir este servidor. El backend de Viromech@t lo hace con un fastmcp.Client:
from fastmcp import Client
async with Client("http://localhost:8000/mcp") as mcp:
tools = await mcp.list_tools()
result = await mcp.call_tool("wikipedia_search", {"search_term": "Lentivirus"})El cliente debe descubrir las herramientas y los recursos dinámicamente (list_tools() / list_resources()) y despachar según artifact["type"] — nunca fijar nombres de herramientas ni conocimiento de columnas. Eso es lo que mantiene desacoplados los dos repositorios: añadir aquí una herramienta que reutilice un tipo de artefacto existente no requiere ningún cambio en el cliente.
Recursos
Los recursos son conocimiento estático, de lectura única — no algo que el LLM “llame” como una herramienta. El cliente los lee una vez por conversación y mezcla su contenido en el prompt de sistema.
URI | Contenido | Fuente |
| Mapa JSON |
|
| Esquema JSON completo (nombre, descripción, columnas, clave primaria, definición de fila) de |
|
Añadir un recurso nuevo (por ejemplo, un tercer dataset) no requiere ningún cambio del cliente: el cliente lo descubre mediante list_resources() y lo lee de forma genérica.
El contrato de respuesta
Cada herramienta devuelve exactamente esta forma, independientemente de lo que haga:
{
"success": true, // or false
"content": "human-readable text — this is what the LLM reads back as the tool result",
"artifacts": [ ... ] // structured extras the client can render; [] if none
}En caso de error, content contiene el mensaje de error (con orientación de retry) a cuando sea posible y artifacts estará vacío. Las dos funciones auxiliares _ok(content, artifacts) / _fail(content) al inicio de server_mcp.py construyen esta forma; úselas siempre en lugar de crear un dict manualmente.
Tipos de artefacto
| Emitido por | Forma | Consumido por el cliente como |
|
|
| Enlace a página de Wikipedia en el panel “Sources” |
|
|
| Enlaces de PubMed + lista blanca de PMIDs para el guard contra alucinaciones |
|
|
| Enlace a NCBI Taxonomy en el panel “Sources” |
|
|
| Se registró si el SQL/código se ejecutó en bitácora; |
|
|
| También se muestra en “Rendered plot” graph |
El cliente despacha solo según artifact["type"], nunca según el nombre de la herramienta. Añadir una herramienta que reutilice un tipo de artefacto existente (p. ej., otra que devuelva "table") no requiere ningún cambio en el cliente.
Herramientas
wikipedia_search(query: str, wikipedia_limit: int = 4000) -> dict
Busca una página en Wikipedia; si no hay coincidencia exacta de título, recurre a la coincidencia más cercana en renderedización de texto completo (con comprobación de “coincidencia difusa”). Devuelve un artefacto url.
pubmed_search(query: str, max_results: int = 5) -> dict
Busca en PubMed (NCBI E-utilities ESearch + efetch, db=pubmed) y devuelve para cada hallazgo título, autores, revista, año, abstract, DOI y PMID. Devuelve un artefacto pubmed con todos los PMID reales encontrados (fuente única de verdad para el módulo de guard contra alucinaciones del cliente).
ncbi_taxonomy_search(name: str) -> dict
Resolver, para cualquier nombre de organismo: acrónimo, nombre común o científico, contra base de datos NCBI Taxonomy (E-utilities, db=taxonomy). Cada coincidencia devuelve nombre científico, rango (especie/género/familia…), división y nombre rot y su clean lineage. Este es la manera correcta de convertir p.e. HIV en Human immunodeficiency virus 1 y su género Lentivirus, o, en el caso de comprobar (por ejemplo) si un nombre es de un género o de familia, y todo independiente de la definición de Wikipedia. ncbi_taxonomy artifact esqueleto.
Clave de implementación: el XML de
efetchde NCBI anida un<Taxon>por cada rango antepasado dentro del<LineageEx>del resultado. El parser solo iteraroot.findall("Taxon")(hijos directos); utilizar.//Taxonnos traería también cada antepasado como si fuera matcheado por separado.
query_host_sql(sql: str, preview_rows: int = 50) -> dict
Ejecuta una consulta SELECT de solo input contra la vista history (porción Parquet en S3) y devuelve un artefacto table. Es el primer paso obligatorio antes de usar query_dataframe, create_map, create_map (que funcionan con el resultado de la última llamada a query_host_sql (last_host_context), no desde el dataset completo).
Guard debe:
Solo una statement
SELECT—INSERT/UPDATE/DELETE/DDL/PRAGMA/...quedan rechazadas por_FORBIDDEN_SQL_KEYWORDS.SELECT *NO se acepta.hosttiene ~65 columnas y un blobgeometrypesado; leer todas las columnas de cada fila desde S3 es lo que provocaba timeouts de varios minutos antes de este guard. Quien pregunta debe especificar office solo de las columnas.Las coordenadas están en un punto GEOMETRY, no en camp separados
lat/lon; tú que les extra consulta conST_X(geometry) AS lon, WHERE geometry vig.
query_dataframe(code: str, preview_rows: int = 50) -> dict
Ejecuta código pandas en entorno con df_taxo, df_host (igual a ctx.last_host_result, o un error si aún no hubo query_host_sql), pd/np en el contexto. Debe asignar el DataFrame a result. Devuelve artefacto table.
create_visualization(code: str) -> dict
Mismo entorno de ejecución que query_dataframe, con px/go texto. Llama obligatoriamente asignar su dibujo a fig. Si la figure tiene 0 registros se rechaza con mensaje de orientación (no se devuelva silenciosa en blanco). Returns artefacto plotly.
create_map(code: str) -> dict
Igual que create_visualization pero obliga a usar port define:
única manera de
scatter_mapbox, nuncascatter_map.lon/latya extraído en la precedente llamadaquery_host_sql.
If primary_id (BioSample based) no está en hover_data del gráfico result, los rejected en código y no en docstring (_check_hover_has_column) — mapa sin primary_id para _fail(…).
Ampliar el servidor
Para añadir una nueva herramienta:
Escribirá como función normal con el decorador
@mcp.tool, que devuelva_ok(content, artifacts)o `_fail(content)» (prohibido mapa sin formato).Si produce algo específico para que el cliente lo renderice (enlace, tabla, figura), use un tipo de artefacto existente del cuadro siempre que instale el tipo — así = cero cambio en el cliente. Solo hay que inventar un nuevo tipo (y rozarlo en la salida del cliente) si la estructura difiere verdaderamente.
Coloque cada regla de uso, advertencia y ejemplo **en el “docstring”. Al LLM se lo envía tal cual (texto de la herramienta); es el único sitio para la guía al detalle.
Este with "preview_rows"... If un valor por defect't se debe confI-config (p ej
preview_rows,wikipedia_limit), use solo nombre del parámetro. El cliente con UI habilita esa config correspondiente poniendo exactamente ese nombre en el JSON schema.
Configuración
server_mcp.py en import (import) debe cargar .env (look at .env.example) mediante load_env_file() import from mcp_config.py:
Variable | Obligatoria | Por defecto | Significado |
| Sí | — | Hostname del endpoint compatible con S3 |
| Sí | — | S3 access key |
| Sí | — | S3 secret key |
| Sí | — | Nombre del bucket S3 |
| Sí |
| Clave del objeto Parquet dentro del bucket |
| No |
| Región S3 |
| No |
| Ajuste |
| No |
| Ruta local al CSV de taxonomía |
La configuración no secreta está en mcp_config.py.
Esta version ha sido traducida preserving the original structure.
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to discover and execute tools via a secure MCP server with JWT authentication, RBAC, rate limiting, and audit logging.1MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to interact with a persistent knowledge graph backend using MCP tools for reading, searching, and analyzing wiki pages with vector search and graph algorithms.4
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to query live schema, lineage, and query-context across data warehouses, dbt projects, orchestration systems, and BI tools via MCP tools.Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to access a unified catalog of tools from various APIs (OpenAPI, GraphQL, MCP, Google Discovery) through the MCP protocol.MIT
Related MCP Connectors
Free public MCP for AI agents — 193 tools, 44 workflows. No API key.
Real-time Amazon, WIPO & PACER data for AI agents — 19 tools via the MCP protocol.
OCR, transcription, file extraction, and image generation for AI agents via MCP.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Romumrn/viromeatlas_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server