Expand description
Library surface for noyalib-mcp.
Hosts the JSON-RPC 2.0 dispatch logic and the tool implementations.
The noyalib-mcp binary in main.rs is a thin stdio loop that
drives handle_message; tests reach the same handlers
directly so coverage no longer depends on standing up a real
stdio process.
§Cargo features
This crate exposes no optional features; the MCP tool set
(noyalib_get, noyalib_set, noyalib_set_multidoc) is
fixed. Optional noyalib
features pulled in by a downstream packager (schema,
parallel, …) do not change the MCP wire surface — they
only affect what noyalib::Error messages can appear inside
tool-call error envelopes. The canonical noyalib feature
matrix lives in
crates/noyalib/src/lib.rs.
§MSRV
Rust 1.86.0 stable — same as the core noyalib library
(and this crate’s rust-version; an earlier revision of this
paragraph said 1.75.0 while the manifest said 1.86.0 — the
manifest is the contract).
The MCP wire surface is text-only JSON-RPC and pulls no
nightly-only deps. CI verifies the floor via the
Per-crate MSRV workflow job. See the workspace
POLICIES.md
for the bump policy.
§Panics
Public functions in this crate do not panic on well-formed
input. The MCP binary unwraps once on stdin acquisition
during boot — that’s deliberate, every caller invokes the
binary via a host process that controls the pipe.
§Errors
Tool calls return JSON-RPC error envelopes per the
MCP specification. The
error code taxonomy lives in
docs/tools-reference.md:
-32000 (file I/O), -32001 (parse), -32002 (path not
found), -32003 (set), -32602 (missing arg), -32601
(unknown method).
§Concurrency
Each MCP request is processed sequentially on the binary’s
stdio loop. The host (Claude Desktop, Cursor, Zed, …) is
responsible for not pipelining requests; if it does, the
tool execution is serialised by the loop’s BufRead reader.
§Platform support
Tier-1 (CI-verified each PR): aarch64-apple-darwin,
x86_64-unknown-linux-gnu, x86_64-pc-windows-msvc.
noyalib_set writes via an atomic file replacement
helper: write to a sibling temp file → sync_all →
rename. This is naturally atomic on POSIX; on Windows it
uses MoveFileExW(MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) semantics so concurrent readers
always see either the old or the new contents — never a
half-write or a stale-page-cache observation. This was the
fix for the historical Windows-only tool_call_set_preserves_comments
flake.
§Performance
Each tools/call round-trip goes through one
noyalib::cst::parse_document (O(n) over input bytes)
and, for noyalib_set, one Document::to_string emit
(O(n) over output bytes). JSON-RPC line framing is
amortised constant-time per message. Tool calls do not
cache the parsed CST between requests — every call is a
fresh parse so concurrent edits from outside the MCP server
are always observed. Typical tool-call latency on a 100 KB
YAML file: 1–3 ms parse + emit on commodity hardware.
§Security
#![forbid(unsafe_code)]. No FFI. No network I/O —
noyalib-mcp is stdio-only by design; remote hosting goes
through a separate broker (see examples/hosted-mcp-run.md).
The server has no auth layer; restrict the working
directory of the spawned process via container mounts /
systemd ReadWritePaths= for production deployments.
Resource-limit gates are inherited from noyalib’s
ParserConfig defaults. Full posture:
SECURITY.md.
§API stability and SemVer
Pre-1.0 (0.0.x): the MCP wire contract (tool names,
input-schema shapes, error code ranges, the
SUPPORTED_PROTOCOL_VERSIONS set) is stable within a
0.0.x line — bug fixes only.
Adding a new tool is allowed within a 0.0.x bump; removing
or renaming a tool, or repurposing an error code, is held
to a 0.x bump (e.g. 0.0.x → 0.1.0). The Rust library
surface (handle_message, dispatch, error_str,
Request, Response, ErrorResponse, HandleOutcome) is
covered by the workspace SemVer policy in
POLICIES.md.
cargo-semver-checks runs in CI on every PR.
§Documentation
- Engineering policies — workspace
POLICIES.md. - MCP specification: https://modelcontextprotocol.io.
- Tools reference (input schemas, error codes):
docs/tools-reference.md. - Host configurations (Claude Desktop, Cursor,
Continue.dev, Zed, hosted gateways):
examples/.
Modules§
- prompts
- Prompt registry for the MCP server.
- resources
- Resource registry for the MCP server.
- tools
- Tool registry for the MCP server.
Structs§
- Error
Object - JSON-RPC 2.0 error object.
- Error
Response - JSON-RPC 2.0 error envelope.
- Request
- JSON-RPC 2.0 request envelope. Method-specific parameters live
in
JsonValueto keep parsing flexible across the few methods the MCP spec asks of a server. - Response
- JSON-RPC 2.0 success response envelope.
Enums§
- Handle
Outcome - What the stdio loop should do with a parsed message — write a reply on stdout, or stay silent (notifications never receive a response).
Constants§
- LEGACY_
PROTOCOL_ VERSION - The newest handshake-based revision this server implements —
what
initializeanswers when the client’s requested version is not supported (per the 2025-06-18 negotiation rules, the server then responds with a version it does support). - META_
PROTOCOL_ VERSION_ KEY - The
_metakey a modern (2026-07-28+) client uses to declare the protocol revision of each request. - SUPPORTED_
PROTOCOL_ VERSIONS - Protocol revisions this server speaks, newest first. The server
is dual-era (MCP 2026-07-28 “Versioning and Compatibility”
terminology): a modern client declares its version per request in
_metaand may probe withserver/discover; a legacy client opens with aninitializehandshake and negotiatesLEGACY_PROTOCOL_VERSION. - UNSUPPORTED_
PROTOCOL_ VERSION UnsupportedProtocolVersionErrorcode (2026-07-28 error-code allocation:-32020..=-32099reserved for the MCP spec).
Functions§
- dispatch
- MCP method dispatcher. Returns the
resultpayload on success or a(code, message)pair for the error envelope. - error_
str - Render a JSON-RPC error envelope to a single line string.
- handle_
message - Process one newline-delimited JSON-RPC message. The stdio loop
in
maincalls this per line; tests call it with crafted strings.