Contents
- Install — Cargo, npx, Docker
- Quick Start — JSON-RPC handshake
- Why this approach? — design rationale
- Connect — per-client configuration
- Tools exposed — MCP tool reference
- Examples — runnable scripts
- Verification — cosign + npm provenance
- When not to use noyalib-mcp
- Documentation
- License
Install
For environments without a Rust toolchain (the typical AI-agent deployment shape):
# npm wrapper — auto-downloads the matching binary on first run,
# caches under ~/.cache/noyalib-mcp/<version>/.
# Container — multi-arch (linux/amd64, linux/arm64).
Both consume the same signed binary attached to every GitHub Release. See Verification for the verify commands.
Quick Start
The server speaks JSON-RPC 2.0 over stdio with newline-delimited
frames, per the
MCP specification. A typical
agent launches the binary as a child process, sends
initialize, then dispatches tool calls:
Why this approach?
AI agents that edit YAML configuration today regex-replace and corrupt comments, indentation, and document structure. The same agent fixing a port number in a Kubernetes manifest can shift every comment by a line, reorder sibling keys, or strip trailing whitespace that a downstream linter cared about.
noyalib's CST does the edits losslessly — a set("server.port", "9090") rewrites only the byte span of the 8080 scalar; the
surrounding comments and indentation pass through untouched.
This server is the protocol shim that lets MCP-aware clients
drive that engine safely:
- Lossless mutation.
tools/call setreturns a document byte-identical to the input outside the touched span. - Surgical reads.
tools/call getwalks the dotted path and returns just the value, not the whole tree. - Schema validation.
tools/call validate --schemaruns the same JSON Schema 2020-12 enginenoyavalidateships. - Stdio transport. Standard MCP. Works with every spec-compliant client.
Connect
Claude Desktop / Claude Code
Cursor
~/.cursor/mcp.json:
Zed
~/.config/zed/settings.json:
Continue.dev
~/.continue/config.json:
Any other MCP-aware client
Point at the binary; the transport is stdio with newline- delimited JSON-RPC 2.0.
Tools exposed
The v0.0.1 server registers two file-oriented tools — both
operate on a YAML file at file: <path>, not on inline source
strings, so an agent's edits land on disk losslessly:
| Tool | Arguments | Returns |
|---|---|---|
noyalib_get |
{ file: string, path: string } |
The raw source fragment at the dotted/indexed path (e.g. server.host, items[0].name). No re-quoting; no canonicalisation. |
noyalib_set |
{ file: string, path: string, value: string } |
The file rewritten via the lossless CST so only the touched span changes; comments, blank lines, and sibling formatting survive byte-for-byte. The value is a YAML fragment (0.0.2, "hello", [1, 2, 3]); a parse failure leaves the file unchanged. |
Each tool's full input schema lives in the response to
tools/list. The server also handles the standard
initialize / initialized / notifications/cancelled
lifecycle.
Format / parse / validate are not exposed as MCP tools today —
they're available via the noya-cli
binaries (noyafmt, noyavalidate) and the
noyalib library API. Promotion to
first-class MCP tools is on the v0.0.2+ roadmap.
Examples
Agent-driving demos under
crates/noyalib-mcp/examples/:
| Script | What it shows |
|---|---|
handshake.sh |
initialize → tools/list smoke test. Confirms the binary speaks the protocol and announces the expected tools. |
format-call.sh |
tools/call format on a poorly-spaced document. Demonstrates that comments + indentation pass through the CST formatter unchanged. |
set-then-get.sh |
Round-trip the mutation surface: set rewrites server.port, get reads it back. Surgical edit; surrounding bytes untouched. |
|
POSIX-shell only — no jq, no node dependencies. Pipe
through jq -c . if you want pretty-printed JSON responses.
Verification
The npm wrapper and the GHCR image both consume the signed binary attached to every GitHub Release. To verify the underlying binary before trusting it:
COSIGN_EXPERIMENTAL=1
The npm wrapper additionally carries an npm provenance attestation:
Full cookbook: pkg/VERIFY.md.
When not to use noyalib-mcp
- You don't trust your AI agent with filesystem access at all. noyalib-mcp doesn't read or write files itself — every operation takes the YAML document as a string argument and returns the result as a string. The agent decides what to do with the result. If the agent has filesystem access, it can persist the response wherever it wants.
- You need a sandboxed schema registry. noyalib-mcp accepts
schemas as inline strings in
tools/call validate; it does not fetch schemas from URLs. If your workflow needs network-resolved schemas, the agent is responsible for fetching the schema first and passing the bytes.
Compatibility
MSRV: Rust 1.75.0 stable — same floor as the core
noyalib library. The MCP wire surface is text-only JSON-RPC
and pulls no nightly-only deps. CI verifies the floor on every
PR via the Per-crate MSRV workflow job. The bump policy
lives in
doc/POLICIES.md.
Tier-1 platforms (CI-verified each PR): aarch64-apple-darwin,
x86_64-unknown-linux-gnu, x86_64-pc-windows-msvc. The
binary writes via atomic file replacement on every platform —
on Windows via MoveFileExW(MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) semantics.
Documentation
- Engineering policies (MSRV, SemVer, security, performance, concurrency, platform support, feature flags):
doc/POLICIES.md - Security policy:
SECURITY.md - API reference: https://docs.rs/noyalib-mcp
- Tools reference (input schemas + error codes):
doc/tools-reference.md - Agent integration (Claude Desktop, Cursor, Continue.dev):
doc/agent-integration.md - MCP specification: https://modelcontextprotocol.io
- Workspace README: https://github.com/sebastienrousseau/noyalib#readme
License
Dual-licensed under Apache 2.0 or MIT, at your option.