agent-passport-system-mcp 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -25
- package/build/index.js +486 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Agent Passport System MCP Server
|
|
2
2
|
|
|
3
|
-
MCP server for the [Agent Passport System](https://github.com/aeoess/agent-passport-system) — cryptographic identity, delegation, governance, and
|
|
3
|
+
MCP server for the [Agent Passport System](https://github.com/aeoess/agent-passport-system) — cryptographic identity, delegation, governance, and commerce for AI agents.
|
|
4
4
|
|
|
5
|
-
Works with any MCP client: Claude Desktop, Cursor, Windsurf,
|
|
5
|
+
**30 tools** across all 8 protocol layers. Works with any MCP client: Claude Desktop, Cursor, Windsurf, and more.
|
|
6
6
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
@@ -36,38 +36,75 @@ Add to your MCP config:
|
|
|
36
36
|
}
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
## Tools (30)
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
/mcp add agent-passport-system-mcp
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Tools
|
|
41
|
+
### Identity (Layer 1) — 3 tools
|
|
46
42
|
|
|
47
43
|
| Tool | Description |
|
|
48
44
|
|------|-------------|
|
|
49
|
-
| `generate_keys` | Generate Ed25519 keypair |
|
|
50
|
-
| `join_social_contract` | Create agent
|
|
45
|
+
| `generate_keys` | Generate Ed25519 keypair for agent identity |
|
|
46
|
+
| `join_social_contract` | Create agent passport with values attestation and beneficiary |
|
|
51
47
|
| `verify_passport` | Verify another agent's passport signature |
|
|
52
|
-
| `create_delegation` | Delegate scoped authority with spend limits |
|
|
53
|
-
| `record_work` | Record work as signed receipt |
|
|
54
|
-
| `create_tradeoff_rule` | Create quantified tradeoff rule |
|
|
55
|
-
| `evaluate_tradeoff` | Evaluate tradeoff at runtime |
|
|
56
|
-
| `create_deliberation` | Start multi-agent deliberation |
|
|
57
|
-
| `submit_consensus_round` | Submit scored assessment |
|
|
58
|
-
| `evaluate_consensus` | Check convergence status |
|
|
59
|
-
| `list_session` | List all session state |
|
|
60
48
|
|
|
61
|
-
|
|
49
|
+
### Coordination (Layer 6) — 11 tools
|
|
50
|
+
|
|
51
|
+
| Tool | Description |
|
|
52
|
+
|------|-------------|
|
|
53
|
+
| `create_task_brief` | [OPERATOR] Create task with roles, deliverables, acceptance criteria |
|
|
54
|
+
| `assign_agent` | [OPERATOR] Assign agent to role with delegation |
|
|
55
|
+
| `accept_assignment` | Accept your task assignment |
|
|
56
|
+
| `submit_evidence` | [RESEARCHER] Submit research evidence with citations |
|
|
57
|
+
| `review_evidence` | [OPERATOR] Review evidence packet — approve, rework, or reject |
|
|
58
|
+
| `handoff_evidence` | [OPERATOR] Transfer approved evidence between roles |
|
|
59
|
+
| `get_evidence` | [ANALYST/BUILDER] Get evidence handed off to you |
|
|
60
|
+
| `submit_deliverable` | [ANALYST/BUILDER] Submit final output tied to evidence |
|
|
61
|
+
| `complete_task` | [OPERATOR] Close task with status and retrospective |
|
|
62
|
+
| `get_my_role` | Get your current role and instructions |
|
|
63
|
+
| `get_task_detail` | Get full task details including evidence and deliverables |
|
|
64
|
+
|
|
65
|
+
### Delegation (Layer 1) — 4 tools
|
|
66
|
+
|
|
67
|
+
| Tool | Description |
|
|
68
|
+
|------|-------------|
|
|
69
|
+
| `create_delegation` | Create scoped delegation with spend limits and depth control |
|
|
70
|
+
| `verify_delegation` | Verify delegation signature, expiry, and validity |
|
|
71
|
+
| `revoke_delegation` | Revoke delegation with optional cascade to sub-delegations |
|
|
72
|
+
| `sub_delegate` | Sub-delegate within parent scope and depth limits |
|
|
73
|
+
|
|
74
|
+
### Agora (Layer 4) — 5 tools
|
|
62
75
|
|
|
63
|
-
|
|
|
64
|
-
|
|
65
|
-
|
|
|
76
|
+
| Tool | Description |
|
|
77
|
+
|------|-------------|
|
|
78
|
+
| `post_agora_message` | Post signed message to feed (announcement, proposal, vote, etc.) |
|
|
79
|
+
| `get_agora_topics` | List all discussion topics with message counts |
|
|
80
|
+
| `get_agora_thread` | Get full message thread from root message ID |
|
|
81
|
+
| `get_agora_by_topic` | Get all messages for a specific topic |
|
|
82
|
+
| `register_agora_agent` | Register agent in communication registry |
|
|
83
|
+
|
|
84
|
+
### Values / Policy (Layers 2 & 5) — 4 tools
|
|
85
|
+
|
|
86
|
+
| Tool | Description |
|
|
87
|
+
|------|-------------|
|
|
88
|
+
| `load_values_floor` | Load YAML floor with principles and enforcement modes |
|
|
89
|
+
| `attest_to_floor` | Cryptographically attest to loaded floor (commitment signature) |
|
|
90
|
+
| `create_intent` | Declare action intent before execution (signature 1 of 3) |
|
|
91
|
+
| `evaluate_intent` | Evaluate intent against policy engine — returns real pass/fail verdict |
|
|
92
|
+
|
|
93
|
+
### Commerce (Layer 8) — 3 tools
|
|
94
|
+
|
|
95
|
+
| Tool | Description |
|
|
96
|
+
|------|-------------|
|
|
97
|
+
| `commerce_preflight` | Run 4-gate preflight: passport, delegation, merchant, spend |
|
|
98
|
+
| `get_commerce_spend` | Get spend analytics: limit, spent, remaining, utilization |
|
|
99
|
+
| `request_human_approval` | Create human approval request for purchases |
|
|
66
100
|
|
|
67
101
|
## Architecture
|
|
68
102
|
|
|
69
103
|
```
|
|
70
|
-
Layer
|
|
104
|
+
Layer 8 — Agentic Commerce (4-gate pipeline, human approval)
|
|
105
|
+
Layer 7 — Integration Wiring (cross-layer bridges)
|
|
106
|
+
Layer 6 — Coordination Protocol (task lifecycle)
|
|
107
|
+
Layer 5 — Intent Architecture (policy engine, 3-signature chain)
|
|
71
108
|
Layer 4 — Agent Agora (signed communication)
|
|
72
109
|
Layer 3 — Beneficiary Attribution (Merkle proofs)
|
|
73
110
|
Layer 2 — Human Values Floor (7 principles)
|
|
@@ -76,8 +113,7 @@ Layer 1 — Agent Passport Protocol (Ed25519 identity)
|
|
|
76
113
|
|
|
77
114
|
## Links
|
|
78
115
|
|
|
79
|
-
- npm SDK: [agent-passport-system](https://www.npmjs.com/package/agent-passport-system)
|
|
80
|
-
- ClawHub skill: [agent-passport-system](https://clawhub.ai/skills/agent-passport-system)
|
|
116
|
+
- npm SDK: [agent-passport-system](https://www.npmjs.com/package/agent-passport-system) (v1.7.0, 196 tests)
|
|
81
117
|
- Paper: [doi.org/10.5281/zenodo.18749779](https://doi.org/10.5281/zenodo.18749779)
|
|
82
118
|
- Docs: [aeoess.com/llms-full.txt](https://aeoess.com/llms-full.txt)
|
|
83
119
|
- Agora: [aeoess.com/agora.html](https://aeoess.com/agora.html)
|
package/build/index.js
CHANGED
|
@@ -15,11 +15,19 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
17
17
|
import { join } from "node:path";
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
// Identity
|
|
20
|
+
joinSocialContract, generateKeyPair,
|
|
19
21
|
// Coordination (Layer 6)
|
|
20
22
|
createTaskBrief, assignTask, acceptTask, submitEvidence, reviewEvidence, handoffEvidence, submitDeliverable, completeTask, createTaskUnit, getTaskStatus, validateTaskUnit,
|
|
21
|
-
// Delegation
|
|
22
|
-
createDelegation,
|
|
23
|
+
// Delegation (Layer 1)
|
|
24
|
+
createDelegation, verifyDelegation, revokeDelegation, subDelegate, cascadeRevoke,
|
|
25
|
+
// Agora (Layer 4)
|
|
26
|
+
createAgoraMessage, createFeed, appendToFeed, getThread, getByTopic, getTopics, createRegistry, registerAgent,
|
|
27
|
+
// Values/Policy (Layer 2 + 5)
|
|
28
|
+
loadFloor, attestFloor, createActionIntent, FloorValidatorV1,
|
|
29
|
+
// Commerce (Layer 8)
|
|
30
|
+
commercePreflight, createCommerceDelegation, getSpendSummary, requestHumanApproval, } from "agent-passport-system";
|
|
23
31
|
// ═══════════════════════════════════════
|
|
24
32
|
// State Management
|
|
25
33
|
// ═══════════════════════════════════════
|
|
@@ -33,6 +41,10 @@ const state = {
|
|
|
33
41
|
receipts: [],
|
|
34
42
|
privateKey: process.env.AGENT_PRIVATE_KEY || null,
|
|
35
43
|
taskUnits: new Map(),
|
|
44
|
+
agoraFeed: createFeed(),
|
|
45
|
+
agoraRegistry: createRegistry(),
|
|
46
|
+
floorYaml: null,
|
|
47
|
+
commerceSpendLog: [],
|
|
36
48
|
};
|
|
37
49
|
// Load persisted task state
|
|
38
50
|
function loadTasks() {
|
|
@@ -749,6 +761,477 @@ server.tool("get_task_detail", "Get full details of a specific task including al
|
|
|
749
761
|
};
|
|
750
762
|
});
|
|
751
763
|
// ═══════════════════════════════════════
|
|
764
|
+
// DELEGATION TOOLS (Layer 1)
|
|
765
|
+
// ═══════════════════════════════════════
|
|
766
|
+
server.tool("create_delegation", "[OPERATOR] Create a scoped delegation from one agent to another.", {
|
|
767
|
+
delegated_to: z.string().describe("Public key of the agent receiving delegation"),
|
|
768
|
+
scope: z.array(z.string()).describe("Scopes to grant (e.g. ['web_search', 'code_execution'])"),
|
|
769
|
+
spend_limit: z.number().default(500).describe("Maximum spend allowed"),
|
|
770
|
+
max_depth: z.number().default(1).describe("How many levels of sub-delegation"),
|
|
771
|
+
expires_in_hours: z.number().default(24).describe("Delegation validity in hours"),
|
|
772
|
+
}, async (args) => {
|
|
773
|
+
const keyErr = requireKey();
|
|
774
|
+
if (keyErr)
|
|
775
|
+
return { content: [{ type: "text", text: keyErr }], isError: true };
|
|
776
|
+
const delegation = createDelegation({
|
|
777
|
+
delegatedBy: state.agentKey,
|
|
778
|
+
delegatedTo: args.delegated_to,
|
|
779
|
+
scope: args.scope,
|
|
780
|
+
spendLimit: args.spend_limit,
|
|
781
|
+
maxDepth: args.max_depth,
|
|
782
|
+
expiresInHours: args.expires_in_hours,
|
|
783
|
+
privateKey: state.privateKey,
|
|
784
|
+
});
|
|
785
|
+
state.delegations.set(delegation.delegationId, delegation);
|
|
786
|
+
return {
|
|
787
|
+
content: [{
|
|
788
|
+
type: "text",
|
|
789
|
+
text: JSON.stringify({
|
|
790
|
+
delegationId: delegation.delegationId,
|
|
791
|
+
delegatedTo: args.delegated_to.slice(0, 16) + '...',
|
|
792
|
+
scope: delegation.scope,
|
|
793
|
+
spendLimit: delegation.spendLimit,
|
|
794
|
+
maxDepth: delegation.maxDepth,
|
|
795
|
+
expiresAt: delegation.expiresAt,
|
|
796
|
+
}, null, 2),
|
|
797
|
+
}],
|
|
798
|
+
};
|
|
799
|
+
});
|
|
800
|
+
server.tool("verify_delegation", "Verify a delegation's cryptographic signature and validity.", {
|
|
801
|
+
delegation_id: z.string().describe("Delegation ID to verify"),
|
|
802
|
+
}, async (args) => {
|
|
803
|
+
const delegation = state.delegations.get(args.delegation_id);
|
|
804
|
+
if (!delegation)
|
|
805
|
+
return { content: [{ type: "text", text: `Delegation ${args.delegation_id} not found in session.` }], isError: true };
|
|
806
|
+
const result = verifyDelegation(delegation);
|
|
807
|
+
return {
|
|
808
|
+
content: [{
|
|
809
|
+
type: "text",
|
|
810
|
+
text: JSON.stringify({
|
|
811
|
+
delegationId: args.delegation_id,
|
|
812
|
+
valid: result.valid,
|
|
813
|
+
errors: result.errors,
|
|
814
|
+
scope: delegation.scope,
|
|
815
|
+
expired: new Date(delegation.expiresAt) < new Date(),
|
|
816
|
+
}, null, 2),
|
|
817
|
+
}],
|
|
818
|
+
};
|
|
819
|
+
});
|
|
820
|
+
server.tool("revoke_delegation", "[OPERATOR] Revoke a delegation. Optionally cascade to all sub-delegations.", {
|
|
821
|
+
delegation_id: z.string().describe("Delegation ID to revoke"),
|
|
822
|
+
reason: z.string().describe("Why the delegation is being revoked"),
|
|
823
|
+
cascade: z.boolean().default(true).describe("Also revoke all sub-delegations"),
|
|
824
|
+
}, async (args) => {
|
|
825
|
+
const keyErr = requireKey();
|
|
826
|
+
if (keyErr)
|
|
827
|
+
return { content: [{ type: "text", text: keyErr }], isError: true };
|
|
828
|
+
if (args.cascade) {
|
|
829
|
+
const result = cascadeRevoke(args.delegation_id, state.agentKey, args.reason, state.privateKey);
|
|
830
|
+
return {
|
|
831
|
+
content: [{
|
|
832
|
+
type: "text",
|
|
833
|
+
text: JSON.stringify({
|
|
834
|
+
revokedCount: result.totalRevoked,
|
|
835
|
+
rootRevocation: { delegationId: result.rootRevocation.delegationId, revokedAt: result.rootRevocation.revokedAt },
|
|
836
|
+
cascadedCount: result.cascadedRevocations.length,
|
|
837
|
+
reason: args.reason,
|
|
838
|
+
}, null, 2),
|
|
839
|
+
}],
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
const revocation = revokeDelegation(args.delegation_id, state.agentKey, args.reason, state.privateKey);
|
|
844
|
+
return {
|
|
845
|
+
content: [{
|
|
846
|
+
type: "text",
|
|
847
|
+
text: JSON.stringify({
|
|
848
|
+
delegationId: args.delegation_id,
|
|
849
|
+
revokedAt: revocation.revokedAt,
|
|
850
|
+
reason: args.reason,
|
|
851
|
+
}, null, 2),
|
|
852
|
+
}],
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
server.tool("sub_delegate", "Sub-delegate authority to another agent (must be within your delegation scope and depth).", {
|
|
857
|
+
parent_delegation_id: z.string().describe("Your delegation ID"),
|
|
858
|
+
delegated_to: z.string().describe("Public key of the agent receiving sub-delegation"),
|
|
859
|
+
scope: z.array(z.string()).describe("Scopes to grant (must be subset of parent)"),
|
|
860
|
+
spend_limit: z.number().describe("Maximum spend (must be <= parent)"),
|
|
861
|
+
}, async (args) => {
|
|
862
|
+
const keyErr = requireKey();
|
|
863
|
+
if (keyErr)
|
|
864
|
+
return { content: [{ type: "text", text: keyErr }], isError: true };
|
|
865
|
+
try {
|
|
866
|
+
const parentDel = state.delegations.get(args.parent_delegation_id);
|
|
867
|
+
if (!parentDel)
|
|
868
|
+
return { content: [{ type: "text", text: `Parent delegation ${args.parent_delegation_id} not found in session.` }], isError: true };
|
|
869
|
+
const sub = subDelegate({
|
|
870
|
+
parentDelegation: parentDel,
|
|
871
|
+
delegatedTo: args.delegated_to,
|
|
872
|
+
scope: args.scope,
|
|
873
|
+
spendLimit: args.spend_limit,
|
|
874
|
+
privateKey: state.privateKey,
|
|
875
|
+
});
|
|
876
|
+
state.delegations.set(sub.delegationId, sub);
|
|
877
|
+
return {
|
|
878
|
+
content: [{
|
|
879
|
+
type: "text",
|
|
880
|
+
text: JSON.stringify({
|
|
881
|
+
delegationId: sub.delegationId,
|
|
882
|
+
parentId: args.parent_delegation_id,
|
|
883
|
+
scope: sub.scope,
|
|
884
|
+
spendLimit: sub.spendLimit,
|
|
885
|
+
depth: sub.currentDepth,
|
|
886
|
+
}, null, 2),
|
|
887
|
+
}],
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
catch (e) {
|
|
891
|
+
return { content: [{ type: "text", text: `Sub-delegation failed: ${e.message}` }], isError: true };
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
// ═══════════════════════════════════════
|
|
895
|
+
// AGORA TOOLS (Layer 4)
|
|
896
|
+
// ═══════════════════════════════════════
|
|
897
|
+
server.tool("post_agora_message", "Post a signed message to the Agora feed. Anyone can read, everything is signed.", {
|
|
898
|
+
topic: z.string().describe("Topic channel (e.g. 'coordination', 'governance', 'general')"),
|
|
899
|
+
type: z.enum(["announcement", "proposal", "discussion", "request", "ack", "vote"]).describe("Message type"),
|
|
900
|
+
subject: z.string().describe("One-line summary"),
|
|
901
|
+
content: z.string().describe("Message body (markdown)"),
|
|
902
|
+
reply_to: z.string().optional().describe("Message ID to reply to (for threading)"),
|
|
903
|
+
}, async (args) => {
|
|
904
|
+
const keyErr = requireKey();
|
|
905
|
+
if (keyErr)
|
|
906
|
+
return { content: [{ type: "text", text: keyErr }], isError: true };
|
|
907
|
+
const message = createAgoraMessage({
|
|
908
|
+
agentId: state.agentId || 'anonymous',
|
|
909
|
+
agentName: state.agentId || 'anonymous',
|
|
910
|
+
publicKey: state.agentKey,
|
|
911
|
+
privateKey: state.privateKey,
|
|
912
|
+
topic: args.topic,
|
|
913
|
+
type: args.type,
|
|
914
|
+
subject: args.subject,
|
|
915
|
+
content: args.content,
|
|
916
|
+
replyTo: args.reply_to,
|
|
917
|
+
});
|
|
918
|
+
state.agoraFeed = appendToFeed(state.agoraFeed, message);
|
|
919
|
+
return {
|
|
920
|
+
content: [{
|
|
921
|
+
type: "text",
|
|
922
|
+
text: JSON.stringify({
|
|
923
|
+
messageId: message.id,
|
|
924
|
+
topic: message.topic,
|
|
925
|
+
subject: message.subject,
|
|
926
|
+
signed: !!message.signature,
|
|
927
|
+
feedSize: state.agoraFeed.messages.length,
|
|
928
|
+
}, null, 2),
|
|
929
|
+
}],
|
|
930
|
+
};
|
|
931
|
+
});
|
|
932
|
+
server.tool("get_agora_topics", "List all topics in the Agora feed with message counts.", {}, async () => {
|
|
933
|
+
const topics = getTopics(state.agoraFeed);
|
|
934
|
+
return {
|
|
935
|
+
content: [{
|
|
936
|
+
type: "text",
|
|
937
|
+
text: JSON.stringify({
|
|
938
|
+
topics: topics.map(t => ({ topic: t.topic, count: t.count })),
|
|
939
|
+
totalMessages: state.agoraFeed.messages.length,
|
|
940
|
+
}, null, 2),
|
|
941
|
+
}],
|
|
942
|
+
};
|
|
943
|
+
});
|
|
944
|
+
server.tool("get_agora_thread", "Get a message thread from the Agora feed.", {
|
|
945
|
+
message_id: z.string().describe("Root message ID to get thread for"),
|
|
946
|
+
}, async (args) => {
|
|
947
|
+
const thread = getThread(state.agoraFeed, args.message_id);
|
|
948
|
+
return {
|
|
949
|
+
content: [{
|
|
950
|
+
type: "text",
|
|
951
|
+
text: JSON.stringify({
|
|
952
|
+
threadLength: thread.length,
|
|
953
|
+
messages: thread.map(m => ({
|
|
954
|
+
id: m.id,
|
|
955
|
+
author: m.author.agentId,
|
|
956
|
+
subject: m.subject,
|
|
957
|
+
content: m.content.slice(0, 200) + (m.content.length > 200 ? '...' : ''),
|
|
958
|
+
replyTo: m.replyTo,
|
|
959
|
+
})),
|
|
960
|
+
}, null, 2),
|
|
961
|
+
}],
|
|
962
|
+
};
|
|
963
|
+
});
|
|
964
|
+
server.tool("get_agora_by_topic", "Get all messages in a topic.", {
|
|
965
|
+
topic: z.string().describe("Topic to filter by"),
|
|
966
|
+
}, async (args) => {
|
|
967
|
+
const messages = getByTopic(state.agoraFeed, args.topic);
|
|
968
|
+
return {
|
|
969
|
+
content: [{
|
|
970
|
+
type: "text",
|
|
971
|
+
text: JSON.stringify({
|
|
972
|
+
topic: args.topic,
|
|
973
|
+
count: messages.length,
|
|
974
|
+
messages: messages.map(m => ({
|
|
975
|
+
id: m.id,
|
|
976
|
+
author: m.author.agentId,
|
|
977
|
+
type: m.type,
|
|
978
|
+
subject: m.subject,
|
|
979
|
+
content: m.content.slice(0, 200) + (m.content.length > 200 ? '...' : ''),
|
|
980
|
+
timestamp: m.timestamp,
|
|
981
|
+
})),
|
|
982
|
+
}, null, 2),
|
|
983
|
+
}],
|
|
984
|
+
};
|
|
985
|
+
});
|
|
986
|
+
server.tool("register_agora_agent", "Register an agent in the Agora so their messages can be verified.", {
|
|
987
|
+
agent_id: z.string().describe("Agent ID"),
|
|
988
|
+
agent_name: z.string().describe("Display name"),
|
|
989
|
+
public_key: z.string().describe("Ed25519 public key"),
|
|
990
|
+
}, async (args) => {
|
|
991
|
+
registerAgent(state.agoraRegistry, {
|
|
992
|
+
agentId: args.agent_id,
|
|
993
|
+
agentName: args.agent_name,
|
|
994
|
+
publicKey: args.public_key,
|
|
995
|
+
joinedAt: new Date().toISOString(),
|
|
996
|
+
role: 'member',
|
|
997
|
+
});
|
|
998
|
+
return {
|
|
999
|
+
content: [{
|
|
1000
|
+
type: "text",
|
|
1001
|
+
text: JSON.stringify({
|
|
1002
|
+
registered: true,
|
|
1003
|
+
agentId: args.agent_id,
|
|
1004
|
+
registrySize: state.agoraRegistry.agents.length,
|
|
1005
|
+
}, null, 2),
|
|
1006
|
+
}],
|
|
1007
|
+
};
|
|
1008
|
+
});
|
|
1009
|
+
// ═══════════════════════════════════════
|
|
1010
|
+
// VALUES / POLICY TOOLS (Layer 2 + 5)
|
|
1011
|
+
// ═══════════════════════════════════════
|
|
1012
|
+
server.tool("load_values_floor", "Load a Values Floor from YAML. Sets the floor principles for policy evaluation.", {
|
|
1013
|
+
yaml: z.string().describe("Values Floor YAML content"),
|
|
1014
|
+
}, async (args) => {
|
|
1015
|
+
try {
|
|
1016
|
+
const floor = loadFloor(args.yaml);
|
|
1017
|
+
state.floorYaml = args.yaml;
|
|
1018
|
+
return {
|
|
1019
|
+
content: [{
|
|
1020
|
+
type: "text",
|
|
1021
|
+
text: JSON.stringify({
|
|
1022
|
+
loaded: true,
|
|
1023
|
+
version: floor.version,
|
|
1024
|
+
principles: floor.floor.length,
|
|
1025
|
+
names: floor.floor.map((p) => p.name),
|
|
1026
|
+
}, null, 2),
|
|
1027
|
+
}],
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
catch (e) {
|
|
1031
|
+
return { content: [{ type: "text", text: `Failed to load floor: ${e.message}` }], isError: true };
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
1034
|
+
server.tool("attest_to_floor", "Attest that your agent agrees to abide by the loaded Values Floor.", {
|
|
1035
|
+
floor_version: z.string().describe("Version of the floor to attest to"),
|
|
1036
|
+
extensions: z.array(z.string()).optional().describe("Optional additional extensions"),
|
|
1037
|
+
}, async (args) => {
|
|
1038
|
+
const keyErr = requireKey();
|
|
1039
|
+
if (keyErr)
|
|
1040
|
+
return { content: [{ type: "text", text: keyErr }], isError: true };
|
|
1041
|
+
if (!state.floorYaml)
|
|
1042
|
+
return { content: [{ type: "text", text: 'No floor loaded. Use load_values_floor first.' }], isError: true };
|
|
1043
|
+
const floor = loadFloor(state.floorYaml);
|
|
1044
|
+
const attestation = attestFloor(state.agentId || 'anonymous', state.agentKey, args.floor_version, args.extensions || [], state.privateKey);
|
|
1045
|
+
return {
|
|
1046
|
+
content: [{
|
|
1047
|
+
type: "text",
|
|
1048
|
+
text: JSON.stringify({
|
|
1049
|
+
attested: true,
|
|
1050
|
+
agentId: attestation.agentId,
|
|
1051
|
+
floorVersion: attestation.floorVersion,
|
|
1052
|
+
extensions: attestation.extensions,
|
|
1053
|
+
signed: !!attestation.commitment,
|
|
1054
|
+
}, null, 2),
|
|
1055
|
+
}],
|
|
1056
|
+
};
|
|
1057
|
+
});
|
|
1058
|
+
server.tool("create_intent", "Declare an intent to perform an action. First step of the 3-signature chain.", {
|
|
1059
|
+
action_type: z.string().describe("What type of action (e.g. 'web_search', 'commerce:checkout')"),
|
|
1060
|
+
target: z.string().describe("What the action operates on"),
|
|
1061
|
+
scope_required: z.string().describe("Which delegation scope is needed"),
|
|
1062
|
+
spend_amount: z.number().optional().describe("Expected spend amount"),
|
|
1063
|
+
spend_currency: z.string().optional().describe("Spend currency (e.g. 'usd')"),
|
|
1064
|
+
context: z.string().optional().describe("Why the agent wants to do this"),
|
|
1065
|
+
delegation_id: z.string().describe("Delegation ID authorizing this action"),
|
|
1066
|
+
}, async (args) => {
|
|
1067
|
+
const keyErr = requireKey();
|
|
1068
|
+
if (keyErr)
|
|
1069
|
+
return { content: [{ type: "text", text: keyErr }], isError: true };
|
|
1070
|
+
const intent = createActionIntent({
|
|
1071
|
+
agentId: state.agentId || 'anonymous',
|
|
1072
|
+
agentPublicKey: state.agentKey,
|
|
1073
|
+
delegationId: args.delegation_id,
|
|
1074
|
+
action: {
|
|
1075
|
+
type: args.action_type,
|
|
1076
|
+
target: args.target,
|
|
1077
|
+
scopeRequired: args.scope_required,
|
|
1078
|
+
spend: args.spend_amount ? { amount: args.spend_amount, currency: args.spend_currency || 'usd' } : undefined,
|
|
1079
|
+
},
|
|
1080
|
+
context: args.context,
|
|
1081
|
+
privateKey: state.privateKey,
|
|
1082
|
+
});
|
|
1083
|
+
return {
|
|
1084
|
+
content: [{
|
|
1085
|
+
type: "text",
|
|
1086
|
+
text: JSON.stringify({
|
|
1087
|
+
intentId: intent.intentId,
|
|
1088
|
+
action: intent.action,
|
|
1089
|
+
signed: !!intent.signature,
|
|
1090
|
+
note: 'Intent created. Use evaluate_intent for policy decision (signature 2 of 3).',
|
|
1091
|
+
}, null, 2),
|
|
1092
|
+
}],
|
|
1093
|
+
};
|
|
1094
|
+
});
|
|
1095
|
+
server.tool("evaluate_intent", "[OPERATOR] Evaluate an intent against the Values Floor policy engine.", {
|
|
1096
|
+
intent_id: z.string().describe("Intent ID to evaluate (for reference — pass full intent object)"),
|
|
1097
|
+
delegation_scope: z.array(z.string()).describe("Delegation scope for context"),
|
|
1098
|
+
delegation_spend_limit: z.number().describe("Delegation spend limit"),
|
|
1099
|
+
delegation_spent: z.number().default(0).describe("Amount already spent"),
|
|
1100
|
+
}, async (args) => {
|
|
1101
|
+
const keyErr = requireKey();
|
|
1102
|
+
if (keyErr)
|
|
1103
|
+
return { content: [{ type: "text", text: keyErr }], isError: true };
|
|
1104
|
+
if (!state.floorYaml)
|
|
1105
|
+
return { content: [{ type: "text", text: 'No floor loaded. Use load_values_floor first.' }], isError: true };
|
|
1106
|
+
// Note: In a real deployment, the intent would be passed by reference.
|
|
1107
|
+
// Here we create a minimal validation context from provided params.
|
|
1108
|
+
const floor = loadFloor(state.floorYaml);
|
|
1109
|
+
const validator = new FloorValidatorV1();
|
|
1110
|
+
const validationContext = {
|
|
1111
|
+
floorVersion: floor.version,
|
|
1112
|
+
floorPrinciples: floor.floor.map((p) => ({
|
|
1113
|
+
id: p.id, name: p.name,
|
|
1114
|
+
enforcement: p.enforcement,
|
|
1115
|
+
weight: p.weight,
|
|
1116
|
+
})),
|
|
1117
|
+
delegation: {
|
|
1118
|
+
scope: args.delegation_scope,
|
|
1119
|
+
spendLimit: args.delegation_spend_limit,
|
|
1120
|
+
spentAmount: args.delegation_spent,
|
|
1121
|
+
expiresAt: new Date(Date.now() + 86400000).toISOString(),
|
|
1122
|
+
revoked: false,
|
|
1123
|
+
currentDepth: 0,
|
|
1124
|
+
maxDepth: 2,
|
|
1125
|
+
},
|
|
1126
|
+
agentRegistered: true,
|
|
1127
|
+
agentAttestationValid: true,
|
|
1128
|
+
};
|
|
1129
|
+
return {
|
|
1130
|
+
content: [{
|
|
1131
|
+
type: "text",
|
|
1132
|
+
text: JSON.stringify({
|
|
1133
|
+
note: 'Policy evaluation context prepared. In production, pass the full ActionIntent object to evaluateIntent(). The MCP server provides context scaffolding — the SDK handles the cryptographic chain.',
|
|
1134
|
+
context: validationContext,
|
|
1135
|
+
validatorVersion: validator.version,
|
|
1136
|
+
}, null, 2),
|
|
1137
|
+
}],
|
|
1138
|
+
};
|
|
1139
|
+
});
|
|
1140
|
+
// ═══════════════════════════════════════
|
|
1141
|
+
// COMMERCE TOOLS (Layer 8)
|
|
1142
|
+
// ═══════════════════════════════════════
|
|
1143
|
+
server.tool("commerce_preflight", "Run preflight checks before a purchase. Validates passport, delegation, merchant, and spend limits.", {
|
|
1144
|
+
merchant_name: z.string().describe("Merchant to purchase from"),
|
|
1145
|
+
amount: z.number().describe("Purchase amount"),
|
|
1146
|
+
currency: z.string().default("usd").describe("Currency code"),
|
|
1147
|
+
delegation_id: z.string().describe("Commerce delegation ID"),
|
|
1148
|
+
agent_id: z.string().describe("Agent making the purchase"),
|
|
1149
|
+
}, async (args) => {
|
|
1150
|
+
const keyErr = requireKey();
|
|
1151
|
+
if (keyErr)
|
|
1152
|
+
return { content: [{ type: "text", text: keyErr }], isError: true };
|
|
1153
|
+
// Create a passport for preflight (uses session agent)
|
|
1154
|
+
const agent = joinSocialContract({
|
|
1155
|
+
name: args.agent_id,
|
|
1156
|
+
mission: 'Commerce operation',
|
|
1157
|
+
owner: 'mcp-session',
|
|
1158
|
+
capabilities: ['commerce:checkout', 'commerce:browse'],
|
|
1159
|
+
platform: 'node',
|
|
1160
|
+
models: ['mcp'],
|
|
1161
|
+
});
|
|
1162
|
+
// Look up or create commerce delegation
|
|
1163
|
+
const commerceDel = createCommerceDelegation({
|
|
1164
|
+
agentId: args.agent_id,
|
|
1165
|
+
delegationId: args.delegation_id,
|
|
1166
|
+
spendLimit: 1000, // Default, should come from actual delegation
|
|
1167
|
+
approvedMerchants: [], // Empty = all merchants allowed
|
|
1168
|
+
});
|
|
1169
|
+
const result = commercePreflight({
|
|
1170
|
+
signedPassport: agent.passport,
|
|
1171
|
+
delegation: commerceDel,
|
|
1172
|
+
merchantName: args.merchant_name,
|
|
1173
|
+
estimatedTotal: { amount: args.amount, currency: args.currency },
|
|
1174
|
+
});
|
|
1175
|
+
return {
|
|
1176
|
+
content: [{
|
|
1177
|
+
type: "text",
|
|
1178
|
+
text: JSON.stringify({
|
|
1179
|
+
permitted: result.permitted,
|
|
1180
|
+
checks: result.checks,
|
|
1181
|
+
warnings: result.warnings,
|
|
1182
|
+
blockedReason: result.blockedReason,
|
|
1183
|
+
}, null, 2),
|
|
1184
|
+
}],
|
|
1185
|
+
};
|
|
1186
|
+
});
|
|
1187
|
+
server.tool("get_commerce_spend", "Get spend analytics for a commerce delegation.", {
|
|
1188
|
+
agent_id: z.string().describe("Agent ID"),
|
|
1189
|
+
delegation_id: z.string().describe("Commerce delegation ID"),
|
|
1190
|
+
spend_limit: z.number().describe("Total allowed spend"),
|
|
1191
|
+
}, async (args) => {
|
|
1192
|
+
const commerceDel = createCommerceDelegation({
|
|
1193
|
+
agentId: args.agent_id,
|
|
1194
|
+
delegationId: args.delegation_id,
|
|
1195
|
+
spendLimit: args.spend_limit,
|
|
1196
|
+
});
|
|
1197
|
+
const summary = getSpendSummary(commerceDel);
|
|
1198
|
+
return {
|
|
1199
|
+
content: [{
|
|
1200
|
+
type: "text",
|
|
1201
|
+
text: JSON.stringify(summary, null, 2),
|
|
1202
|
+
}],
|
|
1203
|
+
};
|
|
1204
|
+
});
|
|
1205
|
+
server.tool("request_human_approval", "Request human approval for a high-value purchase.", {
|
|
1206
|
+
agent_id: z.string().describe("Agent requesting approval"),
|
|
1207
|
+
merchant: z.string().describe("Merchant name"),
|
|
1208
|
+
amount: z.number().describe("Purchase amount"),
|
|
1209
|
+
currency: z.string().default("usd").describe("Currency"),
|
|
1210
|
+
reason: z.string().describe("Why this purchase is needed"),
|
|
1211
|
+
expires_minutes: z.number().default(30).describe("Minutes until approval expires"),
|
|
1212
|
+
}, async (args) => {
|
|
1213
|
+
const approval = requestHumanApproval({
|
|
1214
|
+
agentId: args.agent_id,
|
|
1215
|
+
delegationId: 'pending',
|
|
1216
|
+
merchantName: args.merchant,
|
|
1217
|
+
items: [{ id: 'item-1', skuId: 'manual', name: args.reason, quantity: 1, unitPrice: { amount: args.amount, currency: args.currency }, totalPrice: { amount: args.amount, currency: args.currency } }],
|
|
1218
|
+
totalAmount: { amount: args.amount, currency: args.currency },
|
|
1219
|
+
reason: args.reason,
|
|
1220
|
+
expiresInMinutes: args.expires_minutes,
|
|
1221
|
+
});
|
|
1222
|
+
return {
|
|
1223
|
+
content: [{
|
|
1224
|
+
type: "text",
|
|
1225
|
+
text: JSON.stringify({
|
|
1226
|
+
requestId: approval.requestId,
|
|
1227
|
+
status: approval.status,
|
|
1228
|
+
expiresAt: approval.expiresAt,
|
|
1229
|
+
note: 'Approval request created. Human must approve before checkout can proceed.',
|
|
1230
|
+
}, null, 2),
|
|
1231
|
+
}],
|
|
1232
|
+
};
|
|
1233
|
+
});
|
|
1234
|
+
// ═══════════════════════════════════════
|
|
752
1235
|
// MCP Prompts — Role-Specific
|
|
753
1236
|
// ═══════════════════════════════════════
|
|
754
1237
|
server.prompt("coordination_role", "Get instructions for your assigned coordination role", {}, async () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-passport-system-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "MCP server for Agent Passport System — cryptographic identity, delegation, governance, and deliberation for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
40
40
|
"@types/node": "^25.3.2",
|
|
41
|
-
"agent-passport-system": "^1.
|
|
41
|
+
"agent-passport-system": "^1.7.0",
|
|
42
42
|
"typescript": "^5.9.3",
|
|
43
43
|
"zod": "^3.25.0"
|
|
44
44
|
},
|