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.
Monarch MCP exposes 5 tools across REST/GraphQL/SPARQL modes with detailed descriptions (150-250 chars each) and comprehensive parameter documentation. However, tool naming is inconsistent (three tools share the name '<prefix>_execute' across different modes), violating the single-responsibility principle. Input schemas are present and typed (Zod), but output schemas are not formally documented. Error handling guidance is minimal. The server demonstrates solid foundational quality but lacks the polish needed for production recommendation.
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 api.get/api.post for hybrid REST capability; optional fs.* for virtual filesystem; console.log() capture. Large responses (>30KB) are auto-staged into SQLite. The last expression or return value is the result.
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 tags/categories; getEndpoint(path) / getOperation(idOrPath) — get endpoint docs; api.get(path, params) for GET, api.post(path, body, params) for POST; console.log() capture; optional fs.* for virtual filesystem; optional db.stage(), db.queryStaged() for auto-staging. Large responses (>100KB) are auto-staged into SQLite. The last expression or return value is the result.
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 to prepend to queries; optional fs.* for virtual filesystem; console logging capture. Large SPARQL responses (>30KB) are auto-staged into SQLite. The last expression or return value is the result.
Search the API catalog (catalog mode) or OpenAPI spec (OpenAPI mode). Returns matching endpoints with full parameter docs. Use this to discover API capabilities before calling <prefix>_execute. Categories are listed. USAGE IN <prefix>_execute: api.get(path, params) for GET, api.post(path, body, params) for POST. Path params like /lookup/{id} are auto-interpolated from params. Remaining params become query string. Large responses (>100KB) are auto-staged: check result.__staged, return the staging info, use <prefix>_query_data to explore. Use limit/pagination params to control response size.
Three tools named '<prefix>_execute' across REST, GraphQL, and SPARQL modes violate single-responsibility and create ambiguity. LLMs cannot distinguish which execute variant to call without reading full descriptions.
Output schemas are not formally documented. Descriptions mention 'last expression is the result' and 'auto-staging' behavior, but the actual return type structure (fields, types, pagination) is not specified. LLMs cannot plan downstream tool calls without knowing what fields to expect.
Error handling guidance is absent. Descriptions do not explain what errors can occur, how to recover, or what the LLM should do if a query fails. No recovery patterns documented.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 50 | 2026-07-28+ | v2 |
Search the GraphQL schema or discover endpoints. Write JavaScript code to search the schema using helper functions: searchTypes(query) — keyword search across type names and descriptions; listTypes() — list all types; getType(name) — get full type documentation; describeType(name) — formatted type docs; schema — the full frozen GraphQL introspection object. Use <prefix>_search to discover schema, then write code in <prefix>_execute to execute queries.
The 'workspace' parameter (optional, for ADR-006 Phase 0) lacks clear documentation of its purpose, valid values, and when to use it. This creates ambiguity for LLM invocation.
No pagination or result-limiting guidance for large responses. Descriptions mention auto-staging for >100KB responses but do not explain how to query staged data or what the staging API looks like.