agent-passport-system-mcp 2.19.0 → 2.19.1

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
@@ -10,7 +10,7 @@ MCP server for the [Agent Passport System](https://github.com/aeoess/agent-passp
10
10
 
11
11
  > **🤖 For AI agents:** If you are an agent reading this, visit [aeoess.com/llms.txt](https://aeoess.com/llms.txt) for machine-readable documentation or [llms-full.txt](https://aeoess.com/llms-full.txt) for the complete technical reference. MCP discovery: [.well-known/mcp.json](https://aeoess.com/.well-known/mcp.json). This README is designed for humans.
12
12
 
13
- **124 tools** across 63 core modules + 32 v2 constitutional governance modules (separation of powers, circuit breakers, approval fatigue detection, and more). Independently cited by [PDR in Production (Nanook & Gerundium, UBC)](https://doi.org/10.5281/zenodo.19323172). Works with any MCP client: Claude Desktop, Cursor, Windsurf, and more.
13
+ **125 tools** across 63 core modules + 32 v2 constitutional governance modules (separation of powers, circuit breakers, approval fatigue detection, and more). Independently cited by [PDR in Production (Nanook & Gerundium, UBC)](https://doi.org/10.5281/zenodo.19323172). Works with any MCP client: Claude Desktop, Cursor, Windsurf, and more.
14
14
 
15
15
  ## Quick Start
16
16
 
@@ -29,7 +29,7 @@ npm install -g agent-passport-system-mcp
29
29
  npx agent-passport-system-mcp setup
30
30
  ```
31
31
 
32
- Auto-configures Claude Desktop and Cursor. Restart your AI client. 124 tools ready.
32
+ Auto-configures Claude Desktop and Cursor. Restart your AI client. 125 tools ready.
33
33
 
34
34
  <details>
35
35
  <summary>Manual config (if setup doesn't detect your client)</summary>
@@ -208,7 +208,7 @@ Layer 1 — Agent Passport Protocol (Ed25519 identity)
208
208
 
209
209
  ## Links
210
210
 
211
- - npm SDK: [agent-passport-system](https://www.npmjs.com/package/agent-passport-system) (v1.29.1, 1919 tests)
211
+ - npm SDK: [agent-passport-system](https://www.npmjs.com/package/agent-passport-system) (v1.29.2, 1929 tests)
212
212
  - Python SDK: [agent-passport-system](https://pypi.org/project/agent-passport-system/) (v0.5.1)
213
213
  - Paper (Protocol): [doi.org/10.5281/zenodo.18749779](https://doi.org/10.5281/zenodo.18749779)
214
214
  - Paper (Faceted Narrowing): [doi.org/10.5281/zenodo.19260073](https://doi.org/10.5281/zenodo.19260073)
package/build/index.js CHANGED
@@ -155,8 +155,26 @@ const state = {
155
155
  issuanceContexts: new Map(),
156
156
  issuanceChallenges: new Map(),
157
157
  issuanceCount: 0,
158
+ postIssuanceBehavior: new Map(),
159
+ recentlyIssuedPassports: new Set(),
160
+ issuanceTimestamps: new Map(),
161
+ endorsementLatencies: new Map(),
158
162
  };
159
163
  // Load persisted task state
164
+ // ── Post-issuance behavioral sequence recording ──
165
+ // Consilium signal #2: first 10 tool calls after passport issuance.
166
+ // Real agents do work. Farming agents extract. Server-recorded, can't retroactively change.
167
+ const MAX_BEHAVIORAL_SEQUENCE = 10;
168
+ function recordBehavior(toolName) {
169
+ // Record for all recently-issued passport holders in this session
170
+ for (const agentId of state.recentlyIssuedPassports) {
171
+ const seq = state.postIssuanceBehavior.get(agentId) || [];
172
+ if (seq.length < MAX_BEHAVIORAL_SEQUENCE) {
173
+ seq.push({ tool: toolName, ts: new Date().toISOString() });
174
+ state.postIssuanceBehavior.set(agentId, seq);
175
+ }
176
+ }
177
+ }
160
178
  function loadTasks() {
161
179
  if (existsSync(STORE_PATH)) {
162
180
  try {
@@ -450,6 +468,7 @@ server.tool("identify", "Identify yourself to the coordination server. Sets your
450
468
  private_key: z.string().describe("Your Ed25519 private key (for signing)"),
451
469
  agent_id: z.string().optional().describe("Your agent ID"),
452
470
  }, async (args) => {
471
+ recordBehavior('identify');
453
472
  state.agentKey = args.public_key;
454
473
  state.privateKey = args.private_key;
455
474
  state.agentId = args.agent_id || null;
@@ -543,16 +562,49 @@ server.tool("issue_passport", "Issue a complete agent passport with keys, signed
543
562
  const passport = hasIssuer
544
563
  ? countersignPassport(agent.passport, AEOESS_ISSUER_PRIVATE_KEY, 'aeoess')
545
564
  : agent.passport;
546
- // Phase 4: Derive issuance context
565
+ // Phase 4: Derive issuance context with computed signals
547
566
  const evidence = createEmptyEvidenceRecord(observed);
567
+ const issuanceAgeMs = Date.now() - (globalThis.__mcpStartTime || Date.now());
568
+ const derivedSignals = [
569
+ { key: 'issuance_age_ms', value: String(issuanceAgeMs), derivedFrom: ['serverStartTime', 'requestedAt'], computedAt: new Date().toISOString() },
570
+ { key: 'session_passport_count', value: String(state.issuanceCount), derivedFrom: ['issuanceCount'], computedAt: new Date().toISOString() },
571
+ ];
548
572
  const context = createIssuanceContext(evidence, {
549
573
  hasIssuerSignature: hasIssuer,
574
+ derivedSignals,
550
575
  });
551
576
  // Phase 5: Bind attestation to passport
552
577
  const attestedPassport = bindAttestation(passport, context);
553
578
  // Store the issuance context (server-side memory)
554
579
  const passportId = passport.passport.agentId;
555
580
  state.issuanceContexts.set(passportId, context);
581
+ state.recentlyIssuedPassports.add(passportId);
582
+ state.issuanceTimestamps.set(passportId, Date.now());
583
+ // Initialize behavioral sequence tracking for this agent
584
+ state.postIssuanceBehavior.set(passportId, [{ tool: 'issue_passport', ts: new Date().toISOString() }]);
585
+ // Bridge: fire-and-forget POST to gateway (if configured)
586
+ // When Mini adds POST /issuance-dossier, this data starts flowing automatically.
587
+ const gwUrl = process.env.AEOESS_GATEWAY_URL; // e.g. https://gateway.aeoess.com
588
+ const gwKey = process.env.AEOESS_GATEWAY_KEY; // e.g. aps_live_...
589
+ if (gwUrl && gwKey) {
590
+ fetch(`${gwUrl}/api/v1/issuance-dossier`, {
591
+ method: 'POST',
592
+ headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${gwKey}` },
593
+ body: JSON.stringify({
594
+ passport_id: passportId,
595
+ public_key_hash: sha256(attestedPassport.passport.publicKey),
596
+ passport_grade: context.assessment.passportGrade,
597
+ flags: context.assessment.flags,
598
+ attestation_bundle_hash: context.assessment.attestationBundleHash,
599
+ observed_context: context.evidence.observed,
600
+ runtime_attestations: context.evidence.runtimeAttestations,
601
+ provider_attestations: context.evidence.providerAttestations,
602
+ self_declared_signals: context.evidence.selfDeclaredSignals,
603
+ derived_signals: context.assessment.derivedSignals || [],
604
+ prior_passport_ref: context.evidence.priorPassportRef || null,
605
+ }),
606
+ }).catch(() => { }); // fire-and-forget: never block passport issuance
607
+ }
556
608
  return {
557
609
  content: [{
558
610
  type: "text",
@@ -686,6 +738,50 @@ server.tool("list_issuance_records", "List all stored issuance records with thei
686
738
  };
687
739
  });
688
740
  // ═══════════════════════════════════════
741
+ // TOOL: get_behavioral_sequence
742
+ // ═══════════════════════════════════════
743
+ server.tool("get_behavioral_sequence", "Get the post-issuance behavioral sequence for an agent. Shows the first 10 tool calls after passport issuance. Real agents do work. Farming agents extract. This is consilium signal #2.", {
744
+ agent_id: z.string().describe("The agent ID to query"),
745
+ }, async (args) => {
746
+ const sequence = state.postIssuanceBehavior.get(args.agent_id);
747
+ if (!sequence || sequence.length === 0) {
748
+ return {
749
+ content: [{
750
+ type: "text",
751
+ text: JSON.stringify({
752
+ agent_id: args.agent_id,
753
+ found: false,
754
+ note: "No behavioral sequence recorded. Agent may have been issued before tracking was enabled.",
755
+ }, null, 2),
756
+ }],
757
+ };
758
+ }
759
+ // Classify the behavioral pattern
760
+ const toolNames = sequence.map(s => s.tool);
761
+ const hasWork = toolNames.some(t => ['submit_evidence', 'publish_intent_card', 'create_agora_message', 'submit_deliverable'].includes(t));
762
+ const hasExtraction = toolNames.some(t => ['commerce_preflight', 'create_checkout'].includes(t));
763
+ const pattern = hasWork ? 'productive' : hasExtraction ? 'extractive' : 'neutral';
764
+ return {
765
+ content: [{
766
+ type: "text",
767
+ text: JSON.stringify({
768
+ agent_id: args.agent_id,
769
+ found: true,
770
+ sequence_length: sequence.length,
771
+ max_tracked: MAX_BEHAVIORAL_SEQUENCE,
772
+ pattern,
773
+ tools_called: toolNames,
774
+ sequence,
775
+ note: pattern === 'extractive'
776
+ ? "Agent's first actions after passport were value extraction (commerce). Farming signal."
777
+ : pattern === 'productive'
778
+ ? "Agent's first actions after passport were productive work. Healthy pattern."
779
+ : "Neutral pattern — identity/delegation setup.",
780
+ }, null, 2),
781
+ }],
782
+ };
783
+ });
784
+ // ═══════════════════════════════════════
689
785
  // TOOL: get_my_role
690
786
  // ═══════════════════════════════════════
691
787
  server.tool("get_my_role", "Get your current role, assigned tasks, and role-specific instructions.", {}, async () => {
@@ -1104,6 +1200,7 @@ server.tool("submit_evidence", "[RESEARCHER] Submit research evidence as a signe
1104
1200
  })).describe("Evidence claims with citations"),
1105
1201
  methodology: z.string().describe("How you gathered this evidence"),
1106
1202
  }, async (args) => {
1203
+ recordBehavior('submit_evidence');
1107
1204
  const keyErr = requireKey();
1108
1205
  if (keyErr)
1109
1206
  return { content: [{ type: "text", text: keyErr }], isError: true };
@@ -1320,6 +1417,7 @@ server.tool("create_delegation", "[OPERATOR] Create a scoped delegation from one
1320
1417
  max_depth: z.number().default(1).describe("How many levels of sub-delegation"),
1321
1418
  expires_in_hours: z.number().default(24).describe("Delegation validity in hours"),
1322
1419
  }, async (args) => {
1420
+ recordBehavior('create_delegation');
1323
1421
  const keyErr = requireKey();
1324
1422
  if (keyErr)
1325
1423
  return { content: [{ type: "text", text: keyErr }], isError: true };
@@ -1388,6 +1486,7 @@ server.tool("revoke_delegation", "[OPERATOR] Revoke a delegation. Optionally cas
1388
1486
  reason: z.string().describe("Why the delegation is being revoked"),
1389
1487
  cascade: z.boolean().default(true).describe("Also revoke all sub-delegations"),
1390
1488
  }, async (args) => {
1489
+ recordBehavior('revoke_delegation');
1391
1490
  const keyErr = requireKey();
1392
1491
  if (keyErr)
1393
1492
  return { content: [{ type: "text", text: keyErr }], isError: true };
@@ -1946,6 +2045,7 @@ server.tool("commerce_preflight", "Run preflight checks before a purchase. Valid
1946
2045
  delegation_id: z.string().describe("Commerce delegation ID"),
1947
2046
  agent_id: z.string().describe("Agent making the purchase"),
1948
2047
  }, async (args) => {
2048
+ recordBehavior('commerce_preflight');
1949
2049
  const keyErr = requireKey();
1950
2050
  if (keyErr)
1951
2051
  return { content: [{ type: "text", text: keyErr }], isError: true };
@@ -2236,6 +2336,12 @@ server.tool("endorse_agent", "Endorse an agent as a principal. Creates a cryptog
2236
2336
  relationship: z.enum(["creator", "operator", "employer", "sponsor"]).describe("How principal relates to agent"),
2237
2337
  expires_in_days: z.number().default(365).describe("Days until endorsement expires"),
2238
2338
  }, async (args) => {
2339
+ recordBehavior('endorse_agent');
2340
+ // Consilium signal #5: endorsement latency. T+200ms = automation. T+3h = human.
2341
+ const issuedAt = state.issuanceTimestamps.get(args.agent_id);
2342
+ if (issuedAt && !state.endorsementLatencies.has(args.agent_id)) {
2343
+ state.endorsementLatencies.set(args.agent_id, Date.now() - issuedAt);
2344
+ }
2239
2345
  if (!state.principal || !state.principalPrivateKey) {
2240
2346
  return { content: [{ type: "text", text: 'No principal identity. Call create_principal first.' }], isError: true };
2241
2347
  }
@@ -2792,6 +2898,7 @@ server.tool("publish_intent_card", "Publish an IntentCard to the Intent Network
2792
2898
  visibility: z.enum(["public", "verified", "minimal"]).default("public"),
2793
2899
  ttl_hours: z.number().default(24).describe("Hours until card expires"),
2794
2900
  }, async (args) => {
2901
+ recordBehavior('publish_intent_card');
2795
2902
  const keyErr = requireKey();
2796
2903
  if (keyErr)
2797
2904
  return { content: [{ type: "text", text: keyErr }], isError: true };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "agent-passport-system-mcp",
3
- "version": "2.19.0",
3
+ "version": "2.19.1",
4
4
  "mcpName": "io.github.aeoess/agent-passport-mcp",
5
- "description": "MCP server for the Agent Passport System — enforcement infrastructure for the agent economy. 124 tools across 95 modules. Policy eval <2ms. Identity, delegation, reputation, enforcement, attestation, feeless Nano wallet, commerce.",
5
+ "description": "MCP server for the Agent Passport System — enforcement infrastructure for the agent economy. 125 tools across 95 modules. Policy eval <2ms. Identity, delegation, reputation, enforcement, attestation, feeless Nano wallet, commerce.",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "agent-passport-system-mcp": "./build/bin.js",