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
| Tool | Maps to | Returns |
|---|---|---|
nci_query | nci query <subcommand> --format json | CLI envelope: |
nci_sql | nci 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 onesymbols.id.packages/package_versions/package_deps/source_packages/symbols— listings.
Resources
| URI | MIME | What it returns |
|---|---|---|
nci://primer/agent | text/markdown | Compact NCI-first workflow primer. Read first. |
nci://primer/reference | text/markdown | Tabular reference: schema columns, joins, edge cases. |
nci://database/active | application/json | Strictly 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 :
{ "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_versionwhenever both are known. The primer pushes this hard for a reason. - Prefer
evidenceover chainedfind+symbol+snippetcalls. It is the batched single-process path. - Use
nci_sqlonly when a structurednci_querysubcommand will not answer.