# MCP Server Comparison: Top Implementations & Enterprise Gap Analysis

> **Status**: Round 9 analysis (2026-05-10). Full comprehensive review via 6 parallel
> agents (PR code review + silent failure analysis + type design analysis + test
> coverage analysis + deep architecture exploration + ecosystem research). Individual
> per-repo comparison docs now at `docs/reference/comparisons/mcp/`. Key new finding
> from ecosystem research: Stripe MCP is now a **pure stdio-to-HTTP proxy** to
> `mcp.stripe.com` (validates our proxy pattern). GitHub MCP has **toolset-level
> server instructions** and **tool snapshot testing** (`__toolsnaps__/`). ToolHive has
> **Kubernetes Operator with CRDs** and **semantic tool search** (85% token savings).
> Grafana MCP has the **gold-standard OTel stack** (slog bridge + Prometheus +
> OTLP). Google Toolbox has **zero-code YAML tool definition** with 20+ databases.
> SDK v2 still alpha.2 (Q1 target slipped). Enterprise WG forming. 12K+ MCP servers.

## Overview

This document compares our Coda MCP server implementation against the top MCP server implementations and the evolving MCP specification. The goal is to identify: (1) what we'd improve if starting fresh, (2) patterns to adopt from other MCPs, and (3) enterprise gaps excluding permissioning (tracked separately as COD-109).

**Per-repo comparison docs**: See [`docs/reference/comparisons/mcp/`](comparisons/mcp/) for detailed individual comparison documents against Stripe, Playwright, GitHub, FastMCP, Cloudflare, Grafana, ToolHive, Google Toolbox, and Notion MCP servers.

### Repos analyzed

