A middleware server that enables multiple isolated instances of the same MCP servers to coexist independently with unique namespaces and configurations.
Scoring was not performed
Tools are generated dynamically at runtime from wrapped servers, no static tool definitions visible in source code. Tool names, descriptions, schemas, and parameters cannot be verified before runtime.
Tool naming template `{functionsPrefix}_{wrappedToolName}` is generic and constructed, not action-oriented verbs. The generated names depend entirely on the wrapped server and are not optimized for LLM understanding. Example: if wrapped tool is 'execute', result is 'functions_execute', ambiguous what action occurs.
Tool descriptions are synthetic: 'Use this tool only in the "{functionsPrefix}" scope' prepended to original description. This violates the principle that descriptions should explain WHAT the tool does, WHEN to use it, and any prerequisites, not scope/namespace restrictions which are implementation detail.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 25 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 24 | - | v1 |
Input schemas are converted from the wrapped server's JSON schema via `convertJsonSchemaToZodShape()`, then passed to `mainMcpServer.tool()`. No validation, documentation, or post-processing of schemas is visible. If wrapped server returns incomplete or malformed schemas, they are propagated unchecked.
No error handling visible in tool callback (wrapped-servers.ts, line ~98 `callback = async (args) => {...}`). If `wrappedServer.callTool()` throws or returns malformed output, there is no try-catch, no error classification (retryable vs fatal), and no guidance for agent recovery.
No output schema documentation for tools. The callback returns `res as { content: { type: "text", text: string }[] }`, a bare assertion. If the wrapped server returns a different structure, it will fail at runtime with no guidance.