agent-passport-system-mcp 2.9.1 → 2.10.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 +5 -3
- package/build/index.js +215 -5
- package/package.json +5 -8
package/README.md
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
MCP server for the [Agent Passport System](https://github.com/aeoess/agent-passport-system) — cryptographic identity, delegation, governance, and commerce for AI agents.
|
|
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. This README is designed for humans.
|
|
12
|
+
|
|
13
|
+
**82 tools** across 37 core modules + 30 v2 constitutional governance modules (separation of powers, circuit breakers, approval fatigue detection, and more). Works with any MCP client: Claude Desktop, Cursor, Windsurf, and more.
|
|
12
14
|
|
|
13
15
|
## Quick Start
|
|
14
16
|
|
|
@@ -27,7 +29,7 @@ npm install -g agent-passport-system-mcp
|
|
|
27
29
|
npx agent-passport-system-mcp setup
|
|
28
30
|
```
|
|
29
31
|
|
|
30
|
-
Auto-configures Claude Desktop and Cursor. Restart your AI client.
|
|
32
|
+
Auto-configures Claude Desktop and Cursor. Restart your AI client. 82 tools ready.
|
|
31
33
|
|
|
32
34
|
<details>
|
|
33
35
|
<summary>Manual config (if setup doesn't detect your client)</summary>
|
|
@@ -204,7 +206,7 @@ Layer 1 — Agent Passport Protocol (Ed25959 identity)
|
|
|
204
206
|
|
|
205
207
|
## Links
|
|
206
208
|
|
|
207
|
-
- npm SDK: [agent-passport-system](https://www.npmjs.com/package/agent-passport-system) (v1.
|
|
209
|
+
- npm SDK: [agent-passport-system](https://www.npmjs.com/package/agent-passport-system) (v1.21.1, 1165 tests)
|
|
208
210
|
- Python SDK: [agent-passport-system](https://pypi.org/project/agent-passport-system/) (v0.4.0, 86 tests)
|
|
209
211
|
- Paper: [doi.org/10.5281/zenodo.18749779](https://doi.org/10.5281/zenodo.18749779)
|
|
210
212
|
- Docs: [aeoess.com/llms-full.txt](https://aeoess.com/llms-full.txt)
|
package/build/index.js
CHANGED
|
@@ -50,6 +50,8 @@ defineV2EmergencyPathway, activateV2Emergency,
|
|
|
50
50
|
requestV2Migration,
|
|
51
51
|
// v2: Attestation
|
|
52
52
|
createV2Attestation, assessV2AttestationQuality, } from "agent-passport-system";
|
|
53
|
+
// Data Governance (Modules 36A, 38, 39 + Enforcement Gate + Training Attribution)
|
|
54
|
+
import { registerSelfAttestedSource, createContributionLedger, queryContributions, getSourceMetrics, getAgentDataFootprint, generateSettlement, verifySettlement, generateDataComplianceReport, DataEnforcementGate, createTrainingAttribution, verifyTrainingAttribution, createTrainingLedger, recordTrainingAttribution, getModelDataSources, } from "agent-passport-system";
|
|
53
55
|
// ═══════════════════════════════════════
|
|
54
56
|
// State Management
|
|
55
57
|
// ═══════════════════════════════════════
|
|
@@ -82,6 +84,10 @@ const state = {
|
|
|
82
84
|
promotionHistory: [],
|
|
83
85
|
gateway: null,
|
|
84
86
|
gatewayKeys: null,
|
|
87
|
+
dataEnforcementGate: null,
|
|
88
|
+
contributionLedger: createContributionLedger(),
|
|
89
|
+
sourceReceipts: new Map(),
|
|
90
|
+
trainingLedger: createTrainingLedger(),
|
|
85
91
|
};
|
|
86
92
|
// Load persisted task state
|
|
87
93
|
function loadTasks() {
|
|
@@ -1067,6 +1073,11 @@ server.tool("sub_delegate", "Sub-delegate authority to another agent (must be wi
|
|
|
1067
1073
|
const parentDel = state.delegations.get(args.parent_delegation_id);
|
|
1068
1074
|
if (!parentDel)
|
|
1069
1075
|
return { content: [{ type: "text", text: `Parent delegation ${args.parent_delegation_id} not found in session.` }], isError: true };
|
|
1076
|
+
// F-3 fix: pre-check revocation before attempting sub-delegation
|
|
1077
|
+
const parentStatus = verifyDelegation(parentDel);
|
|
1078
|
+
if (!parentStatus.valid) {
|
|
1079
|
+
return { content: [{ type: "text", text: `Sub-delegation failed: Parent delegation ${args.parent_delegation_id} is invalid (${parentStatus.errors.join(', ')}).` }], isError: true };
|
|
1080
|
+
}
|
|
1070
1081
|
const sub = subDelegate({
|
|
1071
1082
|
parentDelegation: parentDel,
|
|
1072
1083
|
delegatedTo: args.delegated_to,
|
|
@@ -1579,20 +1590,26 @@ server.tool("commerce_preflight", "Run preflight checks before a purchase. Valid
|
|
|
1579
1590
|
const keyErr = requireKey();
|
|
1580
1591
|
if (keyErr)
|
|
1581
1592
|
return { content: [{ type: "text", text: keyErr }], isError: true };
|
|
1593
|
+
// F-1 fix: look up actual delegation from session state for real scope/spend
|
|
1594
|
+
const sessionDel = state.delegations.get(args.delegation_id);
|
|
1595
|
+
const actualSpendLimit = sessionDel?.spendLimit ?? 1000;
|
|
1596
|
+
const hasCommerceScope = sessionDel
|
|
1597
|
+
? sessionDel.scope.some((s) => s === 'commerce' || s === 'commerce:checkout' || s.startsWith('commerce'))
|
|
1598
|
+
: (state.agentContext ? true : false); // fallback to context if no delegation found
|
|
1582
1599
|
// Create a passport for preflight (uses session agent)
|
|
1583
1600
|
const agent = joinSocialContract({
|
|
1584
1601
|
name: args.agent_id,
|
|
1585
1602
|
mission: 'Commerce operation',
|
|
1586
1603
|
owner: 'mcp-session',
|
|
1587
|
-
capabilities: ['commerce:checkout', 'commerce:browse'],
|
|
1604
|
+
capabilities: hasCommerceScope ? ['commerce:checkout', 'commerce:browse'] : [],
|
|
1588
1605
|
platform: 'node',
|
|
1589
1606
|
models: ['mcp'],
|
|
1590
1607
|
});
|
|
1591
|
-
// Look up or create commerce delegation
|
|
1608
|
+
// Look up or create commerce delegation using actual scope/spend
|
|
1592
1609
|
const commerceDel = createCommerceDelegation({
|
|
1593
1610
|
agentId: args.agent_id,
|
|
1594
1611
|
delegationId: args.delegation_id,
|
|
1595
|
-
spendLimit:
|
|
1612
|
+
spendLimit: actualSpendLimit,
|
|
1596
1613
|
approvedMerchants: [], // Empty = all merchants allowed
|
|
1597
1614
|
});
|
|
1598
1615
|
const result = commercePreflight({
|
|
@@ -1715,6 +1732,8 @@ server.tool("create_agent_context", "Create an enforcement context that automati
|
|
|
1715
1732
|
}
|
|
1716
1733
|
state.agentContext = ctx;
|
|
1717
1734
|
state.floor = floor;
|
|
1735
|
+
// F-4 fix: also register in state.agents so gateway and other tools can find this agent
|
|
1736
|
+
state.agents.set(agent.agentId, agent);
|
|
1718
1737
|
return {
|
|
1719
1738
|
content: [{
|
|
1720
1739
|
type: "text",
|
|
@@ -2205,9 +2224,20 @@ server.tool("register_gateway_agent", "Register an agent with the gateway. The a
|
|
|
2205
2224
|
if (!state.gateway) {
|
|
2206
2225
|
return { content: [{ type: "text", text: "Error: Create gateway first (create_gateway)" }] };
|
|
2207
2226
|
}
|
|
2208
|
-
|
|
2227
|
+
// F-4 fix: check both state.agents AND state.agentContext for agent data
|
|
2228
|
+
let agent = state.agents.get(agentId);
|
|
2229
|
+
if (!agent && state.agentContext && state.agentId === agentId) {
|
|
2230
|
+
// Agent was created via create_agent_context, bridge to gateway
|
|
2231
|
+
const ctx = state.agentContext;
|
|
2232
|
+
agent = {
|
|
2233
|
+
passport: ctx.agent?.passport || ctx.passport,
|
|
2234
|
+
publicKey: state.agentKey,
|
|
2235
|
+
agentId: state.agentId,
|
|
2236
|
+
attestation: ctx.agent?.attestation || ctx.attestation,
|
|
2237
|
+
};
|
|
2238
|
+
}
|
|
2209
2239
|
if (!agent) {
|
|
2210
|
-
return { content: [{ type: "text", text: `Error: Agent "${agentId}" not found in session. Join social contract first.` }] };
|
|
2240
|
+
return { content: [{ type: "text", text: `Error: Agent "${agentId}" not found in session. Join social contract or create_agent_context first.` }] };
|
|
2211
2241
|
}
|
|
2212
2242
|
const agentDelegations = Array.from(state.delegations.values()).filter(d => d.delegatedTo === agent.publicKey);
|
|
2213
2243
|
if (agentDelegations.length === 0) {
|
|
@@ -2983,6 +3013,186 @@ server.tool("check_anomaly", "Record an action and check for anomalies (first-ma
|
|
|
2983
3013
|
}
|
|
2984
3014
|
});
|
|
2985
3015
|
// ═══════════════════════════════════════
|
|
3016
|
+
// Data Governance Tools (Modules 36A, 38, 39)
|
|
3017
|
+
// ═══════════════════════════════════════
|
|
3018
|
+
server.tool("register_data_source", "Register a data source with terms for agent access. Returns a signed SourceReceipt.", {
|
|
3019
|
+
contentDescriptor: z.string().describe("Human-readable description of the data"),
|
|
3020
|
+
contentCommitment: z.string().describe("SHA-256 hash of the data content"),
|
|
3021
|
+
contentType: z.enum(["document", "structured_data", "media", "user_input", "model_context"]).describe("Type of data"),
|
|
3022
|
+
allowedPurposes: z.array(z.string()).describe("Allowed purposes: read, analyze, summarize, generate, recommend, train, embed, redistribute, commercial"),
|
|
3023
|
+
requireAttribution: z.boolean().default(true),
|
|
3024
|
+
compensationType: z.enum(["none", "attribution_only", "per_access", "negotiate"]).default("none"),
|
|
3025
|
+
compensationAmount: z.number().optional().describe("Amount per access (for per_access type)"),
|
|
3026
|
+
compensationCurrency: z.string().default("usd"),
|
|
3027
|
+
maxAccessCount: z.number().optional().describe("Max total accesses allowed"),
|
|
3028
|
+
derivativePolicy: z.enum(["unrestricted", "same_terms", "attribution_required", "no_derivatives"]).default("attribution_required"),
|
|
3029
|
+
}, async (p) => {
|
|
3030
|
+
if (!state.agentKey || !state.privateKey)
|
|
3031
|
+
return { content: [{ type: "text", text: "❌ Not identified. Call identify first." }] };
|
|
3032
|
+
const comp = p.compensationType === 'per_access'
|
|
3033
|
+
? { type: 'per_access', amount: p.compensationAmount || 0.01, currency: p.compensationCurrency }
|
|
3034
|
+
: p.compensationType === 'attribution_only' ? { type: 'attribution_only' }
|
|
3035
|
+
: p.compensationType === 'negotiate' ? { type: 'negotiate', contact: state.agentId || '' }
|
|
3036
|
+
: { type: 'none' };
|
|
3037
|
+
const terms = {
|
|
3038
|
+
allowedPurposes: p.allowedPurposes,
|
|
3039
|
+
requireAttribution: p.requireAttribution,
|
|
3040
|
+
requireNotification: false,
|
|
3041
|
+
compensation: comp,
|
|
3042
|
+
derivativePolicy: p.derivativePolicy,
|
|
3043
|
+
auditVisibility: 'source_and_principal',
|
|
3044
|
+
revocable: false,
|
|
3045
|
+
maxAccessCount: p.maxAccessCount,
|
|
3046
|
+
};
|
|
3047
|
+
const receipt = registerSelfAttestedSource({
|
|
3048
|
+
ownerPrincipalId: state.principal?.principalId || state.agentId || 'unknown',
|
|
3049
|
+
ownerPublicKey: state.agentKey,
|
|
3050
|
+
ownerPrivateKey: state.privateKey,
|
|
3051
|
+
contentCommitment: p.contentCommitment,
|
|
3052
|
+
contentType: p.contentType,
|
|
3053
|
+
contentDescriptor: p.contentDescriptor,
|
|
3054
|
+
dataTerms: terms,
|
|
3055
|
+
});
|
|
3056
|
+
state.sourceReceipts.set(receipt.sourceReceiptId, receipt);
|
|
3057
|
+
return { content: [{ type: "text", text: `✅ Data source registered.\n\nSource Receipt ID: ${receipt.sourceReceiptId}\nDescriptor: ${p.contentDescriptor}\nAllowed purposes: ${p.allowedPurposes.join(', ')}\nCompensation: ${p.compensationType}${p.compensationAmount ? ' $' + p.compensationAmount : ''}\nMax accesses: ${p.maxAccessCount || 'unlimited'}\nDerivative policy: ${p.derivativePolicy}` }] };
|
|
3058
|
+
});
|
|
3059
|
+
server.tool("create_data_enforcement_gate", "Create a data enforcement gate that checks terms before allowing data access. Modes: enforce (block violations), audit (log only), off.", {
|
|
3060
|
+
mode: z.enum(["enforce", "audit", "off"]).default("enforce").describe("Enforcement mode"),
|
|
3061
|
+
}, async (p) => {
|
|
3062
|
+
const kp = generateKeyPair();
|
|
3063
|
+
state.dataEnforcementGate = new DataEnforcementGate({
|
|
3064
|
+
gatewayId: 'gw_data_' + Date.now().toString(36),
|
|
3065
|
+
gatewayPublicKey: kp.publicKey,
|
|
3066
|
+
gatewayPrivateKey: kp.privateKey,
|
|
3067
|
+
mode: p.mode,
|
|
3068
|
+
}, state.contributionLedger);
|
|
3069
|
+
// Register all known sources
|
|
3070
|
+
for (const [id, receipt] of state.sourceReceipts) {
|
|
3071
|
+
state.dataEnforcementGate.registerSource(receipt, receipt.contentDescriptor);
|
|
3072
|
+
}
|
|
3073
|
+
return { content: [{ type: "text", text: `✅ Data enforcement gate created.\n\nMode: ${p.mode}\nRegistered sources: ${state.sourceReceipts.size}\nContribution ledger: active` }] };
|
|
3074
|
+
});
|
|
3075
|
+
server.tool("check_data_access", "Check if an agent can access a data source through the enforcement gate. Generates receipt and feeds contribution ledger.", {
|
|
3076
|
+
sourceReceiptId: z.string().describe("Source receipt ID to access"),
|
|
3077
|
+
declaredPurpose: z.enum(["read", "analyze", "summarize", "generate", "recommend", "train", "embed", "redistribute", "commercial"]).describe("Declared purpose"),
|
|
3078
|
+
accessMethod: z.enum(["api_call", "file_read", "database_query", "web_fetch", "memory_retrieval", "embedding_lookup", "stream", "human_provided"]).default("api_call"),
|
|
3079
|
+
}, async (p) => {
|
|
3080
|
+
if (!state.dataEnforcementGate)
|
|
3081
|
+
return { content: [{ type: "text", text: "❌ No enforcement gate. Call create_data_enforcement_gate first." }] };
|
|
3082
|
+
if (!state.agentKey)
|
|
3083
|
+
return { content: [{ type: "text", text: "❌ Not identified." }] };
|
|
3084
|
+
const decision = state.dataEnforcementGate.checkAccess({
|
|
3085
|
+
agentId: state.agentId || 'unknown',
|
|
3086
|
+
agentPublicKey: state.agentKey,
|
|
3087
|
+
principalId: state.principal?.principalId || 'unknown',
|
|
3088
|
+
sourceReceiptId: p.sourceReceiptId,
|
|
3089
|
+
declaredPurpose: p.declaredPurpose,
|
|
3090
|
+
accessMethod: p.accessMethod,
|
|
3091
|
+
accessScope: 'data:' + p.declaredPurpose,
|
|
3092
|
+
executionFrameId: 'frame_' + Date.now().toString(36),
|
|
3093
|
+
});
|
|
3094
|
+
const status = decision.allowed ? '✅ Access ALLOWED' : '❌ Access DENIED';
|
|
3095
|
+
let text = `${status}\n\nSource: ${p.sourceReceiptId}\nPurpose: ${p.declaredPurpose}`;
|
|
3096
|
+
if (decision.hardViolations.length)
|
|
3097
|
+
text += `\nViolations: ${decision.hardViolations.join('; ')}`;
|
|
3098
|
+
if (decision.advisoryWarnings.length)
|
|
3099
|
+
text += `\nWarnings: ${decision.advisoryWarnings.join('; ')}`;
|
|
3100
|
+
if (decision.receipt)
|
|
3101
|
+
text += `\nReceipt ID: ${decision.receipt.accessReceiptId}`;
|
|
3102
|
+
if (decision.accessesRemaining !== undefined)
|
|
3103
|
+
text += `\nAccesses remaining: ${decision.accessesRemaining}`;
|
|
3104
|
+
return { content: [{ type: "text", text }] };
|
|
3105
|
+
});
|
|
3106
|
+
server.tool("query_contributions", "Query the data contribution ledger. Filter by source, agent, principal, purpose, or time range.", {
|
|
3107
|
+
sourceReceiptId: z.string().optional(),
|
|
3108
|
+
agentId: z.string().optional(),
|
|
3109
|
+
principalId: z.string().optional(),
|
|
3110
|
+
purpose: z.string().optional(),
|
|
3111
|
+
minAccessCount: z.number().optional(),
|
|
3112
|
+
}, async (p) => {
|
|
3113
|
+
const records = queryContributions(state.contributionLedger, p);
|
|
3114
|
+
if (records.length === 0)
|
|
3115
|
+
return { content: [{ type: "text", text: "No contributions found matching query." }] };
|
|
3116
|
+
const lines = records.map(r => `• ${r.sourceDescriptor || r.sourceReceiptId}: ${r.accessCount} accesses by ${r.agentId}, purposes: ${r.purposes.join('/')}, owed: $${r.compensationAccrued.totalOwed.toFixed(4)}`);
|
|
3117
|
+
return { content: [{ type: "text", text: `📊 ${records.length} contribution records:\n\n${lines.join('\n')}` }] };
|
|
3118
|
+
});
|
|
3119
|
+
server.tool("get_source_metrics", "Get aggregate metrics for a data source: total accesses, unique agents, compensation owed.", {
|
|
3120
|
+
sourceReceiptId: z.string().describe("Source receipt ID"),
|
|
3121
|
+
}, async (p) => {
|
|
3122
|
+
const metrics = getSourceMetrics(state.contributionLedger, p.sourceReceiptId);
|
|
3123
|
+
if (!metrics)
|
|
3124
|
+
return { content: [{ type: "text", text: "No data found for this source." }] };
|
|
3125
|
+
return { content: [{ type: "text", text: `📊 Source Metrics: ${metrics.sourceDescriptor}\n\nTotal accesses: ${metrics.totalAccesses}\nUnique agents: ${metrics.uniqueAgents}\nUnique principals: ${metrics.uniquePrincipals}\nCompensation owed: $${metrics.compensationOwed.totalOwed.toFixed(4)} ${metrics.compensationOwed.currency}\nPurpose breakdown: ${JSON.stringify(metrics.purposeBreakdown)}\nTop agents: ${metrics.topAgents.map(a => `${a.agentId} (${a.accessCount})`).join(', ')}` }] };
|
|
3126
|
+
});
|
|
3127
|
+
server.tool("get_agent_data_footprint", "Show every data source an agent has accessed, with compensation status.", {
|
|
3128
|
+
agentId: z.string().describe("Agent ID to check"),
|
|
3129
|
+
}, async (p) => {
|
|
3130
|
+
const footprint = getAgentDataFootprint(state.contributionLedger, p.agentId);
|
|
3131
|
+
if (!footprint)
|
|
3132
|
+
return { content: [{ type: "text", text: "No data access found for this agent." }] };
|
|
3133
|
+
const sources = footprint.sourcesAccessed.map(s => `• ${s.sourceDescriptor || s.sourceReceiptId}: ${s.accessCount} accesses, purposes: ${s.purposes.join('/')}, status: ${s.compensationStatus}`);
|
|
3134
|
+
return { content: [{ type: "text", text: `🔍 Agent Data Footprint: ${p.agentId}\n\nTotal sources: ${footprint.totalSources}\nTotal accesses: ${footprint.totalAccesses}\nTotal compensation accrued: $${footprint.totalCompensationAccrued.toFixed(4)} ${footprint.currency}\n\nSources:\n${sources.join('\n')}` }] };
|
|
3135
|
+
});
|
|
3136
|
+
server.tool("generate_settlement", "Generate a Merkle-committed, signed settlement record for a period. Shows what's owed to each data source.", {
|
|
3137
|
+
startDate: z.string().describe("Period start (YYYY-MM-DD)"),
|
|
3138
|
+
endDate: z.string().describe("Period end (YYYY-MM-DD)"),
|
|
3139
|
+
periodLabel: z.string().describe("Label (e.g. '2026-Q1', '2026-03')"),
|
|
3140
|
+
}, async (p) => {
|
|
3141
|
+
const kp = generateKeyPair();
|
|
3142
|
+
const settlement = generateSettlement(state.contributionLedger, { startDate: p.startDate, endDate: p.endDate, periodLabel: p.periodLabel }, kp.publicKey, kp.privateKey);
|
|
3143
|
+
const verification = verifySettlement(settlement);
|
|
3144
|
+
const lines = settlement.lineItems.map(li => `• ${li.sourceDescriptor || li.sourceReceiptId}: ${li.accessCount} accesses, $${li.amount.toFixed(4)} (${li.compensationModel})`);
|
|
3145
|
+
return { content: [{ type: "text", text: `📋 Settlement Record: ${settlement.settlementId}\n\nPeriod: ${p.periodLabel}\nTotal: $${settlement.totalAmount.toFixed(4)} ${settlement.currency}\nTotal accesses: ${settlement.totalAccesses}\nUnique sources: ${settlement.uniqueSources}\nUnique payers: ${settlement.uniquePayers}\nMerkle root: ${settlement.merkleRoot.slice(0, 16)}...\nVerification: ${verification.valid ? '✅ VALID' : '❌ INVALID'}\n\nLine items:\n${lines.join('\n')}` }] };
|
|
3146
|
+
});
|
|
3147
|
+
server.tool("generate_compliance_report", "Generate a GDPR Article 30 / EU AI Act Article 10 / SOC 2 compliance report.", {
|
|
3148
|
+
reportType: z.enum(["gdpr_article30", "euai_article10", "soc2_data", "general"]).describe("Report type"),
|
|
3149
|
+
startDate: z.string().describe("Period start"),
|
|
3150
|
+
endDate: z.string().describe("Period end"),
|
|
3151
|
+
periodLabel: z.string().describe("Label"),
|
|
3152
|
+
agentId: z.string().optional().describe("Filter by agent"),
|
|
3153
|
+
principalId: z.string().optional().describe("Filter by principal"),
|
|
3154
|
+
}, async (p) => {
|
|
3155
|
+
const kp = generateKeyPair();
|
|
3156
|
+
const report = generateDataComplianceReport(state.contributionLedger, { startDate: p.startDate, endDate: p.endDate, periodLabel: p.periodLabel }, p.reportType, kp.privateKey, { agentId: p.agentId, principalId: p.principalId });
|
|
3157
|
+
return { content: [{ type: "text", text: `📋 Compliance Report: ${report.reportId}\n\nType: ${p.reportType}\nPeriod: ${p.periodLabel}\nTotal data accesses: ${report.summary.totalDataAccesses}\nUnique data sources: ${report.summary.uniqueDataSources}\nPurpose breakdown: ${JSON.stringify(report.summary.purposeBreakdown)}\nCompensation: $${report.summary.compensationSummary.total.toFixed(4)} (pending: $${report.summary.compensationSummary.pending.toFixed(4)})\nTerms violations: ${report.summary.termsViolations}\nAdvisory warnings: ${report.summary.advisoryWarnings}\nSigned: ✅` }] };
|
|
3158
|
+
});
|
|
3159
|
+
server.tool("record_training_use", "Record that agent output derived from data sources was used for training/fine-tuning/embedding. Creates a signed training attribution receipt.", {
|
|
3160
|
+
trainingUseType: z.enum(["fine_tune", "lora_adapter", "embedding", "rag_index", "distillation", "evaluation", "synthetic_data"]).describe("Type of training use"),
|
|
3161
|
+
modelId: z.string().describe("Model being trained"),
|
|
3162
|
+
sourceAccessReceiptIds: z.array(z.string()).describe("Access receipt IDs of source data used"),
|
|
3163
|
+
outputContentHash: z.string().describe("SHA-256 of the output used for training"),
|
|
3164
|
+
contributionWeights: z.record(z.number()).optional().describe("Fractional weights per source (sum to 1.0)"),
|
|
3165
|
+
datasetSize: z.number().optional().describe("Number of training examples"),
|
|
3166
|
+
}, async (p) => {
|
|
3167
|
+
if (!state.agentKey || !state.privateKey)
|
|
3168
|
+
return { content: [{ type: "text", text: "❌ Not identified." }] };
|
|
3169
|
+
const receipt = createTrainingAttribution({
|
|
3170
|
+
trainingUseType: p.trainingUseType,
|
|
3171
|
+
modelId: p.modelId,
|
|
3172
|
+
trainerId: state.agentId || 'unknown',
|
|
3173
|
+
trainerPublicKey: state.agentKey,
|
|
3174
|
+
trainerPrivateKey: state.privateKey,
|
|
3175
|
+
sourceAccessReceiptIds: p.sourceAccessReceiptIds,
|
|
3176
|
+
executionFrameId: 'frame_train_' + Date.now().toString(36),
|
|
3177
|
+
outputContentHash: p.outputContentHash,
|
|
3178
|
+
inputDataHashes: p.sourceAccessReceiptIds.map(id => id), // simplified
|
|
3179
|
+
contributionWeights: p.contributionWeights,
|
|
3180
|
+
datasetSize: p.datasetSize,
|
|
3181
|
+
});
|
|
3182
|
+
recordTrainingAttribution(state.trainingLedger, receipt);
|
|
3183
|
+
const v = verifyTrainingAttribution(receipt);
|
|
3184
|
+
return { content: [{ type: "text", text: `✅ Training attribution recorded.\n\nReceipt: ${receipt.trainingReceiptId}\nType: ${p.trainingUseType}\nModel: ${p.modelId}\nSources: ${p.sourceAccessReceiptIds.length}\nDataset size: ${p.datasetSize || 'N/A'}\nWeights: ${p.contributionWeights ? JSON.stringify(p.contributionWeights) : 'equal'}\nVerification: ${v.valid ? '✅' : '❌'}` }] };
|
|
3185
|
+
});
|
|
3186
|
+
server.tool("get_model_data_sources", "Show which data sources contributed to a model's training, with fractional weights.", {
|
|
3187
|
+
modelId: z.string().describe("Model ID to check"),
|
|
3188
|
+
}, async (p) => {
|
|
3189
|
+
const sources = getModelDataSources(state.trainingLedger, p.modelId);
|
|
3190
|
+
if (sources.length === 0)
|
|
3191
|
+
return { content: [{ type: "text", text: "No training data found for this model." }] };
|
|
3192
|
+
const lines = sources.map(s => `• ${s.accessReceiptId}: weight ${s.weight.toFixed(4)}, type: ${s.trainingUseType}`);
|
|
3193
|
+
return { content: [{ type: "text", text: `🧠 Model Training Sources: ${p.modelId}\n\n${sources.length} data sources contributed:\n${lines.join('\n')}` }] };
|
|
3194
|
+
});
|
|
3195
|
+
// ═══════════════════════════════════════
|
|
2986
3196
|
// MCP Prompts — Role-Specific
|
|
2987
3197
|
// ═══════════════════════════════════════
|
|
2988
3198
|
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.10.0",
|
|
4
4
|
"mcpName": "io.github.aeoess/agent-passport-mcp",
|
|
5
5
|
"description": "MCP server for Agent Passport System — cryptographic identity, delegation, governance, and deliberation for AI agents",
|
|
6
6
|
"type": "module",
|
|
@@ -48,15 +48,12 @@
|
|
|
48
48
|
},
|
|
49
49
|
"homepage": "https://github.com/aeoess/agent-passport-mcp",
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@modelcontextprotocol/sdk": "1.27.1",
|
|
52
|
-
"agent-passport-system": "^1.
|
|
53
|
-
"zod": "^3.25.
|
|
51
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
52
|
+
"agent-passport-system": "^1.21.1",
|
|
53
|
+
"zod": "^3.25.76"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@types/node": "^
|
|
56
|
+
"@types/node": "^22.19.15",
|
|
57
57
|
"typescript": "^5.9.3"
|
|
58
|
-
},
|
|
59
|
-
"peerDependencies": {
|
|
60
|
-
"zod": "^3.25.0"
|
|
61
58
|
}
|
|
62
59
|
}
|