@atrib/verify-mcp 0.2.21 → 1.0.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 +12 -0
- package/dist/index.d.ts +2 -54
- package/dist/index.js +10 -150
- package/dist/main.js +5 -3
- package/package.json +4 -5
package/README.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atrib/verify-mcp
|
|
2
2
|
|
|
3
|
+
**Legacy home.** The read-verb implementation moved to
|
|
4
|
+
[`@atrib/recall`](../atrib-recall/README.md) per the attest/recall rename
|
|
5
|
+
([D164](../../DECISIONS.md#d164-attestrecall-verb-rename-and-primitive-surface-collapse)).
|
|
6
|
+
`atrib-verify` folds into `recall` through its `verification` parameter.
|
|
7
|
+
This package re-exports the same surface and forwards the `atrib-verify`
|
|
8
|
+
binary to `@atrib/recall`'s handlers. Results are JSON-identical. The
|
|
9
|
+
`atrib-verify` tool name stays mounted as a permanent alias during the
|
|
10
|
+
alias window, alongside the new `recall` tool. `@atrib/verify` (the
|
|
11
|
+
verifier library) is NOT renamed. This package keeps a hard dependency on
|
|
12
|
+
`@atrib/verify` so the verifier always resolves, independent of
|
|
13
|
+
`@atrib/recall`'s optional-peer posture toward it.
|
|
14
|
+
|
|
3
15
|
MCP server exposing the `atrib-verify` cognitive primitive for atrib's verifiable action layer. It verifies counterparty handoff evidence before a receiving agent signs follow-up work that cites those records through `informed_by`.
|
|
4
16
|
|
|
5
17
|
The package is read-only. It accepts caller-supplied evidence, returns accepted and rejected hashes, and leaves the follow-up signing step to `atrib-emit` or normal wrapped tool calls.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,54 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Exposes the seventh atrib cognitive primitive: verify counterparty handoff
|
|
5
|
-
* evidence before the receiving agent signs a follow-up that cites it through
|
|
6
|
-
* informed_by. The server is deliberately thin. @atrib/verify owns the actual
|
|
7
|
-
* cryptographic checks, packet extraction, and rejection reasons.
|
|
8
|
-
*/
|
|
9
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
10
|
-
import { z } from 'zod';
|
|
11
|
-
import { type HandoffClaimVerification } from '@atrib/verify';
|
|
12
|
-
declare const VerifyInput: z.ZodObject<{
|
|
13
|
-
packet: z.ZodOptional<z.ZodUnknown>;
|
|
14
|
-
records: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
15
|
-
claims: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
16
|
-
required_record_hashes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
17
|
-
trusted_creator_keys: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
18
|
-
allowed_context_ids: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
19
|
-
require_body: z.ZodOptional<z.ZodBoolean>;
|
|
20
|
-
require_body_commitment: z.ZodOptional<z.ZodBoolean>;
|
|
21
|
-
require_log_inclusion: z.ZodOptional<z.ZodBoolean>;
|
|
22
|
-
log_public_key_b64: z.ZodOptional<z.ZodString>;
|
|
23
|
-
now_ms: z.ZodOptional<z.ZodNumber>;
|
|
24
|
-
max_age_ms: z.ZodOptional<z.ZodNumber>;
|
|
25
|
-
}, z.core.$strip>;
|
|
26
|
-
export type AtribVerifyInput = z.infer<typeof VerifyInput>;
|
|
27
|
-
export interface AtribVerifyServer {
|
|
28
|
-
mcp: McpServer;
|
|
29
|
-
}
|
|
30
|
-
export interface AtribVerifyOutput {
|
|
31
|
-
primitive: 'atrib-verify';
|
|
32
|
-
all_accepted: boolean;
|
|
33
|
-
accepted_record_hashes: string[];
|
|
34
|
-
accepted: CompactHandoffClaim[];
|
|
35
|
-
rejected: CompactHandoffClaim[];
|
|
36
|
-
}
|
|
37
|
-
interface CompactHandoffClaim {
|
|
38
|
-
record_hash: string;
|
|
39
|
-
accepted: boolean;
|
|
40
|
-
rejection_reasons: string[];
|
|
41
|
-
warnings: string[];
|
|
42
|
-
signature_ok: boolean | null;
|
|
43
|
-
computed_record_hash: string | null;
|
|
44
|
-
signer_trusted: boolean | null;
|
|
45
|
-
context_allowed: boolean | null;
|
|
46
|
-
record_context_id?: string;
|
|
47
|
-
record_creator_key?: string;
|
|
48
|
-
record_timestamp?: number;
|
|
49
|
-
body?: HandoffClaimVerification['body'];
|
|
50
|
-
proof?: HandoffClaimVerification['proof'];
|
|
51
|
-
}
|
|
52
|
-
export declare function handleAtribVerify(input: AtribVerifyInput): Promise<AtribVerifyOutput>;
|
|
53
|
-
export declare function createAtribVerifyServer(): Promise<AtribVerifyServer>;
|
|
54
|
-
export {};
|
|
1
|
+
export { createAtribVerifyServer, handleAtribVerify, registerVerifyTool, tryHandleAtribVerify, VerifyInput, } from '@atrib/recall';
|
|
2
|
+
export type { AtribVerifyInput, AtribVerifyOutput, AtribVerifyServer, RecallVerificationBlock, } from '@atrib/recall';
|
package/dist/index.js
CHANGED
|
@@ -1,151 +1,11 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import { extractRecordHashesFromMcpResult, logReadPrimitiveCall, SHA256_REF_PATTERN, } from '@atrib/mcp';
|
|
13
|
-
import { handoffClaimsFromEvidencePacket, verifyHandoffClaims, } from '@atrib/verify';
|
|
14
|
-
const HEX_32_PATTERN = /^[0-9a-f]{32}$/;
|
|
15
|
-
const VerifyInput = z.object({
|
|
16
|
-
packet: z
|
|
17
|
-
.unknown()
|
|
18
|
-
.optional()
|
|
19
|
-
.describe('Private continuation or handoff packet carrying records, proof bundles, local mirror sidecars, and optional trust policy.'),
|
|
20
|
-
records: z
|
|
21
|
-
.array(z.unknown())
|
|
22
|
-
.optional()
|
|
23
|
-
.describe('Evidence entries, usually parsed D062 local mirror envelopes or packet records. Used when packet is omitted.'),
|
|
24
|
-
claims: z
|
|
25
|
-
.array(z.unknown())
|
|
26
|
-
.optional()
|
|
27
|
-
.describe('Alias for records. Each entry can be a bare AtribRecord or an envelope with record, proof, and _local sidecar.'),
|
|
28
|
-
required_record_hashes: z
|
|
29
|
-
.array(z.string().regex(SHA256_REF_PATTERN))
|
|
30
|
-
.optional()
|
|
31
|
-
.describe('Record hashes the receiving agent expected. Missing entries are preserved as verifier rejections.'),
|
|
32
|
-
trusted_creator_keys: z
|
|
33
|
-
.array(z.string().min(1))
|
|
34
|
-
.optional()
|
|
35
|
-
.describe('Allowed creator_key values for upstream records. When set, records from other signers are rejected.'),
|
|
36
|
-
allowed_context_ids: z
|
|
37
|
-
.array(z.string().regex(HEX_32_PATTERN))
|
|
38
|
-
.optional()
|
|
39
|
-
.describe('Allowed upstream context_id values. When set, records from other contexts are rejected.'),
|
|
40
|
-
require_body: z
|
|
41
|
-
.boolean()
|
|
42
|
-
.optional()
|
|
43
|
-
.describe('Require private body material from body, args/result, or D062 _local content.'),
|
|
44
|
-
require_body_commitment: z
|
|
45
|
-
.boolean()
|
|
46
|
-
.optional()
|
|
47
|
-
.describe('Require args_hash or result_hash on the signed record so private body material can be checked.'),
|
|
48
|
-
require_log_inclusion: z
|
|
49
|
-
.boolean()
|
|
50
|
-
.optional()
|
|
51
|
-
.describe('Require a supplied proof bundle whose inclusion path verifies against the checkpoint root.'),
|
|
52
|
-
log_public_key_b64: z
|
|
53
|
-
.string()
|
|
54
|
-
.optional()
|
|
55
|
-
.describe('Optional trusted log Ed25519 public key, base64 or base64url encoded. When supplied, checkpoint signatures are verified.'),
|
|
56
|
-
now_ms: z
|
|
57
|
-
.number()
|
|
58
|
-
.optional()
|
|
59
|
-
.describe('Verifier wall-clock override in milliseconds. Mostly for deterministic tests.'),
|
|
60
|
-
max_age_ms: z
|
|
61
|
-
.number()
|
|
62
|
-
.optional()
|
|
63
|
-
.describe('Freshness window. Records older than this, or dated in the future, are rejected as stale.'),
|
|
64
|
-
});
|
|
65
|
-
function decodeLogPublicKey(value) {
|
|
66
|
-
if (!value)
|
|
67
|
-
return undefined;
|
|
68
|
-
const normalized = value.replace(/-/g, '+').replace(/_/g, '/');
|
|
69
|
-
const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, '=');
|
|
70
|
-
const decoded = new Uint8Array(Buffer.from(padded, 'base64'));
|
|
71
|
-
if (decoded.length !== 32) {
|
|
72
|
-
throw new Error(`log_public_key_b64 must decode to 32 bytes, got ${decoded.length}`);
|
|
73
|
-
}
|
|
74
|
-
return decoded;
|
|
75
|
-
}
|
|
76
|
-
function packetFromInput(input) {
|
|
77
|
-
if (input.packet !== undefined)
|
|
78
|
-
return input.packet;
|
|
79
|
-
return {
|
|
80
|
-
records: (input.records ?? input.claims ?? []),
|
|
81
|
-
required_record_hashes: input.required_record_hashes,
|
|
82
|
-
trusted_creator_keys: input.trusted_creator_keys,
|
|
83
|
-
allowed_context_ids: input.allowed_context_ids,
|
|
84
|
-
max_age_ms: input.max_age_ms,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
function compactClaim(claim) {
|
|
88
|
-
const out = {
|
|
89
|
-
record_hash: claim.record_hash,
|
|
90
|
-
accepted: claim.accepted,
|
|
91
|
-
rejection_reasons: claim.rejection_reasons,
|
|
92
|
-
warnings: claim.warnings,
|
|
93
|
-
signature_ok: claim.signature_ok,
|
|
94
|
-
computed_record_hash: claim.computed_record_hash,
|
|
95
|
-
signer_trusted: claim.signer_trusted,
|
|
96
|
-
context_allowed: claim.context_allowed,
|
|
97
|
-
};
|
|
98
|
-
if (claim.record) {
|
|
99
|
-
out.record_context_id = claim.record.context_id;
|
|
100
|
-
out.record_creator_key = claim.record.creator_key;
|
|
101
|
-
out.record_timestamp = claim.record.timestamp;
|
|
102
|
-
}
|
|
103
|
-
if (claim.body)
|
|
104
|
-
out.body = claim.body;
|
|
105
|
-
if (claim.proof)
|
|
106
|
-
out.proof = claim.proof;
|
|
107
|
-
return out;
|
|
108
|
-
}
|
|
109
|
-
function compactResult(result) {
|
|
110
|
-
return {
|
|
111
|
-
primitive: 'atrib-verify',
|
|
112
|
-
all_accepted: result.all_accepted,
|
|
113
|
-
accepted_record_hashes: result.accepted_record_hashes,
|
|
114
|
-
accepted: result.accepted.map(compactClaim),
|
|
115
|
-
rejected: result.rejected.map(compactClaim),
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
export async function handleAtribVerify(input) {
|
|
119
|
-
const packet = packetFromInput(input);
|
|
120
|
-
const claims = handoffClaimsFromEvidencePacket(packet, {
|
|
121
|
-
required_record_hashes: input.required_record_hashes,
|
|
122
|
-
trusted_creator_keys: input.trusted_creator_keys,
|
|
123
|
-
allowed_context_ids: input.allowed_context_ids,
|
|
124
|
-
max_age_ms: input.max_age_ms,
|
|
125
|
-
});
|
|
126
|
-
const result = await verifyHandoffClaims(claims, {
|
|
127
|
-
trusted_creator_keys: input.trusted_creator_keys,
|
|
128
|
-
allowed_context_ids: input.allowed_context_ids,
|
|
129
|
-
require_body: input.require_body === true,
|
|
130
|
-
require_body_commitment: input.require_body_commitment === true,
|
|
131
|
-
require_log_inclusion: input.require_log_inclusion === true,
|
|
132
|
-
log_public_key: decodeLogPublicKey(input.log_public_key_b64),
|
|
133
|
-
now_ms: input.now_ms,
|
|
134
|
-
max_age_ms: input.max_age_ms,
|
|
135
|
-
});
|
|
136
|
-
return compactResult(result);
|
|
137
|
-
}
|
|
138
|
-
export async function createAtribVerifyServer() {
|
|
139
|
-
const mcp = new McpServer({ name: 'atrib-verify', version: '0.1.0' });
|
|
140
|
-
mcp.registerTool('atrib-verify', {
|
|
141
|
-
description: 'Verify counterparty handoff evidence before linking follow-up work through informed_by.',
|
|
142
|
-
inputSchema: VerifyInput.shape,
|
|
143
|
-
}, async (rawInput) => logReadPrimitiveCall('atrib-verify', rawInput, async () => {
|
|
144
|
-
const input = VerifyInput.parse(rawInput);
|
|
145
|
-
const result = await handleAtribVerify(input);
|
|
146
|
-
return {
|
|
147
|
-
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
148
|
-
};
|
|
149
|
-
}, extractRecordHashesFromMcpResult));
|
|
150
|
-
return { mcp };
|
|
151
|
-
}
|
|
2
|
+
// @atrib/verify-mcp is the legacy home of the atrib-verify read primitive
|
|
3
|
+
// (cognitive primitive #7 of D079/D106). The implementation lives in
|
|
4
|
+
// @atrib/recall per the attest/recall rename: handoff verification folds
|
|
5
|
+
// into the `recall` verb's `verification` parameter, and the atrib-verify
|
|
6
|
+
// tool name stays mounted as a permanent alias over the same handler. This
|
|
7
|
+
// package re-exports the surface so existing imports keep working, and its
|
|
8
|
+
// hard dependency on @atrib/verify guarantees the verifier peer resolves
|
|
9
|
+
// for every consumer of this package (@atrib/recall alone treats it as an
|
|
10
|
+
// optional peer).
|
|
11
|
+
export { createAtribVerifyServer, handleAtribVerify, registerVerifyTool, tryHandleAtribVerify, VerifyInput, } from '@atrib/recall';
|
package/dist/main.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
//
|
|
2
|
+
// atrib-verify standalone binary (forwarding shim). Serves the legacy
|
|
3
|
+
// atrib-verify server, which mounts `atrib-verify` plus the `recall` verb
|
|
4
|
+
// per the alias-window rule W1.
|
|
3
5
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
-
import { createAtribVerifyServer } from '
|
|
6
|
+
import { createAtribVerifyServer } from '@atrib/recall';
|
|
5
7
|
async function main() {
|
|
6
8
|
const { mcp } = await createAtribVerifyServer();
|
|
7
9
|
const transport = new StdioServerTransport();
|
|
8
10
|
await mcp.connect(transport);
|
|
9
11
|
}
|
|
10
12
|
main().catch((e) => {
|
|
11
|
-
console.error('atrib-verify: fatal', e instanceof Error ?
|
|
13
|
+
console.error('atrib-verify: fatal', e instanceof Error ? e.stack ?? e.message : String(e));
|
|
12
14
|
process.exit(1);
|
|
13
15
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atrib/verify-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Legacy home of atrib's handoff-verification read primitive. Superseded by @atrib/recall (the read verb, verification parameter); this package re-exports the same surface, forwards the atrib-verify binary, and keeps a hard dependency on the @atrib/verify library so the verifier always resolves.",
|
|
5
5
|
"author": "atrib <hello@atrib.dev>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"atrib",
|
|
@@ -24,9 +24,8 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
27
|
-
"
|
|
28
|
-
"@atrib/
|
|
29
|
-
"@atrib/verify": "0.8.3"
|
|
27
|
+
"@atrib/recall": "1.0.0",
|
|
28
|
+
"@atrib/verify": "0.9.0"
|
|
30
29
|
},
|
|
31
30
|
"devDependencies": {
|
|
32
31
|
"@noble/ed25519": "^3.1.0",
|