MCP server providing Code Mode execution for API discovery and querying, with support for REST APIs, GraphQL, and SPARQL endpoints. Includes catalog search, dynamic code execution in sandboxed V8 isolates, auto-staging of large responses, and citation/provenance tracking.
The server defines 4 tools with detailed descriptions and parameter schemas. However, there are critical issues: (1) Tool naming is inconsistent, three tools are named '<prefix>_execute' (REST, GraphQL, SPARQL variants), violating the single-responsibility principle and making them indistinguishable to LLMs. (2) Parameter descriptions are verbose but lack actionable constraints (enums, ranges, patterns). (3) Output schemas are not documented, LLMs cannot predict what fields to expect from code execution results. (4) Error handling guidance is absent. (5) The 'code' parameter accepts arbitrary JavaScript, creating injection risks without validation guidance. Descriptions are strong (150-300 chars), but schema completeness and error recovery patterns are weak.
Execute JavaScript code against the API in a sandboxed V8 isolate. Code runs with: searchSpec(query) / searchPaths(query) — search the API catalog or OpenAPI spec; listCategories() / listTags() — inspect categories/tags; getEndpoint(path) / getOperation(idOrPath) — get endpoint docs; api.get(path, params) for GET, api.post(path, body, params) for POST; Large responses (>100KB) are auto-staged into SQLite; Use limit/pagination params to control response size. Path params like /lookup/{id} are auto-interpolated from params.
Execute JavaScript code against a SPARQL endpoint in a sandboxed V8 isolate. Code runs 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; console logging capture; Optional filesystem: fs.readFile / fs.writeFile / fs.glob; Large SPARQL responses (>30KB) are auto-staged into SQLite.
Execute JavaScript code against a GraphQL endpoint in a sandboxed V8 isolate. Code runs with: gql.query(queryString, variables?) — execute GraphQL queries; schema.types(), schema.type(), schema.search() — introspection helpers; db.stage(), db.queryStaged() — staging helpers; Optional REST capability: api.get/api.post for hybrid GraphQL+REST servers; console.log() capture; Large responses (>30KB) are auto-staged into SQLite.
Search the API catalog (catalog mode) or OpenAPI spec (OpenAPI mode). Returns matching endpoints with full parameter documentation. Use this to discover API capabilities before calling <prefix>_execute. In catalog mode: accepts query/category/max_results parameters and performs keyword-based search over static ApiCatalog. In OpenAPI mode: accepts code parameter for agent-written JavaScript with full resolved OpenAPI spec and helper functions available.
Three tools share the name '<prefix>_execute' with different behaviors (REST, GraphQL, SPARQL). LLMs cannot distinguish them; they will guess wrong or fail to select the correct variant. Violates single-responsibility and naming clarity principles.
Output schemas are not documented. The 'code' parameter accepts arbitrary JavaScript that returns results, but LLMs have no schema to predict field names, types, or structure. This forces agents to guess what fields exist and risks parsing failures.
The 'code' parameter accepts arbitrary JavaScript without validation guidance or injection warnings. Descriptions mention 'sandboxed V8 isolate' but do not explain what code is safe, what APIs are available, or how to handle errors. LLMs may pass malicious or invalid code.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 46 | 2026-07-28+ | v2 |
Parameter 'max_results' in search tool lacks numeric constraints (min/max). Description says 'default 10, max 25' but schema does not enforce bounds. LLMs may pass invalid values like 0 or 1000.
No error handling guidance. Descriptions do not explain what happens on failure (timeout, invalid code, API error, staging overflow). LLMs have no recovery path and will retry blindly or give up.