Skip to main content
Glama
CumulativeWebInc

cwi-mcp-server

Official
README.md
# cwi-mcp-server

CWI's **read-only** MCP (Model Context Protocol) server. Nine tools, zero
dependencies, stdio transport — connect it to any MCP client (Claude Desktop,
Claude Code, Cursor, or another agent) and read CWI's trust infrastructure
from your own runtime.

**What you get:**

- **Gear Ledger reads** (5 tools) — the live, public provenance log of the
  CWI agent company: version, full state, agents + presence, task summaries,
  single-task detail.
- **`trust_verdict`** — score agent trust with the CWI Verdict Engine v1.0.0
  (deterministic, evidence-bound; it returns `insufficient-data` instead of
  inventing a score).
- **`needledrop_verify`** — verify the hash-chain integrity of any
  NEEDLE DROP placement ledger (`cwi-needledrop/v1`).
- **`errorbar_stamp`** — stamp any claim with a reproducible confidence
  interval + provenance check (The Error Bar v1.0.0; deterministic given the
  seed — fake precision dies on contact).
- **`errorbar_verify`** — re-run an Error Bar stamp and check
  byte-equivalence. A stamp that cannot be re-run is void.

**Read-only means read-only.** No write tools, no signing, no presence
heartbeats, no task creation, no state mutation. The server holds no secrets:
no tokens, passwords, or keys in code, config, or logs.

Don't trust us — see [VERIFY.md](VERIFY.md) for how to check every claim
yourself, cold, in under five minutes.

## Install (copy-paste)

Requirements: **Node ≥ 18** and **python3** on your PATH. Nothing to install —
there are zero dependencies.

```bash
git clone https://github.com/CumulativeWebInc/cwi-mcp-server.git
cd cwi-mcp-server
node test.js     # expect: 28/28 tests passed
```

That's it. `server.js` is the server.

## Connect your MCP client

**Claude Desktop** (`claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "cwi": {
      "command": "node",
      "args": ["/absolute/path/to/cwi-mcp-server/server.js"]
    }
  }
}
```

**Claude Code / any stdio MCP client:** same shape — command `node`, one
argument: the absolute path to `server.js`. Transport is stdio: one JSON-RPC
object per line on stdin, responses on stdout.

## The 7 tools

| # | Tool | Arguments | Returns |
|---|---|---|---|
| 1 | `ledger_state_version` | none | `{version, updated_at, sha, tasks, agents}` |
| 2 | `ledger_state_get` | `fields` (optional string[]) | Full ledger state, or selected top-level keys |
| 3 | `ledger_agents` | none | Every registered agent + latest presence heartbeat |
| 4 | `ledger_tasks` | `state` (optional enum) | Task summaries; filter by lifecycle state |
| 5 | `ledger_task_get` | `task_id` (required) | Full task detail incl. state history and artifacts |
| 6 | `trust_verdict` | `input` (required object) | Trust score or honest `insufficient-data` |
| 7 | `needledrop_verify` | `file` (optional path) | `{file, ok, messages}` chain-integrity verdict |

### Example — read the ledger version

```jsonc
// tools/call {"name": "ledger_state_version", "arguments": {}}
{
  "version": 1541,
  "updated_at": "2026-09-17T11:23:35Z",
  "sha": "3b2b46c8b8e14e0a3351e8896c6bd75e53391cde",
  "tasks": 38,
  "agents": 11
}
```

### Example — score trust (or get an honest refusal)

```jsonc
// tools/call {"name": "trust_verdict", "arguments": {"input": {
  "engine_version": "1.0.0",
  "subject": {"agent_id": "some_agent"},
  "context": "agent-trust",
  "observed_at": "2026-09-17T12:00:00Z",
  "signals": {"erc8004": [], "needle_drop": [], "first_spin": []}
}}}
{
  "status": "insufficient-data",
  "score": null,
  "missing": ["at least 3 verified signals across 2 families"],
  "input_sha256": "9f2c…"
}
```

Empty evidence → `insufficient-data`, never a made-up number. That's the
engine's whole point. Feed it real, citable evidence and you get a real
score; the output carries `input_sha256` so anyone can reproduce it
byte-for-byte.

### Example — verify a NEEDLE DROP ledger

```jsonc
// tools/call {"name": "needledrop_verify", "arguments": {}}
{
  "file": "vendor/needledrop/example-ledger.json",
  "ok": true,
  "messages": ["chain intact"]
}
```

Point `file` at any absolute path to a `cwi-needledrop/v1` ledger to verify
that one instead. Tampered entries fail — try it: copy the example ledger,
edit one byte, watch `ok` flip to `false` with the entry named.

## How the ledger reads work on your machine

On CWI's infrastructure the tools read through the canonical ledger CLI. On
yours, they read the **same bytes** from CWI's **public**
[`gear-ledger`](https://github.com/CumulativeWebInc/gear-ledger) repo — no
auth, no setup. (`trust_verdict` and `needledrop_verify` are fully local and
never touch the network at all.)

## Files

- `server.js` — the server (7 tools, stdio, zero deps)
- `test.js` — full protocol + tool harness (`node test.js` → 28/28)
- `VERIFY.md` — the zero-trust verification guide: check everything yourself
- `EQUIPS.md` — public, receipt-only log of external equips
- `agent-card.json` — machine-readable card for agent discovery
- `vendor/cwi-verdict-engine-v1.0.0/` — the vendored verdict engine
  (byte-identical copy; see `vendor/cwi-verdict-engine-v1.0.0/SOURCE.md`)
- `vendor/needledrop/` — `ledger.py` + schema + a 2-entry example ledger
  (entries sealed by the real `ledger.py`, clearly labeled as examples)
- `examples/` — real verdict output from a 2026-09-17 run

## Result, measurement, kill rule

- **Result this must produce:** an external agent calls a tool with their
  identity attached. Receipts go in [EQUIPS.md](EQUIPS.md).
- **Measured by:** real tool calls with checkable receipts.
- **Kill rule:** 0 external calls by 2026-10-01 → the MCP server is retired
  as an adoption surface (kept for internal use) and the lesson is logged.

## License

MIT — see [LICENSE](LICENSE).

TDQS

A4.1/5.0

Scored across 7 tools

Disambiguation4/5

Each tool has a distinct purpose: ledger_state_get returns the full state document, ledger_agents and ledger_tasks are specialized views, ledger_task_get is a detail lookup, and trust_verdict/needledrop_verify cover different verification domains. The only mild ambiguity is that ledger_state_get can also reach agents/tasks via its fields argument, but descriptions make the specialized tools clearly preferable for those cases.

Naming Consistency3/5

The ledger tools share a useful `ledger_` prefix and snake_case, but verb placement is inconsistent: some names end with `_get` (ledger_state_get, ledger_task_get), others are bare nouns (ledger_agents, ledger_tasks), one is a noun phrase (ledger_state_version), and the non-ledger tools use different forms (trust_verdict, needledrop_verify). The convention is readable but not predictable enough to infer tool names without reading descriptions.

Tool Count5/5

Seven tools is a well-scoped set for this server. It provides the core read-only ledger views, a task detail endpoint, the state version, plus two specialized verification/scoring tools without unnecessary redundancy.

Completeness4/5

The read-only ledger surface covers the main entities: full state, agents with presence, task summaries, and task detail, plus a version endpoint. The main gap is that handoffs and approvals are only reachable through ledger_state_get rather than dedicated tools, but agents can work around that by requesting the full state or selecting fields.

Maintenance

ActivityMaintained
ResponsivenessNo issues