Quick Start
Add identity, delegation, and cryptographic proofs to any MCP server in under five minutes.
MCP solved discovery. It gave every AI agent a universal way to find and use tools. But it didn't solve trust. There's no way for a server to verify who's connecting. No way for a client to verify the server is legitimate. No accountability at all.
We've seen this movie before. When the industry designed email, nobody anticipated bad senders. Fifty years later, we're still paying for that with spam filters, DKIM, DMARC, and a global trust problem that never fully goes away. We can't make the same mistake with AI agents.
@kya-os/mcp adds the missing trust layer to MCP: cryptographic identity via DIDs, delegated authorization via Verifiable Credentials, and signed proofs on every tool call. It's an open spec, donated to the Decentralized Identity Foundation. Free to use. Built for the community.
Install
npm install @kya-os/mcp
Requires Node.js 20+. Only two dependencies: jose and json-canonicalize.
Add Identity to Your Server
One function call. That's it.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { withKyaOs, NodeCryptoProvider } from "@kya-os/mcp";
const server = new McpServer({ name: "my-server", version: "1.0.0" });
await withKyaOs(server, { crypto: new NodeCryptoProvider() });
Your server now has:
- A unique cryptographic identity (DID) generated automatically
- A handshake endpoint agents can use to establish trust
- Signed proofs attached to every tool response
- Session management with replay prevention
Register tools exactly like you normally would. KYA-OS operates at the protocol layer. Your tool code doesn't change.
See It Working
Clone the repo and run the consent-basic example:
git clone https://github.com/decentralized-identity/kya-os-mcp.git
cd kya-os-mcp
pnpm install
npx tsx examples/consent-basic/src/server.ts
Connect with MCP Inspector via stdio:
npx @modelcontextprotocol/inspector npx tsx examples/consent-basic/src/server.ts
Call the checkout tool. You'll get a consent link back. Open it, approve, retry the tool. That's the full delegation flow: agent requests access, human approves, agent retries with a signed credential, server verifies the chain and executes.
No passwords shared. No tokens stored in plaintext. The agent proves who authorized it, cryptographically, on every single call.
What's Happening Under the Hood
Every tool call through KYA-OS follows three steps:
1. Identity. Your server generates a DID (Decentralized Identifier) from an Ed25519 key pair. The agent has its own DID. Both sides know who they're talking to. No central authority required. The math proves it.
2. Delegation. For protected tools, the agent needs a Verifiable Credential: a signed, scoped, time-limited permission from a human. "User X authorizes Agent Y to perform action Z until date W." If anyone tampers with it, the signature breaks.
3. Proof. Every tool response includes a detached JWS signature over the canonical response content. The caller can verify, independently, that the response came from the server it claims to come from and hasn't been modified.
Here's what a signed proof looks like in practice. Every field is independently verifiable:
Protect Specific Tools
Not every tool needs human consent. Search results? Attach a proof, no consent needed. Place an order? That needs explicit delegation.
import {
createKyaOsMiddleware,
generateIdentity,
NodeCryptoProvider,
} from "@kya-os/mcp";
const crypto = new NodeCryptoProvider();
const identity = await generateIdentity(crypto);
const kyaos = createKyaOsMiddleware(
{ identity, session: { sessionTtlMinutes: 60 } },
crypto
);
// Public tool: proof attached, no consent needed
const search = kyaos.wrapWithProof("search", async (args) => ({
content: [{ type: "text", text: `Results for: ${args["query"]}` }],
}));
// Protected tool: requires human-approved delegation
const placeOrder = kyaos.wrapWithDelegation(
"place_order",
{
scopeId: "orders:write",
consentUrl: "https://example.com/consent",
},
kyaos.wrapWithProof("place_order", async (args) => ({
content: [{ type: "text", text: `Order placed: ${args["item"]}` }],
}))
);
You decide the boundary. Public tools get proofs automatically. Sensitive tools get proofs and require delegation. Your server, your rules.
Bring Your Own Crypto
KYA-OS doesn't lock you into any key management system. Every cryptographic operation goes through an abstract provider interface. Swap in whatever your infrastructure uses.
// Use AWS KMS instead of local keys
class KMSCryptoProvider extends CryptoProvider {
async sign(data: Uint8Array, keyArn: string) {
return kmsClient.sign({ KeyId: keyArn, Message: data });
}
}
await withKyaOs(server, { crypto: new KMSCryptoProvider() });
The same goes for storage (Redis, DynamoDB, Postgres) and DID resolution (did:key built-in, did:web built-in, or any custom method).
The Enterprise Scenario
Here's the situation this was built for.
You're running a team of engineers. They want to connect AI agents to internal tools: databases, deployment pipelines, customer systems. Today, that means agents running on shared credentials with no audit trail and no way to revoke access without rotating keys for everyone.
With KYA-OS:
- Every agent gets its own identity. No shared credentials.
- Agents prove which human authorized them, on every call.
- Permissions are scoped and time-limited. An agent authorized to read customer data cannot write to the deployment pipeline.
- Every action produces a signed receipt. Your compliance team can verify who did what, when, with whose authorization.
- Revoke one agent's access without touching anyone else.
This is what "zero trust for AI agents" actually looks like. Not a dashboard. Not a policy document. Cryptographic proof, baked into every interaction.
Shared API key, free-for-all
- Who authorized this?
- Unknown. The key is shared across 47 agents.
- Revoke one agent?
- Rotate the key, and break it for everyone.
- Audit trail?
- None. Logs only show "API_KEY_PROD" made the call.
- Response tampered?
- No way to know.
"We think agent #23 did it, but we can't prove it."
Cryptographic identity, per agent
- Who authorized this?
- Alice. A signed credential proves it, verifiable by anyone.
- Revoke one agent?
- One call. No other agent is affected.
- Audit trail?
- Every action signed with the agent's DID. Full chain of custody.
- Response tampered?
- Verify the JWS. Cryptographic proof, not trust.
signed record
Two dependencies. That's it.
@kya-os/mcp depends on jose (JWT/JWS/JWE library) and json-canonicalize (deterministic JSON serialization). No framework lock-in. No build step required. Works anywhere Node.js runs.