Stateless MCP agent adapter over the authoritative NUIF core
Document status:
verified. Canonical source.
Summary
MCP 2026-07-28 replaced its protocol handshake and hidden session with a
stateless core. Each request carries protocol and client metadata, optional
server/discover reports server support, and application state must be an
explicit value or handle. Tool schemas use JSON Schema 2020-12 and structured
tool results remain machine-readable. Roots, sampling and protocol logging are
deprecated; a stdio server logs only on stderr and reserves stdout for MCP
messages.
That architecture matches NUIF only when MCP remains a process adapter. The
canonical model, validation, hashing and semantic patch behavior stay in the
Rust core. nuif-mcp-tools-0 therefore exposes four pure tools over inline
canonical text: validate, inspect, canonicalize and apply-patch. Applying a
patch transforms a supplied value and returns a new canonical value; it does
not mutate a host file or keep a hidden document session. The first profile has
no resources, prompts, tasks, sampling, roots, HTTP, OAuth, filesystem,
network, host-document or credential authority.
The implementation uses the official rmcp 3.1.4 server and its generated
schemas rather than reproducing a newly changed protocol by hand. It pins the
only supported protocol revision to 2026-07-28 and uses a current-thread Tokio
runtime. A NUIF-owned reader limits a JSON line before the SDK’s stdio
transport can accumulate it; document, patch, transaction and operation limits
then apply at progressively more semantic layers.
Evidence
- The final 2026-07-28 announcement removes
initialize/initializedandMcp-Session-Id, requires request metadata for the stateless lifecycle, and introduces optionalserver/discover. It recommends explicit application handles rather than transport-hidden state. Locator: The 2026-07-28 Specification, “No handshake or sessions”, retrieved 2026-08-30: https://blog.modelcontextprotocol.io/posts/2026-07-28/. - The same announcement marks roots, sampling and logging deprecated. The release-candidate detail identifies stderr as the stdio logging replacement and records full JSON Schema 2020-12 for tool input and output schemas. Locator: “Roots, Sampling, and Logging Are Deprecated” and “Full JSON Schema 2020-12 for Tools”, retrieved 2026-08-30: https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/.
- The transport contract uses newline-delimited UTF-8 JSON-RPC, requires stdout to contain only protocol messages, and permits logging on stderr. Locator: MCP specification, Transports, “stdio”, retrieved 2026-08-30: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports. The final 2026 revision retained stdio while replacing the HTTP lifecycle.
- The official Rust SDK describes
rmcpas its protocol crate over Tokio. Its current roadmap reports complete dated 2025-11-25 and 2026-07-28 client and server conformance suites, while separately tracking features that those suites do not exercise. Locator:ROADMAP.md, “Conformance” and “Spec features without conformance scenarios”, retrieved 2026-08-30: https://github.com/modelcontextprotocol/rust-sdk/blob/main/ROADMAP.md. rmcp3.1.4 declares Rust 1.88, Apache-2.0, optional protocol features and an officialtransport-ioserver surface. NUIF enables only macros, server and stdio; HTTP, client, OAuth, base64, tasks and provider features are absent. Locator: crates.io package metadata and the locked manifest, retrieved 2026-08-30: https://crates.io/crates/rmcp/3.1.4.rmcp3.1.4’sAsyncRwTransport::receivecallsread_untilinto a reusable vector without applying theJsonRpcMessageCodec::new_with_max_lengthoption. The NUIF wrapper therefore must bound the reader itself before transport parsing. Locator:crates/rmcp/src/transport/async_rw.rsat tagrmcp-v3.1.4,receiveandJsonRpcMessageCodec, retrieved 2026-08-30: https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.1.4/crates/rmcp/src/transport/async_rw.rs.
Mechanism
The host launches nuif-mcp with piped stdin and stdout. A bounded asynchronous
reader permits at most 4 MiB before a newline and closes the connection on the
first excess byte. The official router verifies the 2026 request envelope,
decodes each tool’s generated object schema and dispatches into a stateless
handler. The handler accepts at most 1 MiB each of inline document and patch
text. It decodes documents through CanonicalText, measures patch cardinality
through nuif-protocol, and delegates mutation to a temporary nuif-api
Session. Successful values use declared output schemas; execution failures
are tool errors with stable NUIF_* prefixes so an agent can correct input.
All tools declare read-only, non-destructive, idempotent and closed-world annotations because they transform caller-owned values without external side effects. These are truthful hints, not an authorization mechanism. A host must still choose whether to launch the process and whether to pass its output into a privileged product API.
The full NUIF document is deliberately not mirrored into MCP types. Typed MCP records describe only arguments and bounded results; canonical document and patch strings cross the boundary. This keeps the protocol shell replaceable and makes direct Rust, CLI, WASM and MCP results comparable by canonical hash.
NUIF relevance
Choose the official Rust SDK over a handwritten JSON-RPC loop. The 2026 revision changed lifecycle, request metadata, result discrimination, schema rules and server-to-client interaction together. Reimplementing that surface would create protocol work unrelated to NUIF semantics.
Choose in-process Rust over a TypeScript or Python SDK sidecar. Those SDKs are valid alternatives for applications already implemented in those languages, but a NUIF sidecar would need a second private RPC to the Rust core, duplicate packaging and add another failure boundary. Rust SDK tier status is therefore a monitored delivery risk, not a reason to duplicate the core.
Choose stdio first over Streamable HTTP. Local development clients already own process launch and authorization, while stdio adds no listener, origin, TLS, OAuth or multi-tenant policy. A future HTTP profile is a distinct security product and must define authentication, authorization, request concurrency, tenant isolation, origin validation, rate limits and deployment observability before code is enabled.
Reject file-path tools in profile zero. They make a model-selected string
an ambient filesystem capability and prevent deterministic cross-surface
tests. Large documents and .nuif packages remain available through the CLI,
WASM or direct API where the host explicitly owns bytes and resources.
Open questions
- Which real MCP hosts correctly consume 2026-07-28 stateless stdio requests, output schemas and tool annotations must be proven by a pinned live-client matrix; SDK conformance alone is not host-product evidence.
- The 1 MiB inline text limit is conservative and must be retained or changed from measured agent workloads, not raised merely to match the 16 MiB codec envelope.
- A resource-handle extension may become useful for large documents, but it requires an explicit host-owned capability grant and lifecycle rather than a server-invented path namespace.
- A remote MCP service remains out of scope until its separate security and operations RFC is accepted.