| #   | Repo                                                                                        | Stars | Language   | Domain                        |
| --- | ------------------------------------------------------------------------------------------- | ----- | ---------- | ----------------------------- |
| 1   | [mindsdb/mindsdb](https://github.com/mindsdb/mindsdb)                                       | 39K   | Python     | Unified data platform         |
| 2   | [microsoft/playwright-mcp](https://github.com/microsoft/playwright-mcp)                     | 32K   | TypeScript | Browser automation            |
| 3   | [bytedance/UI-TARS-desktop](https://github.com/bytedance/UI-TARS-desktop)                   | 31K   | TypeScript | Desktop automation            |
| 4   | [github/github-mcp-server](https://github.com/github/github-mcp-server)                     | 30K   | Go         | GitHub API (official)         |
| 5   | [PrefectHQ/fastmcp](https://github.com/PrefectHQ/fastmcp)                                   | 25K   | Python     | Python MCP framework (v3 GA)  |
| 6   | [oraios/serena](https://github.com/oraios/serena)                                           | 24K   | Python     | Coding agent                  |
| 7   | [Skyvern-AI/skyvern](https://github.com/Skyvern-AI/skyvern)                                 | 22K   | Python     | Browser automation + LLM      |
| 8   | [pydantic/pydantic-ai](https://github.com/pydantic/pydantic-ai)                             | 17K   | Python     | Agent framework               |
| 9   | [googleapis/mcp-toolbox](https://github.com/googleapis/mcp-toolbox)                         | 15K   | Python     | Google database toolbox       |
| 10  | [GLips/Figma-Context-MCP](https://github.com/GLips/Figma-Context-MCP)                       | 15K   | TypeScript | Figma design-to-code          |
| 11  | [BeehiveInnovations/pal-mcp-server](https://github.com/BeehiveInnovations/pal-mcp-server)   | 12K   | TypeScript | Multi-model proxy             |
| 12  | [PipedreamHQ/pipedream](https://github.com/PipedreamHQ/pipedream)                           | 11K   | TypeScript | 2500+ API integrations        |
| 13  | [modelcontextprotocol/inspector](https://github.com/modelcontextprotocol/inspector)         | 10K   | TypeScript | Official MCP testing tool     |
| 14  | [awslabs/mcp](https://github.com/awslabs/mcp)                                               | 9K    | Python     | AWS services                  |
| 15  | [modelcontextprotocol/registry](https://github.com/modelcontextprotocol/registry)           | 7K    | -          | Official server registry      |
| 16  | [getsentry/XcodeBuildMCP](https://github.com/getsentry/XcodeBuildMCP)                       | 5K    | Swift      | Xcode/iOS (Sentry official)   |
| 17  | [google-labs-code/stitch-skills](https://github.com/google-labs-code/stitch-skills)         | 5K    | Python     | Google Labs agent skills      |
| 18  | [modelcontextprotocol/go-sdk](https://github.com/modelcontextprotocol/go-sdk)               | 5K    | Go         | Official Go SDK               |
| 19  | [makenotion/notion-mcp-server](https://github.com/makenotion/notion-mcp-server)             | 4K    | TypeScript | Notion (official)             |
| 20  | [modelcontextprotocol/csharp-sdk](https://github.com/modelcontextprotocol/csharp-sdk)       | 4K    | C#         | Official C# SDK               |
| 21  | [open-webui/mcpo](https://github.com/open-webui/mcpo)                                       | 4K    | Python     | MCP-to-OpenAPI proxy          |
| 22  | [cloudflare/mcp-server-cloudflare](https://github.com/cloudflare/mcp-server-cloudflare)     | 4K    | TypeScript | Cloudflare Workers/KV/R2/D1   |
| 23  | [grafana/mcp-grafana](https://github.com/grafana/mcp-grafana)                               | 3K    | Go         | Grafana (official)            |
| 24  | [stacklok/toolhive](https://github.com/stacklok/toolhive)                                   | 2K    | Go         | Enterprise MCP platform       |
| 25  | [stripe/agent-toolkit](https://github.com/stripe/agent-toolkit)                             | 2K    | TypeScript | Payments/billing (official)   |
| 26  | [ahujasid/blender-mcp](https://github.com/ahujasid/blender-mcp)                             | 21K   | Python     | Blender 3D integration        |
| 27  | [executeautomation/mcp-playwright](https://github.com/executeautomation/mcp-playwright)     | 5.5K  | TypeScript | Browser automation + scraping |
| 28  | [dagger/container-use](https://github.com/dagger/container-use)                             | 3.8K  | Go         | Containerized agent envs      |
| 29  | [metatool-ai/metamcp](https://github.com/metatool-ai/metamcp)                               | 2.3K  | TypeScript | Unified MCP middleware/GUI    |
| 30  | [microsoft/mcp-gateway](https://github.com/microsoft/mcp-gateway)                           | 620   | Go         | MCP reverse proxy + routing   |
| 31  | [traceloop/opentelemetry-mcp-server](https://github.com/traceloop/opentelemetry-mcp-server) | 500+  | TypeScript | OTel trace querying via MCP   |

New since Round 6: blender-mcp (21K, 3D), executeautomation/mcp-playwright (5.5K, browser), container-use (3.8K, Dagger containerization), metamcp (2.3K, middleware), microsoft/mcp-gateway (reverse proxy). FastMCP reached v3 GA (Feb 2026, ~1M daily downloads, powers ~70% of MCP servers).

Also notable: HashiCorp Terraform (1.4K), MongoDB (1K), ElevenLabs (1.4K), Sentry (680), Datadog (35), Laravel Boost (3.5K), Casdoor (14K), and julien040/anyquery (1.7K, SQL-over-40-apps).

---

## MCP Protocol Spec Evolution

The spec has gone through five revisions since its initial release:

| Revision      | Key additions                                                                                                                                                                                                                                                                                                                                                                 |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 2024-11-05    | Initial release                                                                                                                                                                                                                                                                                                                                                               |
| 2025-03-26    | OAuth 2.1 framework, **Streamable HTTP transport** (replaces SSE), **tool annotations** (`readOnlyHint`/`destructiveHint`), audio content, progress notifications                                                                                                                                                                                                             |
| 2025-06-18    | **Structured tool output** (`structuredContent`/`outputSchema`), **elicitation** (server requests user input), resource links in tool results, `_meta` expansion, `title` field                                                                                                                                                                                               |
| 2025-11-25    | **Tasks** (async tool execution state machine), **URL-mode elicitation**, icon metadata, **OpenID Connect Discovery**, incremental OAuth scope consent, Protected Resource Metadata (RFC 9728) **required**                                                                                                                                                                   |
| Draft (next)  | **Sessions removed from Streamable HTTP** (`Mcp-Session-Id` gone), **`extensions` capability** (vendor-prefixed negotiation, `ext-auth`/`ext-apps` launched), **OTel trace propagation** formalized (`traceparent`/`tracestate` in `_meta`), deterministic `tools/list` ordering, `Mcp-Method`/`Mcp-Name` request headers, `x-mcp-header` for custom headers from tool params |
| 2026-06 (est) | **Transport evolution**: stateless Streamable HTTP across replicas, scalable session handling, MCP Server Cards (`.well-known`). No new official transports. Enterprise WG deliverables expected.                                                                                                                                                                             |

### What this means for us

Our implementation targets the 2025-06-18 feature set with selective adoption from 2025-11-25 and draft. Here's our current coverage:

| Feature                     | Spec version     | Status       | Notes                                                                          |
| --------------------------- | ---------------- | ------------ | ------------------------------------------------------------------------------ |
| Tool annotations            | 2025-03-26       | **Resolved** | `toAnnotations()` implements `readOnlyHint`/`destructiveHint`                  |
| Progress notifications      | 2025-03-26       | **Resolved** | `progressToken` support with 0/1 start, 1/1 complete                           |
| MCP logging                 | 2025-03-26       | **Resolved** | `sendLoggingMessage` with level-based forwarding                               |
| Structured content          | 2025-06-18       | **Resolved** | `structuredContent` returned alongside text; `outputSchema` on 24 tools/skills |
| Elicitation                 | 2025-06-18       | N/A          | Not needed — tools don't request user input mid-call                           |
| Streamable HTTP             | 2025-03-26       | N/A          | Correct to not have — stdio is right for local client                          |
| Tasks (async)               | 2025-11-25 (exp) | Missing      | Moving to extension (SEP-2663); would benefit long-running tools               |
| OTel trace propagation      | Draft            | **Resolved** | W3C `traceparent` header per tool call (ahead of spec; SEP-414 merged)         |
| Deterministic tool ordering | Draft            | **Resolved** | `.sort((a, b) => a.name.localeCompare(b.name))` in `index.ts`                  |
| `outputSchema` per tool     | 2025-06-18       | **Resolved** | 24 tools/skills have typed output schemas; passthrough tools correctly omit    |
| `idempotentHint`            | 2025-03-26       | **Resolved** | `toAnnotations()` returns `idempotentHint: true` for all non-destructive tools |
| Multi Round-Trip Requests   | Draft            | N/A          | SEP-2322 merged; `InputRequiredResult` — not needed for current tools          |
| Sessionless MCP             | Draft            | **Aligned**  | SEP-2567 merged 2026-05-07; validates our stateless stdio approach             |

---

## Architecture Comparison

### Server structure (updated)

| Repo            | Architecture                                                | Key pattern                                                         |
| --------------- | ----------------------------------------------------------- | ------------------------------------------------------------------- |
| **Playwright**  | Multi-layer factory: CLI -> server -> per-domain tool files | `defineTool()` with capability gating                               |
| **GitHub**      | Go monolith, functional tool registration                   | `toolsets.NewToolset()` with group-based filtering                  |
| **FastMCP**     | Decorator-based Python framework                            | `@mcp.tool()` decorator, async-first, type-inferred schemas         |
| **Google**      | Modular Python toolbox, per-database adapters               | Plugin architecture, multi-DB (Postgres, MySQL, Spanner, AlloyDB)   |
| **MindsDB**     | FastMCP singleton, Starlette app                            | Side-effect module imports register tools                           |
| **Skyvern**     | Central registry, 15+ domain modules                        | `FastMCP` with 5K-char instructions                                 |
| **Stripe**      | Agent toolkit with MCP adapter                              | SDK wraps Stripe API actions as tools                               |
| **Cloudflare**  | Workers extending `McpAgent`                                | Per-app `tools/*.tools.ts` with `registerXxxTools()`                |
| **Grafana**     | Go, per-domain tool files                                   | Resource-oriented tools for dashboards, datasources, alerts         |
| **ToolHive**    | Go platform, container-based isolation                      | Runs MCP servers as isolated containers with audit logging          |
| **AWS**         | Monorepo, 30+ independent servers                           | Class-based `tools.py` with `register()`                            |
| **Coda (ours)** | Proxy: stdio MCP -> HTTP -> Express -> tool registry        | `TOOL_DEFINITIONS` array -> `toMcpToolConfig()` -> `registerTool()` |

**GitHub's approach is noteworthy**: Go-based, functional tool registration via `toolsets.NewToolset()`, with per-group filtering ("repos", "issues", "pull_requests"). Similar to our domain-based filtering. They also implement dynamic tool descriptions that change based on context.

**Stripe's pattern** wraps an existing SDK (Stripe API) as MCP tools — conceptually similar to our proxy, but in-process rather than over HTTP. Validates the adapter pattern for sensitive domains.

**FastMCP** (25K stars) has become the de facto Python MCP framework. Its decorator-based approach (`@mcp.tool()`) is the Python equivalent of our `registerTool()` pattern. Key lesson: simplicity of developer experience drives adoption.

**ToolHive** (Stacklok) has matured significantly in 2026: per-user per-tool rate limiting, horizontal scaling via Redis-backed session routing, embedded OAuth authorization server in vMCP, claim-based authorization, and local CLI mode. Now represents the reference enterprise MCP platform.

**microsoft/mcp-gateway** (620 stars) — official reverse proxy and management layer for MCP servers. Enables session-aware routing and lifecycle management. Validates the gateway pattern for enterprise deployments.

**mcpo** (Open WebUI, 4K stars) bridges MCP servers to REST APIs via MCP-to-OpenAPI proxy. Shows demand for making MCP servers accessible to non-MCP clients — validates our `POST /api/v1/tools/execute` endpoint approach.

**metamcp** (2.3K stars) — unified MCP middleware with GUI for managing connections to multiple MCP servers. The "router + dashboard" pattern is emerging as a developer UX layer on top of raw MCP.

---

## SDK Evolution

### v1.x (current stable — v1.29.0, confirmed May 2026)

The monolithic `@modelcontextprotocol/sdk` package. In maintenance mode, receiving backports only. This is what we use. SDKs collectively at 97M+ monthly downloads.

Recent v1.x additions (v1.25-v1.29):

- Conformance test infrastructure
- OAuth discovery caching (`discoverOAuthServerInfo()`)
- Streaming methods for elicitation and sampling (v1.27)
- Client Credentials provider scopes support (v1.26)
- Cross-client data leak security fix (GHSA-345p-7cg4-v4c7, v1.26)
- `scopes_supported` from resource metadata (v1.28)
- Capability extensions advertising (v1.29)

### v2.x alpha (multi-package) — slipped to Q3 2026

The SDK has been restructured into separate packages. **v2.0.0-alpha.2** released 2026-04-01. The original Q1 2026 stable target has slipped; still in alpha as of May 2026. 7 of 25 backward-compat issues remain open in the v2.0.0-bc milestone.

| Package                         | Purpose                       |
| ------------------------------- | ----------------------------- |
| `@modelcontextprotocol/server`  | Core server                   |
| `@modelcontextprotocol/client`  | Core client                   |
| `@modelcontextprotocol/core`    | Shared types, schemas         |
| `@modelcontextprotocol/express` | Express middleware adapter    |
| `@modelcontextprotocol/hono`    | Hono middleware adapter       |
| `@modelcontextprotocol/fastify` | Fastify middleware adapter    |
| `@modelcontextprotocol/node`    | Node.js runtime shims (stdio) |

**Key v2 breaking changes:**

- **Standard Schema support**: `inputSchema`/`outputSchema` accept Zod v4, Valibot, or ArkType (not just Zod). Our Zod v4 schemas are already compatible.
- Unknown tool calls return JSON-RPC `-32602` protocol errors instead of `CallToolResult` with `isError: true`.
- Task orchestration extracted into `TaskManager` class.
- ReDoS vulnerability fix (CVE-2026-0621) in `UriTemplate` regex.
- `zod` dropped from `peerDependencies` (kept as internal dependency).

**Recent v2 additions (April–May 2026):**

- `registerTool`/`registerPrompt` accept raw Zod shape, auto-wrap with `z.object()` — reduces boilerplate
- Express middleware restored Resource-Server auth glue (`requireBearerAuth`, `mcpAuthMetadataRouter`)
- Tasks support: retrieve stored result from `tasks/result` for failed tasks
- Custom-method support via 3-arg `setRequestHandler`
- Stdio transports moved to `./stdio` subpath export
- Fallback to `z.toJSONSchema` for Zod schemas without `~standard.jsonSchema`
- Legacy `moduleResolution: node` support added

**Additional official SDKs:**

- **Go SDK** (`modelcontextprotocol/go-sdk`, 4.5K stars) — maintained with Google
- **C# SDK** (`modelcontextprotocol/csharp-sdk`, 4.3K stars) — maintained with Microsoft; v1.0 stable released March 2026 with full 2025-11-25 spec support (Tier 1)

**SDK Working Group** chartered 2026-05-05. Formalizes cross-SDK spec implementation coordination via `#general-sdk-dev` Discord. SDK tiering system (SEP-1730) gives developers clear signal of spec compliance per SDK.

**v2 dependencies (from npm, 2026-05-10):** The v2 server package is very lean (`zod ^4.0` only). The client package carries OAuth (`jose ^6.1.3`, `pkce-challenge ^5.0.0`, `eventsource ^3.0.2`). Framework adapters have peer deps (`express ^5.2.1` or `hono ^4.11.4`). This means you only pay for what you use — a significant improvement over the v1 monolith (17 direct dependencies).

**Impact for us:** Migration from v1 to v2 will require updating imports. The `@modelcontextprotocol/express` adapter now has restored auth glue, making embed-in-Express migration viable. The raw Zod shape support means our existing schemas work with less boilerplate. Wait for v2 stable (estimated Q3 2026) before evaluating.

---

## Enterprise Readiness Assessment

Excluding permissioning (COD-109), here is what an enterprise-grade MCP server needs and where we stand:

### Tier 1 — Must-have for production

| Capability                           | Status       | Notes                                                                                                          |
| ------------------------------------ | ------------ | -------------------------------------------------------------------------------------------------------------- |
| **Auth middleware**                  | **Resolved** | Bearer token forwarded to Express. Correct for stdio transport.                                                |
| **Graceful shutdown**                | **Resolved** | SIGTERM/SIGINT with `server.close()` + 5s force-exit + double-close guard.                                     |
| **Health check / readiness**         | **Resolved** | Startup probe hits `/health` before connecting transport.                                                      |
| **Request ID / correlation**         | **Resolved** | UUID per tool call as `X-Request-ID` header, included in stderr log.                                           |
| **OTel trace propagation**           | **Resolved** | W3C `traceparent` header per tool call. Ahead of spec (still in draft).                                        |
| **Input validation at MCP boundary** | **Resolved** | Zod schemas validated natively by MCP SDK; downstream tool handlers validate business rules.                   |
| **Structured error envelopes**       | **Resolved** | `ToolCallOutcome` tagged union with 6 outcome variants (5 error codes + ok) + `[CODE] message + Hint:` format. |
| **Concurrency control**              | **Resolved** | `@coda/async` Semaphore(5) limits in-flight tool calls.                                                        |
| **Progress notifications**           | **Resolved** | `progressToken` support with start/complete notifications.                                                     |
| **MCP logging**                      | **Resolved** | `sendLoggingMessage` with level-based forwarding alongside stderr.                                             |

### Tier 2 — Important for scale

| Capability                      | Status       | Gap / Notes                                                                                                                                                              | Effort    | Pattern source                                          |
| ------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | ------------------------------------------------------- |
| **`outputSchema` per tool**     | **Resolved** | 24 tools/skills have typed output schemas. Passthrough tools correctly omit.                                                                                             | Done      | Spec 2025-06-18                                         |
| **Deterministic tool ordering** | **Resolved** | `.sort((a, b) => a.name.localeCompare(b.name))` in `index.ts`.                                                                                                           | Done      | Spec 2025-11-25                                         |
| **`idempotentHint` annotation** | **Resolved** | `toAnnotations()` returns `idempotentHint: true` for all non-destructive tools.                                                                                          | Done      | Spec 2025-03-26                                         |
| **Rate limiting at MCP layer**  | Missing      | Express has rate limiting downstream but MCP process has no protection. Spec says MUST rate-limit. ToolHive now implements per-user per-tool rate limiting as reference. | 2-3 hours | `@coda/async` throttler; ToolHive rate limiting pattern |
| **Tasks extension**             | Missing      | SEP-1686 shipped experimental. Lifecycle gaps being closed (retry semantics, expiry policies). Long-running tools block the MCP channel.                                 | 6-8 hours | Spec 2025-11-25 (experimental); Agents WG active        |
| **Token refresh / rotation**    | Missing      | Bearer token is static; user must manually copy fresh tokens. ext-auth now offers Enterprise-Managed Authorization via XAA.                                              | 4-6 hours | ext-auth XAA; SEP-2702 (silent refresh)                 |
| **Response body size cap**      | Partial      | 50MB `Content-Length` guard. Chunked responses without `Content-Length` bypass.                                                                                          | 1-2 hours | Streaming accumulation limit for chunked responses      |
| **Metrics export**              | **Resolved** | Dual-write: in-process `ToolMetrics` + OTel OTLP/HTTP export (counters, histograms). Note: duplicate `MeterProvider` bug requires fix — see greenfield review.           | Fix: 1hr  | OTel semconv for MCP; Grafana MCP; Datadog              |

### Tier 3 — Nice-to-have

| Capability                    | Status      | Notes                                                                   | Effort    | Pattern source                            |
| ----------------------------- | ----------- | ----------------------------------------------------------------------- | --------- | ----------------------------------------- |
| **Streamable HTTP transport** | Missing     | Not needed until remote access is required. Bundle with SDK v2.         | 4-6 hours | Playwright (`--port`), Cloudflare Workers |
| **Completions**               | Missing     | Argument autocompletion for prompts and resources.                      | 2-3 hours | MindsDB                                   |
| **SDK v2 migration**          | Not started | v2 still alpha.2 (7 BC issues open). Monitor for stable (est. Q3 2026). | 2-3 hours | Track v2.0.0 stable release               |
| **TTL for list results**      | Missing     | Cache invalidation hints for `tools/list` (SEP-2549). Improves caching. | 1-2 hours | Spec proposal (open SEP)                  |

---

## If We Started Fresh: What Would We Change?

### 1. Embed MCP in Express instead of proxying over HTTP

The SDK v2 `@modelcontextprotocol/express` adapter enables embedding the MCP server directly in the Express app. This would eliminate the HTTP proxy hop, the separate stdio process, and the `CODA_MCP_TOKEN` env var (the MCP server would share the Express auth middleware directly). The architecture becomes:

```
MCP Client -> Streamable HTTP -> Express (MCP middleware) -> Tool Registry
```

**Why we didn't:** The SDK v2 wasn't stable when we started, and the stdio approach was the fastest path. The proxy architecture is correct for v1.

**Should we migrate?** Not yet. Wait for SDK v2 stable. The extra HTTP hop is <5ms on localhost and the proxy approach has been validated by Stripe (same pattern). When v2 ships, the `@modelcontextprotocol/express` adapter would simplify the architecture meaningfully.

<details>
<summary>Previously resolved items (2-8) — collapsed for readability</summary>

Items 2-8 were resolved in prior rounds: outputSchema on 24 tools, null object pattern for all DI, options object for `logToolCall`, deterministic ordering, `mcpSupported` moved to exclusion set, module split, and request correlation.

</details>

### 9. Unify `ToolResult.content` type contract (NEW — Round 7)

**Severity: P1.** The `looksLikeJson` heuristic in `tool-execute-handler.ts` sniffs the first character of `result.content` to decide whether to embed JSON directly into the response. This is a contract smell: `ToolResult.content` is typed as `string` but callers must know it is always JSON from `formatToolResult`. If any tool handler ever returns non-JSON string content, the heuristic silently falls through. If starting fresh, `ToolResult.content` should be `unknown` (raw data) and the handler calls `res.json(result)` once with no heuristic.

### 10. Single-source config validation (NEW — Round 7)

**Severity: P1.** `loadConfig()` validates `timeoutMs` and `concurrency` with manual `Number.isFinite` checks, then passes them to `McpConfigSchema.safeParse` which validates them again. The Zod schema has `.positive()` and `.int()` constraints that are unreachable because the imperative pre-checks throw first. Use `z.preprocess` uniformly and eliminate the manual pre-checks — the schema becomes the single source of truth.

### 11. Encode annotation mutual exclusivity in types (NEW — Round 7)

**Severity: P2.** `ToolAnnotations` allows both `readOnlyHint: true` and `destructiveHint: true` simultaneously. The `toAnnotations` function enforces correctness at runtime, but the type should be a discriminated union: `{ readOnlyHint: true; idempotentHint: true } | { readOnlyHint: false; destructiveHint: true }`.

### 12. Align `ToolExecutionContext` / `ResultContext` field names (NEW — Round 7)

**Severity: P2.** `ToolExecutionContext.logger` maps to `ResultContext.mcpLogger` via manual construction in `handleToolCall`. This renaming is a maintenance risk — either align names or derive `ResultContext` from `ToolExecutionContext` via `Pick<>`.

### 13. Move exclusion reason onto `ToolDefinition` (NEW — Round 7)

**Severity: P2.** `MCP_EXCLUDED_TOOLS` uses hardcoded string literals to avoid circular imports. Put the exclusion reason on `ToolDefinition` itself: `mcpRequires?: 'snowflake-pool' | 'notion-oauth' | 'runner-rpc'`. A tool without this field is MCP-compatible by default. Eliminates the separate exclusion set, the contract test, and the comment explaining why string literals are used.

### 14. Guard `structuredContent` against truncation inconsistency (NEW — Round 7)

**Severity: P2.** When truncation fires, `text` content is truncated but `structuredContent` contains the full untruncated data. This means a client relying on `structuredContent` gets the full payload while one relying on `text` gets truncated data. Either truncate `data` before building `structuredContent`, or set `structuredContent` only when `!truncated`.

---

## What Should We Adopt From Other MCPs?

<details>
<summary>Resolved (items 1-15) — collapsed for readability</summary>

Items 1-15 all resolved: graceful shutdown, request correlation, health probe, structured error envelopes (5 error codes + ok variant), OTel trace propagation, MCP Resources (3), Prompts (4), setup command, progress notifications, MCP logging, structured content, concurrency control (Semaphore), outputSchema (24 tools), deterministic ordering, idempotentHint.

</details>

### Next priorities

16. **Rate limiting at MCP layer** (spec requirement) — The spec says servers MUST rate-limit tool invocations. We rely on Express middleware downstream but the MCP process itself has no protection. A token-bucket from `@coda/async` would prevent cascading load.

17. **Tasks extension** (SEP-2663) — Tasks are being extracted from core spec into an extension. Full state machine for async execution (`working` → `completed`/`failed`). Would address long-running tool problem. Wait for SEP-2663 to finalize before implementing.

18. ~~**Response body size cap**~~ — **Partial.** 50MB `Content-Length` guard in `http-client.ts`. Chunked responses without `Content-Length` still bypass the check. Need streaming accumulation limit.

### Future (bundle with SDK v2)

19. **Streamable HTTP transport** — Deploy as Fargate service with `/mcp` endpoint. Stdio becomes a thin local proxy (Stripe's pattern).
20. **Sampling** — Server-side LLM requests via `sampling/createMessage`. Could enable content summarization without Bedrock tokens.
21. **Completions** — Argument autocompletion for prompts and resources.

### Ecosystem patterns worth monitoring

22. **MCP-to-OpenAPI bridge** (mcpo, 4K stars) — Wraps MCP servers as REST APIs. Validates our `POST /api/v1/tools/execute` endpoint. If this pattern gains adoption, our endpoint becomes a standard integration point.

23. **Container-based MCP platform** (ToolHive, 2K stars) — Enterprise pattern for running multiple MCP servers with isolation, audit logging, centralized management. Relevant if we deploy MCP servers for multiple teams.

24. **Enterprise MCP gateway** (mcp-gateway-registry) — OAuth gateway with Keycloak/Entra ID for centralized auth across MCP servers. Relevant for our eventual remote transport + permissioning story.

### New ecosystem developments (Round 7, 2026-05-09)

25. **MCP Extensions system** — Official extension system launched with vendor-prefixed identifiers (`{vendor}/{name}`), negotiation protocol via `extensions` capability, and two initial repos:
    - **`ext-auth`**: OAuth Client Credentials flow and **Enterprise-Managed Authorization (XAA)** — directly relevant to COD-109. XAA lets MCP Clients obtain tokens from MCP Server auth servers via enterprise IdP assertions. Live today with Okta, Google Workspace support.
    - **`ext-apps`** (2.2K stars, stable spec 2026-01-26): Interactive UI components inline in conversations — dashboards, forms, 3D viewers, maps. Day-one support in Claude, ChatGPT, Goose, VS Code. Launch partners: Amplitude, Asana, Box, Canva, Figma, Hex, Slack. 15+ working examples. Azure Functions MCP extension support added Feb 2026. Relevant for revenue chart visualization.

26. **SEP-2567: Sessionless MCP (merged 2026-05-07)** — **MAJOR.** `Mcp-Session-Id` header removed entirely. All cross-call state uses explicit server-minted handles as tool arguments. Validates our stateless stdio approach and simplifies future Streamable HTTP adoption.

27. **SEP-2322: Multi Round-Trip Requests (merged 2026-05-06)** — **MAJOR.** `IncompleteResult` renamed to `InputRequiredResult`. Multi-step tool call flows formalized. Not needed for our current tools but important for future interactive tools.

28. **Tasks (SEP-1686) — shipped experimental, lifecycle gaps being closed.** Retry semantics (who retries transient failures?) and expiry policies (how long results are retained?) are the two concrete gaps being addressed by the Agents WG. This supersedes the earlier SEP-2663 references. Implement when lifecycle gaps are closed.

29. **SDK Working Group (chartered 2026-05-05)** — Formalizes cross-SDK spec implementation coordination. SDK tiering system (SEP-1730) establishes Tier 1/2/3 compliance levels.

30. **OTel semantic conventions for MCP published** — Official semantic conventions at `opentelemetry.io/docs/specs/semconv/gen-ai/mcp/`. Defines standard span names, attributes, and metrics for MCP operations. FastMCP has native OTel instrumentation. Validates our `traceparent` approach; formalizes the path to full OTel export.

31. **Streamable HTTP adoption: 28% of MCP servers** — 67% local stdio, 28% remote Streamable HTTP, 5% deprecated SSE. Managed-hosting share projected to reach 50%+ within 12 months. Transport evolution in June 2026 spec will address horizontal scaling and stateless session handling.

32. **Enterprise WG forming** — Audit trails, enterprise-managed auth (XAA paved paths), gateway/proxy patterns, and configuration portability. Output expected as extensions rather than core spec changes.

33. **ToolHive platform evolution** — Per-user per-tool rate limiting, Redis-backed horizontal scaling, embedded OAuth authorization server in vMCP, claim-based authorization for registry entries, local CLI mode (no Kubernetes needed), threaded chat + MCP Apps in Playground. Reference enterprise implementation.

34. **12,000+ MCP servers across ecosystem** — GitHub, npm, PyPI, Smithery, Glama, PulseMCP registries. 97M+ monthly SDK downloads. FastMCP powers ~70% of MCP servers across all languages.

35. **Tool `title` field** (2025-11-25) — Human-readable display name separate from programmatic `name`. Not yet surfaced in our `toMcpToolConfig()`. Low priority.

36. **JSON Schema 2020-12** established as default dialect for schema definitions (2025-11-25). Zod v4's `z.toJSONSchema()` outputs draft-07 by default — may need `$schema` annotation for strict compliance.

### Notable new repos (since Round 5)

| Stars | Repo                             | Domain                                    | Relevance                            |
| ----- | -------------------------------- | ----------------------------------------- | ------------------------------------ |
| 22K   | activepieces/activepieces        | AI workflow automation (~400 MCP servers) | Enterprise MCP orchestration pattern |
| 21K   | ahujasid/blender-mcp             | Blender 3D integration                    | Niche domain MCP pattern (3D/CAD)    |
| 16K   | microsoft/mcp-for-beginners      | Official MS MCP curriculum                | Documentation best practices         |
| 12K   | tadata-org/fastapi_mcp           | FastAPI → MCP bridge                      | Auto-expose API endpoints as tools   |
| 10K   | mcp-use/mcp-use                  | Fullstack MCP framework                   | MCP Apps pattern for rich clients    |
| 8.8K  | LaurieWired/GhidraMCP            | Ghidra reverse engineering MCP            | Niche domain MCP pattern             |
| 8.7K  | mark3labs/mcp-go                 | Community Go MCP                          | Alternative Go implementation        |
| 8K    | idosal/git-mcp                   | Remote MCP for GitHub repos               | Remote MCP pattern                   |
| 5.5K  | executeautomation/mcp-playwright | Browser automation + web scraping         | Alternative to official Playwright   |
| 3.8K  | dagger/container-use             | Containerized agent environments          | Sandboxed tool execution pattern     |
| 2.3K  | metatool-ai/metamcp              | Unified MCP middleware with GUI           | Router + dashboard UX pattern        |

### Open SEPs to monitor

| SEP      | Title                                    | Relevance                                               |
| -------- | ---------------------------------------- | ------------------------------------------------------- |
| SEP-1686 | Tasks (lifecycle gaps)                   | Retry semantics + expiry policies; Agents WG active     |
| SEP-2549 | TTL for List Results                     | Cache invalidation for `tools/list` — improves caching  |
| SEP-2672 | Per-Call Passkey Verified Approval       | Enterprise security for destructive tools               |
| SEP-2127 | MCP Server Cards (.well-known)           | Enterprise server discovery; Server Card WG active      |
| SEP-2448 | MCP Server Execution Telemetry           | Standardized observability; OTel semconv already exists |
| SEP-2702 | Client Silent Refresh on 401             | Automatic token refresh                                 |
| SEP-2356 | File Input Support for Tools             | File upload in tool calls                               |
| SEP-1932 | DPoP (Demonstrating Proof of Possession) | Enhanced token security; sponsored work underway        |
| SEP-1933 | Workload Identity Federation             | Federated identity for machine-to-machine auth          |
| SEP-2133 | Experimental Extensions                  | Framework for WG/IG experimentation before formal SEPs  |

---

## Auth Landscape (2025-11-25 spec)

The auth story has matured significantly. Key patterns:

| Pattern                           | Spec status   | Relevance to us                                                  |
| --------------------------------- | ------------- | ---------------------------------------------------------------- |
| OAuth 2.1 + PKCE (S256 mandatory) | Required      | Future — when we add Streamable HTTP transport                   |
| Protected Resource Metadata       | **Required**  | Servers MUST expose `/.well-known/oauth-protected-resource`      |
| Client ID Metadata Documents      | Recommended   | Replaces Dynamic Client Registration for client-server trust     |
| Incremental scope consent         | Stable        | Step-up authorization via `WWW-Authenticate` challenges          |
| Resource Indicators (RFC 8707)    | Mandatory     | Tokens bound to specific MCP server URIs                         |
| Token passthrough                 | **Forbidden** | Servers MUST NOT forward client tokens to upstream APIs          |
| Bearer token (env var)            | Adequate      | Correct for our stdio transport; no protocol auth needed locally |

**Impact for us:** Our Bearer token approach is correct for stdio. When we move to remote transport, we'll need OAuth 2.1 + Protected Resource Metadata. This is a COD-109 / SDK v2 concern, not a current gap.

---

## Summary Matrix

| Dimension               | Best-in-class                  | Coda current                                                | Status                              |
| ----------------------- | ------------------------------ | ----------------------------------------------------------- | ----------------------------------- |
| **Architecture**        | Stripe (same proxy pattern)    | Proxy via HTTP                                              | Validated by Stripe, mcpo           |
| **Tool registration**   | GitHub (toolset groups)        | Static array + composable predicates                        | Adequate                            |
| **Schema format**       | Zod (TS) / Pydantic (Python)   | Zod v4 (`z.object`)                                         | Resolved                            |
| **Tool annotations**    | Playwright, Skyvern            | `toAnnotations()` per tool (`destructive` + `idempotent`)   | Resolved                            |
| **Server instructions** | Skyvern (5K chars)             | `SERVER_INSTRUCTIONS` (~2K)                                 | Resolved                            |
| **Auth**                | Cloudflare (OAuth 2.1 + PKCE)  | Bearer token env var                                        | Correct for stdio                   |
| **Error handling**      | Skyvern (structured envelope)  | `ToolCallOutcome` tagged union + hints                      | Resolved                            |
| **Response truncation** | Skyvern (140K cap)             | `serializeResponse()` 100K structural                       | Resolved                            |
| **Transport**           | Stripe (stdio + Streamable)    | stdio only                                                  | Correct; Streamable with SDK v2     |
| **Testing**             | Playwright (E2E via client)    | Unit + integration (170+ tests, 17 files)                   | Resolved (gaps in telemetry/setup)  |
| **Observability**       | Cloudflare (metrics + Sentry)  | JSON stderr + X-Request-ID + traceparent + OTel OTLP export | Resolved (fix MeterProvider bug)    |
| **Graceful shutdown**   | Standard                       | SIGTERM/SIGINT + 5s force-exit                              | Resolved                            |
| **Request correlation** | Standard                       | X-Request-ID + W3C traceparent                              | Resolved                            |
| **Health check**        | Standard                       | Startup probe against `/health`                             | Resolved                            |
| **Structured content**  | Spec 2025-06-18                | `structuredContent` returned on success                     | Resolved                            |
| **Output schemas**      | Spec 2025-06-18                | `outputSchema` on 24 tools/skills                           | **Resolved**                        |
| **Deterministic order** | Spec 2025-11-25                | `.sort()` by name                                           | **Resolved**                        |
| **`idempotentHint`**    | Spec 2025-03-26                | All non-destructive tools marked idempotent                 | **Resolved**                        |
| **Progress notifs**     | Spec 2025-03-26                | `progressToken` start/complete                              | Resolved                            |
| **MCP logging**         | Spec 2025-03-26                | `sendLoggingMessage` + stderr                               | Resolved                            |
| **Resources/Prompts**   | MindsDB (all features)         | 3 resources + 4 prompts                                     | Resolved                            |
| **Config UX**           | Skyvern (setup command)        | `pnpm mcp:setup` for 3 clients                              | Resolved                            |
| **Rate limiting**       | ToolHive (per-user per-tool)   | Express only — no MCP-layer cap                             | **Gap — P2**                        |
| **Tasks**               | SEP-1686 (lifecycle gaps open) | Not implemented                                             | **Gap — P2 (wait for lifecycle)**   |
| **Concurrency control** | Standard                       | Semaphore(5) from `@coda/async`                             | Resolved                            |
| **Sessionless MCP**     | SEP-2567 (merged 2026-05-07)   | Stateless stdio — no session management                     | **Aligned** with new spec direction |
| **OTel semconv**        | Published (genai repo)         | W3C traceparent + OTLP export (counters, histograms)        | Aligned; adopt `mcp.method.name`    |
| **Enterprise auth**     | ext-auth XAA (live)            | Bearer token env var                                        | Correct for stdio; XAA for remote   |
| **SDK version**         | v2 alpha.2 (7 BC issues open)  | v1.29.x (maintenance)                                       | Track v2 stable (est. Q3 2026)      |

---

## Verdict

Our MCP server implementation is architecturally sound, well-tested (170+ tests across 17 files), and feature-rich. The Round 8 greenfield review (7 parallel agents) found **one critical bug** (duplicate `MeterProvider` with leaked exporter) and **one correctness bug** (`checkHealth()` timeout handling inconsistent with `executeTool()`). Convention compliance is excellent — passes all code-style checks, zero `any`, exhaustive switches, interface-first DI throughout.

The proxy-through-HTTP approach has been independently validated by Stripe (same pattern), mcpo (MCP-to-OpenAPI bridge), and microsoft/mcp-gateway (reverse proxy). The Zod v4 migration aligns with the TypeScript MCP ecosystem, and our schemas are forward-compatible with SDK v2's Standard Schema support.

All 15 originally identified enterprise features are implemented. The `ToolCallOutcome` discriminated union rated 5/5 across all four type-design dimensions (encapsulation, invariants, usefulness, enforcement) — "textbook" design.

**Excluding permissioning (COD-109)**, the remaining gaps are:

**Bugs to fix (from greenfield review):**

1. **Duplicate `MeterProvider` in `telemetry.ts`** — orphaned instruments, leaked exporter, duplicate OTLP flush (~1 hour)
2. **`checkHealth()` timeout handling** — missing `DOMException` check consistent with `executeTool()` (~15 min)

**Enterprise gaps:** 3. **Rate limiting at MCP layer** — token bucket from `@coda/async` (~2-3 hours). ToolHive provides reference with per-user per-tool rate limiting. 4. **Tasks** — SEP-1686 shipped experimental; lifecycle gaps (retry, expiry) being closed by Agents WG (~6-8 hours when ready) 5. **Response body size cap** — streaming accumulation limit for chunked responses (~1-2 hours) 6. **SDK v2 migration** — when v2 goes stable (track release, est. Q3 2026)

Full greenfield review with 15 prioritized recommendations at `docs/superpowers/reviews/greenfield-review-mcp-server.md`.

Items 1 and 3 are the substantive near-term gaps. Item 2 is blocked on lifecycle gap resolution. Items 4-5 are operational maturity.

None are blockers for an initial release. The MCP server is production-ready for its current use case (local Claude Code/Desktop integration via stdio).

### Comprehensive review findings (Round 7)

Six specialized review agents analyzed the PR in parallel: greenfield architecture, silent failure analysis, type design, test coverage, documentation quality, and PR code review.

#### Architecture findings (P1)

| #   | Finding                                                                                                         | Severity | Effort |
| --- | --------------------------------------------------------------------------------------------------------------- | -------- | ------ |
| 1   | `looksLikeJson` heuristic is a contract smell — `ToolResult.content` should be `unknown`, not `string`          | P1       | Medium |
| 2   | Config validation duplicated between imperative checks and Zod schema — schema should be single source of truth | P1       | Small  |
| 3   | `ToolExecutionContext` / `ResultContext` field name mismatch (`logger` vs `mcpLogger`) — maintenance risk       | P1       | Small  |

#### Silent failure findings (P0-P1)

| #   | Finding                                                                                                   | Severity | Effort |
| --- | --------------------------------------------------------------------------------------------------------- | -------- | ------ |
| 4   | Fail-open permission bypass in `tool-execute-handler.ts` — COD-109 tracked but should log bypass per call | P0       | Small  |
| 5   | Broad catch block in models endpoint (`routes/index.ts:170-182`) swallows all errors and fails open       | P1       | Small  |
| 6   | Progress notification errors silently swallowed — needs log-once pattern (like `mcp-logger.ts`)           | P1       | Small  |

#### Type design findings (P2)

| #   | Finding                                                                                                 | Severity | Rating  |
| --- | ------------------------------------------------------------------------------------------------------- | -------- | ------- |
| 7   | `McpConfig` — validation duplication, `domains` bypasses Zod via `z.custom()` passthrough               | P2       | 3/3/4/3 |
| 8   | `ToolAnnotations` — mutual exclusivity of readOnly/destructive not encoded in type                      | P2       | 3/3/4/3 |
| 9   | `ToolDefinition` — no startup validation of tool definition arrays (unique names, example/schema match) | P2       | 4/4/5/3 |

#### Test coverage gaps

| Rank | Module                              | Gap                                                                                                    | Criticality |
| ---- | ----------------------------------- | ------------------------------------------------------------------------------------------------------ | ----------- |
| 1    | `tool-result.ts`                    | No direct unit tests for `buildSuccessResult`, `buildErrorResult`, `logToolCall`, `createStderrLogger` | 9/10        |
| 2    | `setup.ts`                          | No tests for config merge, corrupt file handling, directory creation, project root detection           | 8/10        |
| 3    | `http-client.ts`                    | No test for `response.json()` resolving to literal `null`                                              | 7/10        |
| 4    | `tool-execute-handler.ts`           | `looksLikeJson` edge cases (array, boolean, null, number, empty string) untested                       | 6/10        |
| 5    | `tool-caller.ts` / `tool-result.ts` | `hasOutputSchema: true` + truncated non-array object interaction untested                              | 5/10        |

#### Documentation findings

**Strengths:** Comprehensive setup guide with architecture diagram, end-to-end tool call trace (both success and error paths — "exceptionally detailed"), progressive examples (simple/intermediate/advanced), clear "scope and limitations" section with alternatives, env var reference, troubleshooting section, file map. TSDoc consistently present on exports. The `ToolCallOutcome` "why not what" comment and `createShutdownHandler` docblock cited as models.

**Gaps to fix:**

| #   | Issue                                                                                                       | File                            |
| --- | ----------------------------------------------------------------------------------------------------------- | ------------------------------- |
| 1   | Missing `CODA_MCP_CONCURRENCY` env var in documentation table                                               | `docs/guides/mcp-server.md:95`  |
| 2   | Missing `tool-result.ts` from file map                                                                      | `docs/guides/mcp-server.md:234` |
| 3   | "6 error codes" should be "5 error codes + ok variant"                                                      | This doc, line 191              |
| 4   | Stale `z.preprocess` comment — schema doesn't use `z.preprocess`                                            | `config.ts:29-35`               |
| 5   | `structuredContent` note incomplete — must also mention `hasOutputSchema` condition                         | `docs/guides/mcp-server.md:456` |
| 6   | Missing TSDoc on `tool-filter.ts` (all 4 functions), `toAnnotations()`, `toMcpToolConfig()`, `loadConfig()` | Various                         |
| 7   | Comment rot risk: hardcoded test filename in `instructions.ts` — reference by behavior instead              | `instructions.ts:1-9`           |

### What we'd improve if starting fresh (summary)

1. **`ToolResult.content` should be `unknown`** — eliminates `looksLikeJson` heuristic, the raw-string fallback log warning, and the hidden serialization contract
2. **Zod schema as single source of truth** — `z.preprocess` for all config fields; no manual pre-checks
3. **Exclusion reason on `ToolDefinition`** — `mcpRequires?: 'snowflake-pool' | ...` instead of separate `MCP_EXCLUDED_TOOLS` set
4. **Startup validation of tool definitions** — unique names, examples match schemas, permissions follow pattern
5. **Discriminated union for `ToolAnnotations`** — `readOnly + idempotent` | `destructive` makes invalid states unrepresentable

### What we should adopt

1. **Per-user per-tool rate limiting** (ToolHive pattern) — spec says MUST rate-limit
2. **OTel export** — semantic conventions now published; path from in-process metrics to Datadog/Grafana is clear
3. **Enterprise-Managed Authorization (ext-auth XAA)** — inform COD-109 design; enables SSO-integrated flows
4. **ext-apps for revenue visualization** — interactive charts/dashboards inline in conversations
5. **MCP Server Cards** (`.well-known` discovery) — when Server Card WG ships

### Are we enterprise-production-ready?

**Yes, for the current use case (local stdio).** The auth stack is correct (Bearer token → Express middleware → tenant resolution), all error paths are structured and traced, concurrency is controlled, and 194 tests cover the critical paths. The PR code review found zero security vulnerabilities.

**Not yet for remote deployment.** Missing: MCP-layer rate limiting (spec requirement), Tasks for long-running tools, OTel export sink, token refresh, and Streamable HTTP transport. These are tracked and none block the initial release.

### Ecosystem signals to track

- **June 2026 spec cycle** — transport evolution (stateless Streamable HTTP, scalable sessions, Server Cards)
- **Enterprise WG** — audit trails, auth, gateway patterns, config portability
- **SEP-1686 lifecycle gaps** — when retry semantics + expiry policies close, implement Tasks
- **ext-auth XAA** — inform COD-109 permissioning design
- **ext-apps** — revenue chart visualization opportunity
- **SDK v2 stable** — when released, evaluate `@modelcontextprotocol/express` embed migration
- **OTel semconv for MCP** — implement OTel export aligned with published conventions

---

### New ecosystem insights (Round 9, 2026-05-10)

37. **Stripe MCP is now a pure proxy** — The `@stripe/mcp` npm package is a stdio-to-HTTP proxy to `mcp.stripe.com`. No local tool execution. The remote server provides curated tools with permission scoping via Restricted API Keys. This is the closest architectural analog to our MCP server and directly validates the proxy pattern.

38. **GitHub MCP has toolset-level instructions** — Each toolset (repos, issues, PRs, etc.) can inject its own server instructions via a generator function. These are concatenated into the system prompt alongside global instructions. Consider: our `SERVER_INSTRUCTIONS` could be decomposed per domain for better context targeting.

39. **GitHub MCP has tool snapshot testing** — `__toolsnaps__/` files capture the JSON Schema of each tool's definition. Tests compare current schemas against snapshots to catch accidental regressions. Consider adding this pattern for our Zod-to-JSON Schema output.

40. **ToolHive has Kubernetes Operator with CRDs** — `MCPServer`, `MCPRegistry`, and `MCPTelemetryConfig` CRDs for declarative MCP server management. Pre-built Grafana dashboards for OTel data. Not relevant for our local-first deployment but shows enterprise direction.

41. **ToolHive has semantic tool search** — Filters which tools from child MCP servers are exposed based on semantic relevance to the current task. Claims 85% token savings. Relevant concept for our domain filtering — could dynamically adjust exposed tools based on conversation context.

42. **Grafana MCP has gold-standard OTel** — Full stack: `otelhttp` for HTTP instrumentation, `otelslog` for structured logging bridged to OTel, Prometheus metrics exposition, OTLP trace+log exporters. Three test tiers (unit, integration, E2E). This is the OTel implementation we should aspire to when we deepen our telemetry.

43. **Google Toolbox has YAML-driven tools** — Zero-code tool definition. Database connections, queries, and toolsets all in `tools.yaml`. Four client SDKs (Python, TypeScript, Go, Java). Prebuilt configs for 20+ databases. Validates that tool definition should be declarative data, which our Zod schemas already achieve in TypeScript.

44. **Notion MCP being sunsetted** — The local `@notionhq/mcp-server` is being replaced by Notion's remote MCP server at `developers.notion.com/docs/mcp`. This follows the Stripe pattern of centralized remote MCP servers. Signal: the industry is moving toward remote-first MCP servers.

### What we should adopt (updated from Round 9)

| Priority | Pattern                        | Source         | Effort | Notes                                                          |
| -------- | ------------------------------ | -------------- | ------ | -------------------------------------------------------------- |
| **P1**   | Tool snapshot testing          | GitHub         | 2-3h   | Add `__toolsnaps__/` for Zod-to-JSON Schema regression testing |
| **P1**   | Rate limiting at MCP layer     | ToolHive       | 2-3h   | `TokenBucketThrottler` from `@coda/async`                      |
| **P2**   | Per-domain server instructions | GitHub         | 1-2h   | Decompose `SERVER_INSTRUCTIONS` per domain                     |
| **P2**   | Deeper OTel (slog bridge)      | Grafana        | 3-4h   | Bridge stderr JSON logs to OTel traces                         |
| **P3**   | Semantic tool search           | ToolHive       | 4-6h   | Context-aware tool filtering (reduce token usage)              |
| **P3**   | Tool disable flags             | Grafana/GitHub | 1-2h   | `--disable-adjustments` CLI flag for granular control          |

---

_Round 9 analysis conducted 2026-05-10. Full comprehensive review via 6 parallel agents (PR code review + silent failure analysis + type design analysis + test coverage analysis + deep architecture exploration + ecosystem research of 10 repos). Per-repo comparison docs at `docs/reference/comparisons/mcp/`. Key new findings: Stripe confirms pure proxy pattern, GitHub adds toolset instructions + snapshot testing, Grafana shows gold-standard OTel, ToolHive advances to K8s Operator. SDK v2 still alpha.2. Industry trend: remote-first MCP servers replacing local-only._
