Use Kiri via MCP from your IDE
Kirimana ships a Model Context Protocol server that exposes your catalog — contracts, classifications, lineage, PII metadata, AI policy — to any MCP-capable assistant. One Kirimana install, many frontends: Claude Code, Claude.ai’s desktop app, Cursor, Continue, and Cline all speak MCP and read from the same server.
Three properties define how it behaves, and they’re the reason it’s safe to point an agent at your catalog:
- Read-only. The server exposes resources and tools that describe
catalog state. Every mutation —
kiri apply, contract edits — lives on the CLI, never on MCP. An assistant that goes off the rails can’t rewrite a contract. - Identity flows through the environment. The stdio transport doesn’t carry auth headers, so the host process supplies the caller’s identity via env vars, and RBAC is enforced per request.
- Every read and tool-call is audit-logged. One JSONL entry per invocation, so you can always answer “which identity read which contract, when” — the same forensic record the CLI produces.
Install the server
The kiri-mcp binary comes with the Kirimana workspace:
uv sync --all-packages
which kiri-mcp
You won’t run it by hand in normal use; the assistant launches it over stdio. To smoke-test it against a project:
KIRIMANA_PROJECT_DIR=examples/hello-dynamics uv run kiri-mcp
It reads MCP messages on stdin and writes responses on stdout — Ctrl-C to stop.
Wire it into your assistant
Every MCP client uses the same shape of configuration. Add a kirimana
server entry that runs kiri-mcp with the project directory and caller
identity in env.
Claude Code, Cursor, Continue, Cline read a per-project .mcp.json
(Cursor and the generic clients use the same schema; Continue and Cline
read their own config files with the same server block):
{
"mcpServers": {
"kirimana": {
"command": "uv",
"args": ["run", "kiri-mcp"],
"cwd": "/absolute/path/to/your/kirimana/repo",
"env": {
"KIRIMANA_PROJECT_DIR": "examples/hello-dynamics",
"KIRIMANA_MCP_SUBJECT": "alice@acme.com",
"KIRIMANA_MCP_GROUPS": "acme/platform-team"
}
}
}
}
Claude.ai desktop reads
~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or
%APPDATA%\Claude\claude_desktop_config.json (Windows) — same mcpServers
block. Restart the app; the Kirimana resources appear in the attachment
menu and the tools are callable from chat.
For Claude Code, confirm it connected:
claude mcp list
If the GUI clients can’t launch the server, uv is usually not on the app’s
PATH — use an absolute path to uv (which uv) as the command.
What the server exposes
Resources (read-only, URI-addressable)
| URI | What it returns |
|---|---|
catalog://assets | Compact list of every declared asset |
catalog://asset/{urn} | Full detail for one asset — governance, columns, PII |
catalog://lineage/{urn} | Immediate upstream + downstream edges |
catalog://pii/scan | Every asset with PII, plus its PII columns |
catalog://glossary | Business glossary terms |
kirimana://contract/{name} | Full ODCS contract for a declared name |
kirimana://classification/{fq_name} | Classification for a contract or column |
kirimana://ai-policy/{name} | The kiri.ai_policy block for a contract |
kirimana://kpi/{name} | Exec-facing KPI record — owner, lineage, SLA |
Tools (parameterised callables)
| Tool | Purpose |
|---|---|
search_assets(query, limit) | Case-insensitive substring search across name / qualified name / description |
list_assets_by_domain(domain, classification) | Domain-scoped listings, optionally filtered by classification |
list_pii_columns() | Every PII column across the catalog — for GDPR / compliance audits |
get_asset(urn) | Fetch one asset by URN |
list_asset_types() | The set of asset types present in the catalog |
kirimana_check_policy(contract, caller, model) | Pre-flight AI-policy check — yes/no before an LLM call on this data |
On top of these, the server registers a set of read-only CLI commands as tools — contract, lineage, project, and compliance lookups — so an agent can run the same read queries you’d run at the terminal, without leaving the IDE.
Identity and RBAC
The server resolves identity from the environment at each call:
| Env var | Purpose |
|---|---|
KIRIMANA_MCP_SUBJECT | The subject claim recorded in audit and passed to RBAC (email / OIDC sub) |
KIRIMANA_MCP_GROUPS | Comma-separated groups, mapped to roles via kiri_rbac.yml |
KIRIMANA_PROJECT_DIR | Project root — where kiri.yml and kiri_rbac.yml live |
Behaviour when the subject is unset:
- No subject, no
kiri_rbac.yml— single-user degrade path: calls are allowed and audit records the subject asanonymous, so a forensic answer still exists. - No subject, populated
kiri_rbac.yml— safe-default DENY on every call. An unclaimed identity can’t read; an external assistant gets the calling user’s rights, never elevated ones.
Always set both KIRIMANA_MCP_SUBJECT and KIRIMANA_MCP_GROUPS in real
use, scoped to the minimum role the user needs. The host process is the
trust boundary — the transport can’t verify the claim — so treat the config
file’s env block as a credential.
Audit parity with the CLI
Every resource read and tool call appends one row to the same audit stream
the CLI writes, under <project>/.kiri/audit/, in the same JSONL format,
each entry carrying a trace id. That means an MCP read and a CLI read are
forensically indistinguishable in the record — you correlate an IDE agent’s
activity with terminal activity through the same trace id, in the same log,
with the same tooling. Response bodies are never stored (only their size),
so the audit log can’t become a shadow copy of what the assistant read.
Override the path for read-only project dirs:
export KIRIMANA_MCP_AUDIT_PATH=/var/log/kirimana/mcp.jsonl
Try it
From any connected assistant:
- “List every PII column under the sales domain.” — the agent calls
list_assets_by_domain('sales')andlist_pii_columnsand composes the answer. - “Show me the upstream lineage for
gold.dim_customer.” — it attachescatalog://lineage/…and cites the edges. - “Explain the classification on
silver_account.email.” — it fetcheskirimana://classification/silver_account.emailand renders the decision and which contract it inherited from.
Every one of those calls lands in the audit log, under the identity you configured, next to whatever the same person did at the CLI.