# rosetta-mcp-server

Model Context Protocol gateway for the
rosetta-app-server
agent-substrate. A stdio JSON-RPC binary that exposes the
rosetta-app-server `/api/v1/*` REST surface as model-callable MCP
tools, plus a small set of task-shaped composites.

The gateway is an **HTTPS client** — it talks to a running
rosetta-app-server (default `https://api.rosetta-design.com`) over the
public REST API. It does not run locally with its own DB connections;
operators don't need Neo4j or MySQL on their laptops.

Authority: split from `rosetta-app-server` per
`docs/decision-traces/dt-20260507-mcp-server-bootstrap.md`
and the cross-repo supersede DT
(`rosetta-app-server/docs/decision-traces/dt-20260507-mcp-frontend-substrate-supersede.md`).

## Tool catalog

| Composite | What it does |
|-----------|--------------|
| `rosetta_turn` | One conversational turn end-to-end (idempotent create + persist + flow decide) |
| `rosetta_record` | DecisionTrace + optional ADR application + optional QueryTrace |
| `rosetta_query` | Context retrieval with `expand=full` (inlined pattern relationships) |
| `rosetta_engagement_turn` | Engagement-scoped conversational turn — binds the session to an engagement and projects the turn's semantics into the engagement twin |
| `rosetta_engagement_canvas_slack` | Engagement canvas rendered as publish-ready Slack-canvas markdown in one call (`format=slack`) |

Plus thirty-seven 1:1 REST wrappers — see the `rosetta-agent` plugin's
`agent-orchestration/SKILL.md`
for the full catalog and worked-example flows.

**Deliberately absent: twin ratification.** The app-server's human
ratification lane (`twin:ratify` / `twin:reject`, the `twin-ratification`
OpenAPI tag) is structurally excluded from the MCP tool surface per
DT-RX-022 Q-D-1 (rosetta-meta, RATIFIED 2026-07-02). Ratification is the
human gate on agent-authored/simulated twin content — the one verb whose
absence from the agent surface is a feature: exposing it (even behind
confirm-before write-safety) would let an agent satisfy its own review
gate. The tag is pre-classified in `config/mcp/tool-policy.yaml`'s
`denied_tags`, so future `make sync-openapi` runs mint no ratify/reject
tools regardless of spec version (the `ensureAccountForUser` precedent).
Humans ratify via the rosetta-enablement-agent console, whose BFF calls
the REST endpoints under an authenticated named session.

## Install

The binary is self-contained — the OpenAPI spec, composites catalog,
and JSON Schema are baked in via `go:embed`. Download the archive
for your platform from
GitHub Releases,
extract, and put `mcp-server` (or `mcp-server.exe`) on `$PATH`.

**See [INSTALL.md](INSTALL.md)** for full per-platform walkthroughs
(Linux, macOS, Windows), Gatekeeper notes, PATH setup, registration
on Claude Code / Claude Desktop / Claude Cowork (claude.ai web is
not supported — local MCP requires a desktop or CLI surface),
checksum verification, and troubleshooting.

