NCI
MCP Protocol

Two tools, three resources

The MCP server (nci-mcp) is a thin adapter on top of the CLI. It exposes exactly two tools and three resources. The agent does the deciding; the server only forwards calls to nci.

Tools

ToolMaps toReturns
nci_querynci query <subcommand> --format json

CLI envelope: {"ok":true,"data":…} on success, {"ok":false,…} on error.

nci_sqlnci sql --format json -c "…"Raw JSON array of row objects (no envelope). --max-rows applies here, not on nci_query.

nci_query is a discriminated union over subcommand:

  • evidence — exact-name + FTS hits + batched snippets in one call. Preferred first call.
  • active_package — resolve which installed version is live for a name.
  • find / symbol — narrower lookups for a single anchor.
  • show / snippet / overloads — drill in on one symbols.id.
  • packages / package_versions / package_deps / source_packages / symbols — listings.

Resources

URIMIMEWhat it returns
nci://primer/agenttext/markdownCompact NCI-first workflow primer. Read first.
nci://primer/referencetext/markdownTabular reference: schema columns, joins, edge cases.
nci://database/activeapplication/jsonStrictly read-only status snapshot from nci db status --format json.

The full primer text is rendered at Agent primer.

Wire it up

Drop this into ~/.cursor/mcp.json, or open CursorSettingsMCP:

{ "mcpServers": { "nci": { "command": "npx", "args": ["-y", "@nativecontextindex/mcp"] } } }

Cursor opens the server in the workspace it launched in; the server inherits NCI’s working-directory-aware config resolution (the same logic nci uses for nci.config.json). Full setup at Cursor setup.

A round-trip

The Model Context Protocol transport is JSON-RPC 2.0 over stdio (see the spec’s base protocol). nci-mcp is built on @modelcontextprotocol/sdk, which implements that framing — you do not hand-roll JSON-RPC in application code; clients send requests like:

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "nci_query", "arguments": { "subcommand": "evidence", "package_name": "zod", "package_version": "3.23.8", "symbols": ["ZodObject"] } } }

The MCP SDK wraps that stdout as a tool result (content[].text). Parsing it yields the same JSON object you would see from nci query --format json in the terminal — including { "ok": false, "error": "…" } on failures or { "ok": true, "data": … } on success (for evidence, data.symbols / data.snippets as usual).

Best-practice prompts

  • Pin package_name + package_version whenever both are known. The primer pushes this hard for a reason.
  • Prefer evidence over chained find + symbol + snippet calls. It is the batched single-process path.
  • Use nci_sql only when a structured nci_query subcommand will not answer.