s-m-r-t
Open the s-m-r-t source on GitHub Switch to dark color scheme
← Developer tooling

Developer tooling

Protocol support, conformance, and troubleshooting

The MCP surfaces target the 2026-07-28 protocol revision through an exactly pinned scoped SDK. They keep a bounded set of compatibility aliases. Continuous integration runs conformance checks.

Verified against s-m-r-t 0.42.4

One protocol revision, one pinned SDK

Both MCP packages depend on @modelcontextprotocol/server at exactly 2.0.0, with no range. That SDK owns and enforces the 2026-07-28 revision. The framework does not declare the revision as a constant. The exact pin provides one known source for the protocol envelope, header validation, and error codes.

  • The application HTTP mount serves the 2026-07-28 envelope, always reports tools, and advertises the optional tasks extension only when configured.
  • Client-side pins in the framework test suites request the same revision explicitly.
  • The scoped client and node packages are pinned to 2.0.0 as well.

What conformance covers

Continuous integration runs a generated server against the pinned conformance suite. Every pull request also runs a protocol hygiene check. The suite tests version negotiation against the pinned revision and rejects unsupported client revisions.

  • Conformance tooling is pinned exactly, like the SDK itself.
  • Header validation and the mismatch error are covered by transport tests.
  • Deterministic tool ordering is part of the expected discovery output.

Compatibility that is deliberate and bounded

A small number of older shapes remain available so applications can migrate without a coordinated cutover. Each is documented as deprecated, and none of them is a second supported transport.

  • mountMcpToolsRoute and mountMcpCallRoute are REST-shaped aliases retained for one release.
  • They are not an MCP transport; new work should mount the single modern route.
  • resolveUser and resolveAuthenticated remain as legacy identity hooks.
  • The modern mount rejects legacy protocol handling rather than negotiating down.
  • Development tools return structured content beside the original text payload, so text-only clients keep working.

Optional capabilities stay explicit

Durable MCP tasks are available as an experimental, opt-in extension. Their capability is absent unless an allowed object declares at least one task action, so an ordinary tools-only client sees the same surface as before.

  • Task lifecycle state lives in the jobs runtime rather than an MCP transport session.
  • Application deployments must run the mcp-tasks worker and provide a stable principal identity for lifecycle operations.
  • The development plugin declares no streamable HTTP transport in this release.

Local troubleshooting starts with the transport

A stdio MCP server speaks JSON-RPC on stdout, so anything else written there corrupts the channel. Do not call framework code that writes SDK logger progress from a tool path. Suppressing console output does not fix the problem. Write diagnostic logs to stderr.

  • Set DEBUG to true in the server environment to enable diagnostic logging.
  • A client that fails immediately after launch is usually launching the wrong path or the wrong Node runtime.
  • A package-manager launcher can emit its own output before the server starts; prefer an absolute launcher.

Remote failures are usually authorization, not protocol

On the HTTP surface, a rejected call is far more often an identity problem than a protocol one. A -32020 response means a required header was missing or disagreed with the body. A denial carries the non-retryable access-denied code. The denial reveals nothing about the tool, principal, or policy. Find the details in your gateway logs.

  • Confirm the gateway validated the token before the request reached the route.
  • Compare the response issuer and the discovered issuer as exact strings.
  • A token minted for another issuer, audience, or resource must not dispatch.
  • An empty discovery result usually means policy hid the tools rather than that none exist.

Keep deployment and authorization boundaries explicit

Each surface has one supported deployment boundary. Development MCP and the Agent Plugin run locally for a coding-agent client. Generated stdio runs locally beside the application. Hosted application MCP runs behind a gateway that terminates authorization. WebMCP runs in the signed-in browser session.

  • Do not expose Development MCP or generated stdio as a remote server.
  • The hosted route trusts the principal that the application adapter supplies. It does not validate bearer tokens.
  • The gateway must validate the token before it creates the request principal.
  • WebMCP sends operations through the generated REST boundary as the signed-in page user.
  • The Agent Plugin manifest contains no credentials or remote transport settings.

Cache and tenancy safety

Catalogs are private by default on both Development MCP and application MCP. A shared catalog requires explicit opt-in. The server re-verifies the declared shape and downgrades invalid catalogs. This check prevents tenant-scoped or principal-gated tools from entering a shared cache. Workspace knowledge resources use a zero cache lifetime because the server rebuilds them per request. They carry no reliable invalidation signal.

  • Tenant interceptors and field policy stay in the path for every generated operation.
  • Never expose the generated stdio server remotely; it has no per-request principal.
  • Keep issuer metadata, client documents, and gateway policy in deployment source control.