> **Before you install:** generate your bearer token at
> [https://rosetta-design.com](https://rosetta-design.com) →
> Settings → API Keys. The binary refuses to start without one.

### tl;dr (Linux / macOS)

The release version (`0.16.0`) and its embedded API-contract version
(`api 1.46.0`, shown by `mcp-server --version`) are different numbers. The
latest published download is `v0.16.0`; the archive filename uses that
**published release** version:

```bash
TAG=v0.16.0     # release tag
REL=${TAG#v}    # release version → archive filename (mcp-server-${REL}-...)
OS=$(uname -s | tr '[:upper:]' '[:lower:]')               # linux or darwin
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') # amd64 or arm64
curl -L "https://github.com/vernonkeenan/rosetta-mcp-server/releases/download/${TAG}/mcp-server-${REL}-${OS}-${ARCH}.tar.gz" | tar xz
sudo install -m 0755 "mcp-server-${REL}-${OS}-${ARCH}/mcp-server" /usr/local/bin/mcp-server
export ROSETTA_AGENT_TOKEN="rsk_..."   # from rosetta-design.com → Settings → API Keys
cp "mcp-server-${REL}-${OS}-${ARCH}/.mcp.json" /path/to/your/project/
```

> **Mac users:** any Mac with an "M" series chip is `arm64`
> (Apple Silicon). Pre-2020 Intel Macs are `amd64`. The `amd64`
> name refers to the 64-bit x86 instruction set, not specifically
> AMD-brand CPUs.

(macOS only — clear Gatekeeper quarantine before installing:
`xattr -d com.apple.quarantine mcp-server 2>/dev/null || true`. The
guard makes it a no-op for `curl` downloads, which carry no quarantine
flag and would otherwise exit 1.)

### Build from source

```bash
git clone https://github.com/vernonkeenan/rosetta-mcp-server.git
cd rosetta-mcp-server
make build       # produces ./bin/mcp-server
make test        # unit tests (no network)
make test-live   # E2E tests against api.rosetta-design.com (requires ROSETTA_API_KEY)
```

### Smoke test

```bash
ROSETTA_API_KEY="rsk_..." mcp-server <<'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0.0.1"}}}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
EOF
```

Or install the
`rosetta-agent` plugin
for the richer registration that includes a `SKILL.md` teaching the
model when to call which tool.

### Container image

For the network deployment behind `mcp.rosetta-design.com` (Claude.ai
custom connectors), the same binary ships as a multi-arch container
image published to an internal container registry (image tag matches
the GitHub tag without the `v` prefix). Compose pulls the image and
runs it with `--transport=http --http-addr=0.0.0.0:8090` per
`docs/decision-traces/dt-20260527-remote-mcp-transport.md`.
The per-laptop archive flow is unchanged.

## Environment

| Variable | Required | Default | Purpose |
|----------|----------|---------|---------|
| `ROSETTA_API_KEY` | **yes** | — | Bearer token for the agent-substrate. Sent in the `Authorization: Bearer …` header on every tool call. |
| `ROSETTA_API_BASE` | no | `https://api.rosetta-design.com` | Base URL of the rosetta-app-server REST API. |
| `ROSETTA_OPENAPI_PATH` | no | (embedded) | **Override.** When set, loads the OpenAPI spec from this path instead of the embedded copy. Useful for testing against a different REST contract. |
| `ROSETTA_MCP_COMPOSITES_DIR` | no | (embedded) | **Override.** When set, loads `composites.yaml` + `schema/composites.schema.json` from this directory instead of the embedded copies. Useful for editing composites without rebuilding the binary. |

## OpenAPI spec coupling

This repo carries a **vendored snapshot** of rosetta-app-server's
OpenAPI spec at `api/vendored/rosetta-v1.yaml`.
The canonical copy is the source of truth; the build pipeline copies
it into `internal/embedded/` where `go:embed`
bakes it into the binary. End users get a self-contained executable
with no runtime data dependency.

Two sync targets:

```bash
make sync-openapi    # refresh api/vendored/ from a local rosetta-app-server checkout
make sync-embedded   # refresh internal/embedded/ from api/vendored/ + config/mcp/
```

`make build` runs `sync-embedded` automatically. CI's `embedded-sync`
job fails if the embedded copies drift from the canonical files —
when you edit a canonical file, run `make sync-embedded` and commit
both.

The pin (upstream commit hash + version) is recorded at the top of
`api/vendored/rosetta-v1.yaml`. Bumps are operator-driven — there's
no automatic update.

Authority: `docs/decision-traces/dt-20260507-openapi-consumption.md`.

## Plugin

The Claude Code plugin that registers this binary as an MCP server —
`rosetta-agent` — lives in
`rosetta-platform`;
the local `util/plugins/rosetta-agent/`
directory is a redirect stub kept for history. See the plugin's
README at its home for installation.

## Constitutional invariants

This repo is bound by a small subset of `rosetta-app-server`'s
constitutional invariants — only the ones that apply to a
client-side gateway:

- **C-2 analog:** No streaming MCP transport. stdio only for v1.
- **C-10 analog:** No LLM generation in this binary. The dispatcher
  routes; it does not generate.

Other invariants from the source repo (Cypher-as-files, five-field
identity, classifier-as-config) don't apply here — there's no graph,
no five-field identity, no classifier in this binary.

## Versioning

Binary version follows the rosetta-app-server `info.version` it
targets. v0.1.0 is the initial release post-split.

## License

Proprietary — © 2026 Keenan Vision LLC. See `LICENSE`.
