agent-passport-system-mcp 2.3.0 → 2.4.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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
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
- **33 tools** across all 8 protocol layers. Works with any MCP client: Claude Desktop, Cursor, Windsurf, and more.
5
+ **37 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
 
@@ -98,6 +98,15 @@ Add to your MCP config:
98
98
  | `get_commerce_spend` | Get spend analytics: limit, spent, remaining, utilization |
99
99
  | `request_human_approval` | Create human approval request for purchases |
100
100
 
101
+ ### Comms (Agent-to-Agent) — 4 tools
102
+
103
+ | Tool | Description |
104
+ |------|-------------|
105
+ | `send_message` | Send a signed message to another agent (writes to comms/to-{agent}.json) |
106
+ | `check_messages` | Check messages addressed to you, with optional mark-as-read |
107
+ | `broadcast` | Send a signed message to all agents (writes to comms/broadcast.json) |
108
+ | `list_agents` | List registered agents from the agent registry |
109
+
101
110
  ### Agent Context (Enforcement Middleware) — 3 tools
102
111
 
103
112
  | Tool | Description |
@@ -121,7 +130,7 @@ Layer 1 — Agent Passport Protocol (Ed25519 identity)
121
130
 
122
131
  ## Links
123
132
 
124
- - npm SDK: [agent-passport-system](https://www.npmjs.com/package/agent-passport-system) (v1.8.1, 240 tests)
133
+ - npm SDK: [agent-passport-system](https://www.npmjs.com/package/agent-passport-system) (v1.8.1, 264 tests)
125
134
  - Paper: [doi.org/10.5281/zenodo.18749779](https://doi.org/10.5281/zenodo.18749779)
126
135
  - Docs: [aeoess.com/llms-full.txt](https://aeoess.com/llms-full.txt)
127
136
  - Agora: [aeoess.com/agora.html](https://aeoess.com/agora.html)
package/build/index.js CHANGED
@@ -29,13 +29,14 @@ createAgoraMessage, createFeed, appendToFeed, getThread, getByTopic, getTopics,
29
29
  // Values/Policy (Layer 2 + 5)
30
30
  loadFloor, attestFloor, createActionIntent, evaluateIntent, FloorValidatorV1,
31
31
  // Commerce (Layer 8)
32
- commercePreflight, createCommerceDelegation, getSpendSummary, requestHumanApproval, } from "agent-passport-system";
32
+ commercePreflight, createCommerceDelegation, getSpendSummary, requestHumanApproval, coordinationToAgora, } from "agent-passport-system";
33
33
  // ═══════════════════════════════════════
34
34
  // State Management
35
35
  // ═══════════════════════════════════════
36
36
  const STORE_PATH = join(process.env.HOME || '.', '.agent-passport-tasks.json');
37
37
  const COMMS_PATH = process.env.COMMS_PATH || join(process.env.HOME || '.', 'aeoess_web', 'comms');
38
38
  const AGENTS_PATH = process.env.AGENTS_PATH || join(process.env.HOME || '.', 'aeoess_web', 'agora', 'agents.json');
39
+ const AGORA_PATH = process.env.AGORA_PATH || join(process.env.HOME || '.', 'aeoess_web', 'agora', 'messages.json');
39
40
  const state = {
40
41
  agentKey: process.env.AGENT_KEY || null,
41
42
  agentRole: null,
@@ -122,6 +123,78 @@ function getAgentName() {
122
123
  return state.agentKey.slice(0, 8);
123
124
  return 'unknown';
124
125
  }
126
+ // ── Agora bridge: auto-post coordination events ──
127
+ // Load existing Agora feed from disk on startup
128
+ function loadAgoraFeed() {
129
+ if (!existsSync(AGORA_PATH))
130
+ return;
131
+ try {
132
+ const raw = JSON.parse(readFileSync(AGORA_PATH, 'utf-8'));
133
+ if (raw.messages && Array.isArray(raw.messages)) {
134
+ state.agoraFeed = {
135
+ version: raw.version || '1.0',
136
+ protocol: raw.protocol || 'agent-social-contract',
137
+ lastUpdated: raw.lastUpdated || new Date().toISOString(),
138
+ messageCount: raw.messages.length,
139
+ messages: raw.messages,
140
+ };
141
+ }
142
+ }
143
+ catch {
144
+ // Non-fatal: start with empty feed if file is corrupted
145
+ }
146
+ }
147
+ // Persist Agora feed to disk after changes
148
+ function persistAgoraFeed() {
149
+ try {
150
+ const data = {
151
+ version: state.agoraFeed.version,
152
+ protocol: state.agoraFeed.protocol,
153
+ lastUpdated: new Date().toISOString(),
154
+ messageCount: state.agoraFeed.messages.length,
155
+ messages: state.agoraFeed.messages,
156
+ };
157
+ writeFileSync(AGORA_PATH, JSON.stringify(data, null, 2));
158
+ // Also update latest.json (lightweight polling endpoint)
159
+ const latestPath = AGORA_PATH.replace('messages.json', 'latest.json');
160
+ const last = state.agoraFeed.messages[state.agoraFeed.messages.length - 1];
161
+ const latest = {
162
+ lastMessageId: last?.id || null,
163
+ lastMessageTimestamp: last?.timestamp || null,
164
+ messageCount: state.agoraFeed.messages.length,
165
+ lastUpdated: data.lastUpdated,
166
+ feedUrl: 'https://aeoess.com/agora/messages.json',
167
+ registryUrl: 'https://aeoess.com/.well-known/agents.json',
168
+ };
169
+ writeFileSync(latestPath, JSON.stringify(latest, null, 2) + '\n');
170
+ }
171
+ catch {
172
+ // Non-fatal: coordination still works even if persistence fails
173
+ }
174
+ }
175
+ function emitAgoraEvent(event, taskId, detail) {
176
+ // Skip if no identity — can't sign messages
177
+ if (!state.agentKey || !state.privateKey)
178
+ return;
179
+ try {
180
+ const result = coordinationToAgora({
181
+ event,
182
+ taskId,
183
+ agentId: state.agentId || 'anonymous',
184
+ agentName: getAgentName(),
185
+ publicKey: state.agentKey,
186
+ privateKey: state.privateKey,
187
+ feed: state.agoraFeed,
188
+ registry: state.agoraRegistry,
189
+ detail,
190
+ });
191
+ state.agoraFeed = result.feed;
192
+ persistAgoraFeed();
193
+ }
194
+ catch {
195
+ // Non-fatal: coordination still works even if Agora post fails
196
+ }
197
+ }
125
198
  function loadAgentsRegistry() {
126
199
  if (!existsSync(AGENTS_PATH))
127
200
  return [];
@@ -361,6 +434,8 @@ server.tool("create_task_brief", "[OPERATOR] Create a new task with roles, deliv
361
434
  const unit = createTaskUnit(brief);
362
435
  state.taskUnits.set(brief.taskId, unit);
363
436
  saveTasks();
437
+ // Bridge → Agora: announce task creation
438
+ emitAgoraEvent('task_created', brief.taskId, `Task "${brief.title}" created with ${brief.roles.length} roles and ${brief.deliverables.length} deliverables. ${brief.description}`);
364
439
  // Set this agent as operator
365
440
  state.agentRole = 'operator';
366
441
  return {
@@ -412,6 +487,8 @@ server.tool("assign_agent", "[OPERATOR] Assign an agent to a role in a task. Cre
412
487
  unit.brief = updatedBrief;
413
488
  unit.assignments.push(assignment);
414
489
  saveTasks();
490
+ // Bridge → Agora: announce assignment
491
+ emitAgoraEvent('task_assigned', args.task_id, `Agent ${args.agent_id} assigned as ${args.role} with delegation ${delegation.delegationId}.`);
415
492
  return {
416
493
  content: [{
417
494
  type: "text",
@@ -463,6 +540,8 @@ server.tool("review_evidence", "[OPERATOR] Review an evidence packet. Score it a
463
540
  });
464
541
  unit.reviews.push(review);
465
542
  saveTasks();
543
+ // Bridge → Agora: announce review result
544
+ emitAgoraEvent('review_completed', args.task_id, `Review verdict: ${review.verdict} (score: ${review.score}/${review.threshold}). ${review.rationale}`);
466
545
  return {
467
546
  content: [{
468
547
  type: "text",
@@ -512,6 +591,8 @@ server.tool("handoff_evidence", "[OPERATOR] Transfer approved evidence from rese
512
591
  });
513
592
  unit.handoffs.push(handoff);
514
593
  saveTasks();
594
+ // Bridge → Agora: announce handoff
595
+ emitAgoraEvent('evidence_handed_off', args.task_id, `Evidence ${args.packet_id} handed off from researcher to ${args.to_role}.`);
515
596
  return {
516
597
  content: [{
517
598
  type: "text",
@@ -550,6 +631,11 @@ server.tool("complete_task", "[OPERATOR] Close the task unit with final status a
550
631
  });
551
632
  unit.completion = completion;
552
633
  saveTasks();
634
+ // Bridge → Agora: announce task completion
635
+ emitAgoraEvent('task_completed', args.task_id, `Status: ${completion.status}. Agents: ${completion.metrics.agentCount}, ` +
636
+ `Duration: ${completion.metrics.totalDuration}s, ` +
637
+ `Rework cycles: ${completion.metrics.reworkCount}. ` +
638
+ (args.retrospective || ''));
553
639
  return {
554
640
  content: [{
555
641
  type: "text",
@@ -631,6 +717,8 @@ server.tool("submit_evidence", "[RESEARCHER] Submit research evidence as a signe
631
717
  });
632
718
  unit.evidencePackets.push(packet);
633
719
  saveTasks();
720
+ // Bridge → Agora: announce evidence submission
721
+ emitAgoraEvent('evidence_submitted', args.task_id, `Evidence packet with ${packet.metadata.totalClaims} claims (${packet.metadata.citedClaims} cited, ${packet.metadata.gapCount} gaps).`);
634
722
  return {
635
723
  content: [{
636
724
  type: "text",
@@ -714,6 +802,8 @@ server.tool("submit_deliverable", "[ANALYST/BUILDER] Submit your final output ti
714
802
  });
715
803
  unit.deliverables.push(deliverable);
716
804
  saveTasks();
805
+ // Bridge → Agora: announce deliverable
806
+ emitAgoraEvent('deliverable_submitted', args.task_id, `Deliverable for spec ${args.spec_id} submitted by ${state.agentRole || 'agent'} with ${args.citation_count} citations.`);
717
807
  return {
718
808
  content: [{
719
809
  type: "text",
@@ -966,6 +1056,7 @@ server.tool("post_agora_message", "Post a signed message to the Agora feed. Anyo
966
1056
  replyTo: args.reply_to,
967
1057
  });
968
1058
  state.agoraFeed = appendToFeed(state.agoraFeed, message);
1059
+ persistAgoraFeed();
969
1060
  return {
970
1061
  content: [{
971
1062
  type: "text",
@@ -1603,13 +1694,14 @@ server.prompt("coordination_role", "Get instructions for your assigned coordinat
1603
1694
  // ═══════════════════════════════════════
1604
1695
  async function main() {
1605
1696
  loadTasks();
1697
+ loadAgoraFeed();
1606
1698
  const roleInfo = state.agentRole
1607
1699
  ? ` | Role: ${state.agentRole}`
1608
1700
  : ' | No role (call identify or set AGENT_KEY)';
1609
1701
  const transport = new StdioServerTransport();
1610
1702
  await server.connect(transport);
1611
1703
  console.error(`Agent Passport MCP Server v2.0 running${roleInfo}`);
1612
- console.error(`Tasks loaded: ${state.taskUnits.size}`);
1704
+ console.error(`Tasks loaded: ${state.taskUnits.size} | Agora messages: ${state.agoraFeed.messages.length}`);
1613
1705
  }
1614
1706
  main().catch((error) => {
1615
1707
  console.error("Fatal error:", error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-passport-system-mcp",
3
- "version": "2.3.0",
3
+ "version": "2.4.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": {
@@ -12,7 +12,9 @@
12
12
  "scripts": {
13
13
  "build": "tsc && chmod 755 build/index.js",
14
14
  "watch": "tsc --watch",
15
- "inspector": "npx @modelcontextprotocol/inspector build/index.js"
15
+ "inspector": "npx @modelcontextprotocol/inspector build/index.js",
16
+ "prepublishOnly": "npm run build",
17
+ "postpublish": "cd ~/aeoess_web && node scripts/propagate.mjs --apply --commit 2>/dev/null || echo 'Propagation skipped (aeoess_web not found)'"
16
18
  },
17
19
  "keywords": [
18
20
  "mcp",