Skip to content

MCP adapter

vivary-mcp is an optional, read-only bridge from local MCP clients to Vivary’s bounded public context producers. It is not part of the baseline install, does not change the graph, and does not add MCP dependencies to vivary-core.

Read-only is the adapter’s authority ceiling, not a claim that Vivary cannot maintain its workspace. Vivary Core and its CLI workflow can create governed records when an operation has evidence binding and explicit human approval; MCP never grants that approval or silently escalates into a write tool.

vivary-mcp 0.1.3 is published on PyPI. It stays optional and off by default. No Vivary install starts it for you.

The adapter pins:

  • MCP protocol 2026-07-28
  • official Python SDK mcp==2.0.0 and mcp-types==2.0.0
  • local standard input/output transport only
  • SDK-owned discovery through server/discover
  • exactly four tools and no extensions

Tests cover the SDK-owned discovery, metadata, cancellation, schema-validation, and server-identity paths. Vivary has not passed the pinned external conformance harness. Doctor therefore reports conformance_status: unproven.

Install the optional package explicitly from the public index:

Terminal window
python -m pip install vivary-mcp

That resolution pulls vivary-core and vivary-tropo from their declared floors and installs the exact reviewed MCP SDK dependency. The normal vivary and create-vivary installs do not include or start the adapter.

To test a local change instead, install the three distributions together from a checkout so pip does not mix source and registry versions:

Terminal window
python -m pip install ./packages/core ./packages/tropo ./packages/mcp

Bind each public alias to one canonical workspace root at process startup:

Terminal window
vivary-mcp --workspace docs /absolute/path/to/workspace

Repeat --workspace ALIAS PATH to expose more than one root. An alias may use letters, numbers, ., _, or -. It must begin with a letter or number and contain at most 64 characters. Startup normalizes each root and requires distinct canonical directories. It retains an operating-system identity anchor for each root until the server stops. Ordinary writes inside that directory remain valid, but replacing the root path makes subsequent calls refuse with workspace_unavailable. Tool calls cannot supply or change aliases or roots.

For a generated thin-v0.3 workspace, the public producer reads .vivary/workspace.toml as its type policy. Before git init, Core accepts only the exact bounded .gitignore block generated by create-vivary; missing, changed, extended, linked, or arbitrary non-Git policy refuses the request. After the workspace becomes an exact Git worktree, the existing hardened Git ignore policy is authoritative. A root tropo.toml may compose with the thin base only when its policy is privacy-admitted and tighten-only. Invalid, unreadable, linked, or loosening overlays fail closed; the producer never silently ignores an overlay.

The process speaks newline-delimited MCP JSON-RPC on standard input and standard output. It reserves standard output for protocol messages. Standard error carries bounded, sanitary diagnostics:

Terminal window
vivary-mcp \
--workspace docs /absolute/path/to/workspace \
--observability errors

--observability accepts:

  • off: no diagnostics
  • errors: refusal, cancellation, and timeout diagnostics
  • json: all bounded lifecycle diagnostics

Diagnostics exclude workspace aliases and roots, queries, filters, snippets, and paths. They also exclude identifiers, arguments, environment values, client identity, claims, evidence, exceptions, and stack traces. The adapter writes no telemetry, log file, socket, or network request.

All schemas are closed JSON Schema Draft 2020-12 objects. Unknown fields and values outside the published limits are invalid arguments.

Tool Required input Optional input Result
vivary_find workspace, question limit, budget Bounded context selected for a task or question.
vivary_query workspace, text limit, type_filters, path_filters, edge_filters, snippet_chars, explain Bounded filtered typed-graph matches.
vivary_check workspace paths, strict Bounded validation findings without repairs.
vivary_capsule workspace, question max_claims Privacy-projected public Task Capsule without raw evidence or check execution.

Every call returns a vivary.mcp-tool-result/v0 envelope with known, unknown, or refused status. Every envelope names a workspace only by its configured alias. The adapter returns exact results whole or refuses them. It does not silently truncate an oversized result.

The adapter’s public ceilings are part of its contract, not tuning guidance:

Boundary Limit
Operator-bound workspaces per process 16
Workspace alias 1–64 characters
One newline-delimited input frame 65,536 bytes
Question or query text 4,096 characters
Returned matches (limit) 1–20
vivary_find budget 64–4,000; default 1,200
Each query filter list 16 unique values; type 128, path 512, and edge 256 characters per value
Query snippet 0–1,000 characters; default 160
vivary_check paths 200 unique workspace-relative paths, 512 characters each
vivary_capsule claims 0–24; default 24
Active producer work 1 call, 30-second timeout, 5-second cancellation grace
Complete JSON-escaped tool response 1 MiB
One standard-error diagnostic 4,096 bytes

An over-limit argument is invalid. Work, privacy, or response overflow returns a typed unknown/refusal envelope; the adapter never turns a prefix into a complete answer. A producer that ignores cancellation keeps the sole slot quarantined until its worker exits, so later calls receive server_busy instead of overlapping it. Downstream Tropo/Core ceilings still apply, and the tighter limit wins. The constants and schema live in the adapter source; limit, timeout, and quarantine regressions provide the behavior evidence.

The adapter can:

  • inspect only operator-bound local roots
  • invoke fixed, bounded internal Git reads used by the public Tropo/Core contracts
  • read candidate bytes only after Core’s privacy policy admits their paths
  • return bounded public projections

It cannot:

  • write, repair, promote memory, execute checks, or persist state
  • accept a root, executable, shell command, process, endpoint, or transport from a tool caller
  • fetch, index, publish, deploy, approve a gate, or call a provider
  • return ignored or sensitive names, raw evidence, commands, absolute machine paths, credentials, or private content

vivary_capsule returns a complete bounded public capsule object that can bind a later proposal. It does not return write authority. Save that result object, prepare a typed Markdown source, preview create-vivary record --capsule <path>, inspect its capsule-bound plan, and apply only the exact human-approved hash. The CLI verifies the capsule’s canonical integrity and current workspace fingerprint before it can plan. The transaction writes one create or update, reruns Doctor, and rolls back on failed verification. It has no batch or pack mode. See the command contract.

This separation preserves the normal agent loop: retrieve and propose through bounded context interfaces, then cross a deliberate write gate through the workspace owner. MCP startup and all four MCP calls remain non-materializing.

Cancellation and timeouts reach the active producer and its fixed Git process scope. Only one producer runs at a time. Concurrent calls refuse instead of creating unbounded work.

create-vivary doctor --json always includes the optional interop:mcp capability. Doctor reads installed distribution metadata and entry-point declarations only. It does not import the adapter, start a process, connect to a server, or use the network.

The capability is not-installed by default. Compatibility requires the active interpreter to see the vivary-mcp entry point and exact declared mcp==2.0.0 dependency. Doctor reports a different SDK version as incompatible rather than accepting it speculatively.

Run the source regressions with the reviewed SDK installed:

Terminal window
python -m pytest packages/mcp/tests/ -q

These tests prove the repository adapter behavior against the pinned SDK. They do not establish external harness conformance or compatibility with a named MCP client. The official-SDK suite also scaffolds a real five-file greenfield workspace, starts the stdio server, discovers and calls the four tools, proves the read phase made no files, then applies one separately approved capsule-bound record and queries it through the same MCP session. It asserts that no template, module pack, or extra record appears.