Context
The AgentKeys MCP server is the integration surface that makes the Agent IAM thesis legible to xiaozhi-server's LLM (and any other MCP-speaking host). Without this server, the broker + signer + workers shipped in Phase 0 are invisible to the agent runtime — there's no clean way for the xiaozhi LLM to ask "what does this actor have permission to do?" or "fetch my Chengdu trip memory." The MCP server is the answer.
This is THE critical-path issue for M1. Every other M1 issue (#108 namespace, #109 two-tier audit, #110 revocation, #111 parent UI) plumbs through the tools defined here. M1's three-act demo storyboard reads as "Agent IAM, not chatbot" only when these 7 tools return the right answers in the right shape.
Scope (M1)
Active tools (7) — answer real calls
| Tool |
Signature |
What it returns |
agentkeys.identity.whoami |
(actor) |
{omni, display_name, vendor, scopes} from the chain identity tree |
agentkeys.memory.get |
(actor, namespace) |
cap-token-verified S3 read filtered by namespace (per #108) |
agentkeys.memory.put |
(actor, namespace, content) |
cap-token-verified S3 write with namespace binding |
agentkeys.permission.check |
(actor, scope, params?) |
deterministic policy engine (no LLM) — accept / deny / ask-parent verdict |
agentkeys.cap.mint |
(actor, op, params, ttl) |
bounded-TTL cap-token per agent-iam-strategy.md §3.1 |
agentkeys.cap.revoke |
(cap_id) |
immediate online; bounded offline per #110 |
agentkeys.audit.append |
(actor, event) |
emits to two-tier audit (real-time off-chain + 2-min on-chain batch) per #109 |
Schema-only tools (3) — return not_implemented_in_v1
agentkeys.delegation.grant(...)
agentkeys.delegation.revoke(...)
agentkeys.approval.request(...)
These ship as schema previews so vendors integrating in M1 see the full API shape; the wire format won't change when M4 lights them up. Return JSON shape: {"error": "not_implemented_in_v1", "scheduled_for": "M4", "spec_url": "https://github.com/litentry/agentKeys/blob/main/docs/spec/plans/milestones-roadmap.md#m4"}.
Stack
- Python (Anthropic
mcp SDK) as fallback only
- Rust (
mcp-rs) preferred
- Thin adapter layer over existing broker / signer / worker RPCs. No new backend code; the MCP server is plumbing.
- Auth: per-vendor Bearer token at the MCP transport layer +
X-AgentKeys-Actor header for per-actor scoping. The header binds to a device.actor_omni for the duration of the call.
Out of scope (defer to M2+)
Acceptance criteria
Assumptions
Risks
| Risk |
Mitigation |
| Python MCP SDK lags features we need (e.g., streaming) |
Identify the gap in week 1; switch to mcp-rs for the affected tool only |
| Vendor's MCP host interprets the tool spec differently than the spec implies |
Hit both xiaozhi-server + Volcano Ark in CI; document drift per host |
| Per-vendor bearer auth creates a "single tenant of tenants" key-sprawl problem |
Tenant tokens live in agentkeys-broker-server issuance flow; rotation policy is part of M2 |
The demo's three-act storyboard depends on deterministic verdicts from permission.check |
permission.check is policy-engine-driven (declarative rules, NOT LLM); no inference variance possible |
References
Effort
~1 week of focused engineering. Suggested sequencing:
- (Day 1-2) Python MCP SDK skeleton + Bearer auth + actor scoping
- (Day 2-3)
identity.whoami + permission.check + cap.mint + cap.revoke (broker-adapter tools)
- (Day 3-4)
memory.get + memory.put (worker-adapter tools)
- (Day 4-5)
audit.append + schema-only stubs + error envelope
- (Day 5-7) Unit tests + integration test + mock backend + CI image publish
Pickup notes for the next agent / developer
Context
The AgentKeys MCP server is the integration surface that makes the Agent IAM thesis legible to xiaozhi-server's LLM (and any other MCP-speaking host). Without this server, the broker + signer + workers shipped in Phase 0 are invisible to the agent runtime — there's no clean way for the xiaozhi LLM to ask "what does this actor have permission to do?" or "fetch my Chengdu trip memory." The MCP server is the answer.
This is THE critical-path issue for M1. Every other M1 issue (#108 namespace, #109 two-tier audit, #110 revocation, #111 parent UI) plumbs through the tools defined here. M1's three-act demo storyboard reads as "Agent IAM, not chatbot" only when these 7 tools return the right answers in the right shape.
Scope (M1)
Active tools (7) — answer real calls
agentkeys.identity.whoami(actor){omni, display_name, vendor, scopes}from the chain identity treeagentkeys.memory.get(actor, namespace)agentkeys.memory.put(actor, namespace, content)agentkeys.permission.check(actor, scope, params?)agentkeys.cap.mint(actor, op, params, ttl)agent-iam-strategy.md§3.1agentkeys.cap.revoke(cap_id)agentkeys.audit.append(actor, event)Schema-only tools (3) — return
not_implemented_in_v1agentkeys.delegation.grant(...)agentkeys.delegation.revoke(...)agentkeys.approval.request(...)These ship as schema previews so vendors integrating in M1 see the full API shape; the wire format won't change when M4 lights them up. Return JSON shape:
{"error": "not_implemented_in_v1", "scheduled_for": "M4", "spec_url": "https://github.com/litentry/agentKeys/blob/main/docs/spec/plans/milestones-roadmap.md#m4"}.Stack
mcpSDK) as fallback onlymcp-rs) preferredX-AgentKeys-Actorheader for per-actor scoping. The header binds to adevice.actor_omnifor the duration of the call.Out of scope (defer to M2+)
Acceptance criteria
mcp_server_settings.json{"error": "not_implemented_in_v1", ...}with the documented JSON shapeX-AgentKeys-Actorheader per-actor scoping verified by negative test (wrong token → 401, no-header → 403, wrong actor → 403 with audit row)agent-iam-strategy.md§4.3Assumptions
memory.get/memory.putcan pass acceptance. If Phase 1: Memory namespace model — wire to cap-token + worker filter #108 slips, those tools ship as best-effort without namespace filter and Phase 1: Memory namespace model — wire to cap-token + worker filter #108 backfills.Risks
agentkeys-broker-serverissuance flow; rotation policy is part of M2permission.checkpermission.checkis policy-engine-driven (declarative rules, NOT LLM); no inference variance possibleReferences
docs/spec/plans/milestones-roadmap.md§2 (M1 scope) — operational source of truthdocs/research/agent-iam-strategy.md§4.2 (Phase 1 MCP scope), §3.5 (namespace model), §3.1 (revocation), §4.3 (three-act demo)docs/research/volcano-ark-mcp-integration.md— Volcano Ark integration architecture + AgentKeys MCP tool inventorydocs/research/xiaozhi-hermes-architecture.md— xiaozhi-server's first-class MCP support; why no bridge fork is neededdocs/arch.md§17 (per-data-class isolation), §4 (K-key inventory) — invariants this server must not breakEffort
~1 week of focused engineering. Suggested sequencing:
identity.whoami+permission.check+cap.mint+cap.revoke(broker-adapter tools)memory.get+memory.put(worker-adapter tools)audit.append+ schema-only stubs + error envelopePickup notes for the next agent / developer
docs/spec/plans/milestones-roadmap.md§2 for M1 scope contextdocs/research/agent-iam-strategy.md§4 for the Phase 1 demo storyboard this server enablescrates/agentkeys-broker-server/+crates/agentkeys-worker-*/— the MCP server adapts these RPCs, doesn't replace themdocs/research/xiaozhi-hermes-architecture.mdDiagram C (per-turn flow)docs/research/volcano-ark-mcp-integration.mdPattern Bpermission.checkreturning the wrong allow/deny verdict in Act 2 of the demo breaks the demo. The verdict is deterministic — policy-engine, not LLM. If you're tempted to use an LLM here, stop and re-readagent-iam-strategy.md§2.4 (hard line: zero orchestration in v1)./agentkeys-issue-createskill (defined in~/.claude/skills/agentkeys-issue-create/SKILL.md) for any follow-up issues you open during this work.