The endpoint
The server speaks Streamable HTTP at/mcp on the address of your space:
The Python SDK exposes the address as
niadra.mcp_url.
Why the customer is bound by a token
The MCP tools never take a customer as an argument. The customer comes from thesubject_token of the connection: a token signed by the cell that carries the space, the source, the customer handle, the conversation and the verification level, and lives up to 15 minutes. The handle travels sealed inside it. A prompt injection that says “now look up customer X” has no argument to put X in: the model picks what to ask, never whom it is about.
When the customer acts for a company, pass about with the handle of that account or partner. The organization is bound the same way as the customer: the tools use it and the model cannot change it, and every read still checks that the link between the two is active. The token lives 15 minutes; mint a new one when the conversation outlasts it.
Steps
1. Mint a subject token in your backend
Callsubject_token() when the conversation starts, with the level the conversation proved. Mint it on the server side, never in a browser or in the model context.
unauthenticated; mint another one.
2. Connect the MCP client
Use any MCP client that supports Streamable HTTP and custom headers. With the official MCP SDKs:3. Know the eight tools
Eight tools, not sixty. Each description tells the model when to use the tool, when not to, and which tool complements it. A customer-facing source (audiencecustomer_agent) gets seven: resolve_identity is not offered to it.
The server also exposes the resource
niadra://context, the pack of the customer in the token, and one prompt, customer_context, with the pack ready for your model.
With agent memory on in the space, two more tools join: search_agent_memory (read, for keys with the agent_memory or context scope) and remember (write, only for keys with agent_memory:write). They belong to the agent, not the customer, so they need no subject token: a connection without a token lists and calls these two alone, and the eight customer tools answer unauthenticated. A note with personal data goes back to the model as the error personal_data_in_agent_memory, so it rewrites the note without the data.
With the subject signals on in the space, a key with the context scope gets get_constraints: the bound customer’s constraints block, as POST /v1/constraints answers it, with what they asked for and refused in lines for the model. With tool, the name of the tool the model is about to call, the block comes rendered through the binding the space’s tool-bindings document gives that tool for your source: the arguments that carry the constraints and what the tool cannot express. A tool the space does not bind comes back as the error invalid_input, which the model reads. for asks for a beneficiary’s block or a gift’s.
4. Let the pack guide the history tools
The pack already carries the “History” line (the older conversation the current reason repeats, with its resolution) and the open promises, and the count of conversations about the matter arrives as a slot when the turn asks for it. That answers the most common question on its own and tells the model when a search is worth it, which cuts useless calls. The tool definitions are stable text, so they stay in the cached prompt prefix: after the first turn they cost the cache price. Every read made through a tool is filtered by the same policy and verification level as the pack, and leaves a receipt: who read, the items returned, by id, and how many were withheld. There is still no tool that deletes: erasure stays with people and admin keys, atPOST /v1/forget.
Function calling without MCP
If your model API has function calling but you do not run an MCP client, use the same three history tools as plain function definitions. The SDK binds the customer in your code:kit.definitions is the { type: "function", function: {...} } shape most model APIs accept; in Python, kit.anthropic_definitions() returns the Anthropic Messages shape. The definitions are also served at GET /v1/history/tools for any other runtime, including models you host yourself.
Questions about all customers
This server answers about one customer at a time. For an analysis LLM that asks about the whole base (“which promises are overdue this week?”), Niadra has a second MCP endpoint,/mcp/insights, with the base-wide analysis tools: pseudonyms by default, small groups suppressed, daily volume limits, and a receipt for every call. It takes a key with the analytics scope on an analyst source, or a person with the analysis role; revealing a customer behind a pseudonym also needs admin on the key or security on the person, and a reason.
Next steps
History navigation
search, timeline and open in depth.
MCP clients
Claude Code, Claude Desktop, Cursor and VS Code connected to your space.
Mint a subject_token
the request and response.
Spaces and keys
scopes, audiences and revocation.
Receipts and audit
what every read made through a tool leaves behind.

