MCP server for EpiGraphDB providing Code Mode execution with API catalog search, REST API execution, GraphQL execution, and SPARQL query support
This server exposes 5 code-execution tools with detailed descriptions but critical schema and composition gaps. Tools gtex_search, gtex_execute, pharos_execute, bgee_execute, and gtex_search (duplicate name) all accept code or query parameters. Descriptions are verbose (200-400 chars) and explain runtime sandboxes well, but input schemas are either missing or incomplete. The gtex_search tool appears twice with different implementations (catalog-based vs OpenAPI-based), creating naming confusion. No output schemas are documented. Error handling is absent, no guidance on what happens when code fails, API calls timeout, or staging overflows. The server conflates discovery (search) with execution (execute) but does not chain them clearly. Schemas visible in catalog-search-tool.ts use Zod but lack type constraints on the 'code' parameter (free-form string). No pagination, no result limits, no idempotency hints.
Execute JavaScript code against the SPARQL endpoint. Code runs in a sandboxed V8 isolate with: - sparql.query(queryString, opts?) — run SELECT/CONSTRUCT/DESCRIBE; returns array of plain { variable: value } rows - sparql.ask(queryString) — run ASK; returns boolean - sparql.raw(queryString, opts?) — return unparsed { head, results } envelope - prefixes — object of common ontology prefixes (rdfs, owl, xsd, skos, dcterms, void, obo, uberon, go, ncbigene, efo, obi, sio, up, ensembl, bgee) - prefixHeader — pre-built `PREFIX …` block to prepend to your queries - console logging (log, warn, error, info) — captured output - fs.* — persistent virtual filesystem (if enabled) The last expression or return value is the result.
Execute JavaScript code against the API. Code runs in a sandboxed V8 isolate with: - api.get(path, params) / api.post(path, body, params) — call REST endpoints - api.getAll(path, params) — exhaustive fetch with auto-pagination - searchSpec(query) — search the API catalog - listCategories() — list endpoint categories - getEndpoint(path) — get full endpoint docs - db.stage(data, opts?) — stage large datasets into SQLite - db.queryStaged(dataAccessId, sql) — query staged data - fs.* — persistent virtual filesystem (if enabled) - console logging (log, warn, error, info) — captured output The last expression or return value is the result.
Search the API catalog (endpoints). Returns matching endpoints with full parameter docs. Use this to discover API capabilities before calling gtex_execute. Categories: (category list) USAGE IN gtex_execute: - api.get(path, params) for GET, api.post(path, body, params) for POST - Path params like /lookup/{id} are auto-interpolated from params: api.get('/lookup/{id}', {id: 'ENSG...'}) - Remaining params become query string - Large responses (>100KB) are auto-staged: check result.__staged, return the staging info, use gtex_query_data to explore - Use limit/pagination params to control response size. Large datasets auto-stage for SQL queries.
Duplicate tool name 'gtex_search' with two different implementations (catalog vs OpenAPI). LLMs cannot distinguish between them; one will be silently overwritten at registration.
Code execution tools (gtex_execute, pharos_execute, bgee_execute) accept free-form 'code' parameter with no schema constraints, length limits, or validation hints. No output schema documented. LLMs cannot predict what these tools return or how to handle errors.
No error handling guidance. Descriptions do not explain what happens when code throws, API calls fail, or datasets exceed memory. No recovery hints for LLMs.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 46 | 2026-07-28+ | v2 |
Search the API spec (OpenAPI mode). Write JavaScript code to search the OpenAPI spec, or use the legacy query/category arguments for keyword search. Available functions: - searchPaths(query, maxResults=10) — keyword search across paths, summaries, tags, parameters - listTags() — list all tags with operation counts - getOperation(idOrPath) — get full operation by operationId or path - describeOperation(idOrPath) — formatted documentation for an operation - searchSpec/query helpers are also available for backward compatibility inside execute() - spec — the full frozen OpenAPI spec object (spec.paths, spec.info, etc.) Use gtex_search to discover endpoints, then write code in gtex_execute to call them.
Execute JavaScript code against the GraphQL API. Code runs in a sandboxed V8 isolate with: - gql.query(queryString, variables?) — execute GraphQL queries - schema.types() / schema.type(name) / schema.search(query) — introspection helpers - db.stage(data, opts?) — stage large datasets into SQLite - db.queryStaged(dataAccessId, sql) — query staged data - api.get(path, params) / api.post(path, body, params) — optional REST API calls (if configured) - fs.* — persistent virtual filesystem (if enabled) - console logging (log, warn, error, info) — captured output The last expression or return value is the result.
No output schema or pagination documented. Tools returning large datasets (e.g., staged data) do not specify limits, cursors, or result structure. Context window risk.
Tool composition unclear. gtex_search is meant to discover endpoints before gtex_execute, but the dependency is only mentioned in prose descriptions, not enforced via schema or tool chaining patterns.