ViromeChat MCP server
MCP-сервер ViromeChat
Сервер FastMCP, который владеет всем доступом к наборам данных, внешними вызовами API и бизнес-логикой для Viromech@t. Клиент (бэкенд FastAPI / React-фронтенд, в отдельном репозитории viromechat) никогда не обращается напрямую ни к dataframe, ни к учётным данным S3, ни к именам колонок — он только общается с этим сервером по MCP/HTTP, обобщённо, читая те инструменты и ресурсы, которые сервер публикует в данный момент.
Этот репозиторий — автономный дом этого сервера. У него нет зависимости от репозитория приложения; единственный контракт между ними — набор MCP-инструментов и ресурсов, описанный ниже, который бэкенд использует через переменную окружения MCP_SERVER_URL.
Запуск
Предварительные требования: набор данных таксономии (data/TAXONOMY.csv, ~327 МБ) хранится через Git LFS. Выполните git lfs install один раз на каждой машине перед клонированием или git lfs pull после клонирования, чтобы материализовать его.
Локально
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 --buildВ любом случае запускается HTTP-сервер на 0.0.0.0:8000, endpoint MCP на /mcp (http://localhost:8000/mcp — именно это бэкенд указывает через MCP_SERVER_URL). При запуске он:
Полностью загружает
data/TAXONOMY.csvв память какdf_taxo.Загружает два файла описания колонок (
data/v@_columns_description.csvиdata/TAXONOMY_columns_description.json), которые лежат в основе двух ресурсов MCP, описанных ниже.Открывает in-memory-соединение DuckDB, устанавливает расширения
httpfsиspatialи регистрирует представлениеhostповерх S3-набора данных Parquet — Parquet-файл никогда не загружается в память; каждый запросquery_host_printerвыполняется DuckDB прямо в S3 (отсечение по колонкам и группам строк).
Тесты
pip install pytest
pytestВспомогательные тесты покрывают чистые функции (_ok/_fail, построители figure/таблиц, SQL-защиты) и не требуют живого подключения к S3.
Related MCP server: OpenCode LLM Wiki MCP Server
Подключение клиента
Любой MCP-клиент может работать с этим сервером. Бэкенд Viromech@t делает это с помощью 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"})Клиент должен динамически находить инструменты и ресурсы (list_tools() / list_reseources()) и выполнять диспетчеризацию по artifact["type"] — никогда не захардкоживать имена инструментов или знание о колонках. Именно это держит два репозитория развязанными: добавление инструмента, который переиспользует существующий тип артефакта, не требует изменения клиента.
Ресурсы
Ресурсы — это статическое знание, которое читается один раз, а не то, что LLM «вызывает» как инструмент. Клиент читает их один раз за диалог и встраивает их содержимое в системный промпт.
URI | Содержимое | Источник |
| JSON-карта |
|
| Полная JSON-схема (имя, описание, колонки, первичный ключ, определение строки) для |
|
Добавление нового ресурса (например, третьего набора данных) не требует изменений на клиенте: клиент обнаруживает ресурсы через list_resources() и читает каждый из них универсально.
Контракт ответа
Каждый инструмент возвращает ровно такую структуру, независимо от того, что он делает:
{
"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
}При ошибке content содержит сообщение об ошибке (где возможно — с подсказкой, как повторить), а artifacts пуст. Две вспомогательные функции _ok(content, artifacts) / _fail(content) в начале server_mcp.py формируют эту структуру — всегда используйте их вместо ручной сборки dict.
Типы артефактов
| Источник производит | Структура | Использование клиентом |
|
|
| Ссылка на Википедию в панели «Sources» |
|
|
| Ссылки на PubMed + белый список PMID для защиты от галлюцинаций |
|
|
| Ссылка на NCBI Taxonomy в панели «Sources» |
|
|
| Отслеживается как выполненный SQL/код в «Sources»; |
|
|
| Отрисованный график plotly |
Клиент выполняет диспетчеризацию только по artifact["type"] — никогда по имени инструмента. Добавление инструмента, который переиспользует существующий тип артефакта (например, ещё одного инструмента, возвращающего "table"), вообще не требует изменений в клиенте.
Инструменты
wikipedia_search(search_term: str, wikipedia_limit: int = 4000) -> dict
Находит страницу в Википедии; при отсутствии точного совпадения по названию возвращает ближайший результат полнотекстового поиска (в содержимом это помечено как «нечёткое совпадение»). Возвращает артефакт url.
pubmed_search(query: str, max_results: int = 5) -> dict
Выполняет поиск по PubMed (NCBI E-utilities esearch + efetch, db=pubmed) и возвращает для каждого результата название, авторов, журнал, год, аннотацию, DOI и PMID. Возвращает артефакт pubmed со всеми реально найденными PMID — это единственный источник правды для защиты клиента от галлюцинаций по PMID.
ncbi_taxonomy_search(name: str) -> dict
Сопоставляет любое название организма — аббревиатуру, бытовое называние или научное название — с базой данных NCBI Taxonomy (E-utilities, db=taxonomy). Для каждого совпадения возвращает: научное название, ранг (вид/род/семейство/…), отдел, полную родословную и известные синонимы/аббревиатуры. Это авторитетный способ превратить HIV в Human immunodeficiency virus 1 / род Lentivirus или проверить, является ли название родом или семейством, не полагаясь на формулировку Википедии. Возвращает артефакт ncbi_taxonomy для лучшего совпадения.
Примечание к реализации: XML NCBI
efetchсодержит по одному<Taxon>на каждый ранг-предок внутри элемента<LineageEx>каждого результата. Парсер перебирает толькоroot.findall("Taxon")(прямые потомки) — использование.//Taxonзахватило бы каждого предка как отдельное совпадение.
query_host_sql(sql: str, preview_rows: int = 50) -> dict
Выполняет read-only запрос SELECT к представлению host (набор S3 Parquet) и возвращает артефакт table. Это обязательный первый шаг перед тем, как query_dataframe, create_visualization или create_map смогут использовать df_host, — эти инструменты работают с результатом последнего вызова query_host_sql (ctx.last_host_result), а не с полным набором данных.
Защиты, действующие перед выполнением:
Разрешается только одна операция
SELECT—INSERT/UPDATE/DELETE/DDL/PRAGMA/...отклоняются_FORBIDDEN_SQL_KEYWORDS.Голый
SELECT *отклоняется сразу. Вhostоколо ~65 колонок, включая тяжёлое бинарное полеgeometry; выбор всех колонок для всех подходящих строк через S3 — причина многотаимных таймаутов до ввода этой защиты. Вызывающий должен проецировать только те колонки, которые ему нужны.Координаты находятся в нативной колонке точек типа
GEOMETRY, а не в обычныхlat/lon— извлекайте их какST_X(geometry) AS lon, ST_Y(geometry) AS lat(расширениеspatialзагружается при старте).
query_dataframe(code: str, preview_rows: int = 50) -> dict
Выполняет pandas-код, получая в области видимости df_taxo, df_host (= ctx.last_host_result, либо точную ошибку, если query_host_sql ещё не вызывался), pd и np. Код должен присвоить DataFrame переменной result. Возвращает артефакт table.
create_visualization(code: str) -> dict
Та же среда выполнения, что и у query_dataframe, плюс px/go. Код должен присвоить Plotly figure переменной fig. Пустые фигуры (0 точек данных) отклоняются с подсказкой, а не молча превращаются в пустой график. Возвращает артефакт plotly.
create_map(code: str) -> dict
То же, что и create_visualization, но требует px.scatter_mapbox(...) (никогда не scatter_map) и того, что предыдущий вызов query_host_sql уже извлёк lon/lat из geometry. Возвращает артефакт plotly.
Обязательный идентификатор образца: результирующая фигура отклоняется, если в hover_data не встречается primary_id (номер BioSample) — каждая нанесённая на график точка должна прослеживаться до конкретного образца. Это проверяется в коде (_check_hover_has_column(fig, "primary_id")), а не просто упоминается в docstring — карта без него получает жёсткий _fail(...).
Расширение сервера
Чтобы добавить новый инструмент:
Напишите его как обычную функцию с декоратором
@mcp.tool, возвращающую_ok(content, artifacts)или_fail(content)— никогда не вручную собранный dict.Если инструмент создаёт нечто, что клиент должен отрисовать особым образом (ссылку, таблицу, фигуру), используйте существующий
typeартефакта из таблицы выше, когда форма подходит, — это ноль изменений в клиенте. Вводите новыйtype(и подключайте его в диспетчерский цикл клиента), только если форма действительно новая.Все правила использования, предостережения и примеры пишете в docstring инструмента. Она передаётся LLM дословно как описание инструмента — это единственное место, где должна находиться специфичная для данных информация.
Если инструменту нужна настройка по умолчанию, принимаемая в интерфейсе (как
preview_rowsилиwikipedia_limit), дайте параметру именно то имя — клиент применит подходящую экспертную настройку любому инструменту, в JSON-схеме которого заявлен параметр с таким именем.
Конфигурация
server_mcp.py читает .env (см. .env.example) при импорте через load_env_file() из mcp_config.py:
Переменную | Обязательно | По умолчанию | Описание |
| да | — | Хост S3-совместимого endpoint |
| да | — | Ключ доступа S3 |
| да | — | Секретный ключ S3 |
| да | — | Имя бакета S3 |
| да |
| Ключ объекта Parquet-набора внутри бакета |
| нет |
| Регион S3 |
| нет |
| Настройка DuckDB |
| нет |
| Локальный путь к CSV-файлу таксономии |
Несекретные параметры находятся в mcp_config.py.
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