@peac/mcp-server 0.11.3 → 0.12.0-preview.2
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/dist/cli.cjs +77 -59
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +78 -60
- package/dist/cli.mjs.map +1 -1
- package/dist/handlers/issue.d.ts +2 -2
- package/dist/handlers/issue.d.ts.map +1 -1
- package/dist/handlers/verify.d.ts.map +1 -1
- package/dist/index.cjs +77 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +78 -60
- package/dist/index.mjs.map +1 -1
- package/dist/schemas/issue.d.ts +35 -20
- package/dist/schemas/issue.d.ts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/manifest.json +1 -1
- package/package.json +5 -5
- package/server.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { z } from 'zod';
|
|
|
8
8
|
import { sha256Hex, validateKeypair, base64urlDecode, derivePublicKey, base64urlEncode, decode, sign } from '@peac/crypto';
|
|
9
9
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
10
10
|
import { ERRORS } from '@peac/kernel';
|
|
11
|
-
import { verifyLocal,
|
|
11
|
+
import { verifyLocal, issueWire02, IssueError } from '@peac/protocol';
|
|
12
12
|
import { parseReceiptClaims } from '@peac/schema';
|
|
13
13
|
import * as nodePath from 'path';
|
|
14
14
|
import { join } from 'path';
|
|
@@ -1150,16 +1150,15 @@ async function handleVerify(params) {
|
|
|
1150
1150
|
const claims = result.claims;
|
|
1151
1151
|
const claimsSummary = {
|
|
1152
1152
|
iss: claims.iss,
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1153
|
+
kind: claims.kind,
|
|
1154
|
+
type: claims.type,
|
|
1155
|
+
jti: claims.jti,
|
|
1156
|
+
...claims.sub !== void 0 && { sub: claims.sub },
|
|
1157
|
+
variant: result.variant,
|
|
1158
|
+
wireVersion: result.wireVersion
|
|
1156
1159
|
};
|
|
1157
|
-
if (result.variant === "commerce") {
|
|
1158
|
-
claimsSummary.amt = claims.amt;
|
|
1159
|
-
claimsSummary.cur = claims.cur;
|
|
1160
|
-
}
|
|
1161
1160
|
const tr = truncateResponse(
|
|
1162
|
-
`Verification PASSED (${result.variant} receipt, kid=${result.kid})`,
|
|
1161
|
+
`Verification PASSED (${result.variant} receipt, kind=${claims.kind ?? "unknown"}, kid=${result.kid})`,
|
|
1163
1162
|
policy
|
|
1164
1163
|
);
|
|
1165
1164
|
return {
|
|
@@ -1392,49 +1391,44 @@ async function handleIssue(params) {
|
|
|
1392
1391
|
isError: true
|
|
1393
1392
|
};
|
|
1394
1393
|
}
|
|
1395
|
-
if (input.ttl_seconds !== void 0 && input.ttl_seconds > policy.limits.max_ttl_seconds) {
|
|
1396
|
-
return {
|
|
1397
|
-
text: `Input rejected: ttl_seconds ${input.ttl_seconds} exceeds max_ttl_seconds ${policy.limits.max_ttl_seconds}`,
|
|
1398
|
-
structured: {
|
|
1399
|
-
ok: false,
|
|
1400
|
-
code: "E_MCP_INVALID_INPUT",
|
|
1401
|
-
message: `ttl_seconds ${input.ttl_seconds} exceeds policy max of ${policy.limits.max_ttl_seconds}`
|
|
1402
|
-
},
|
|
1403
|
-
isError: true
|
|
1404
|
-
};
|
|
1405
|
-
}
|
|
1406
1394
|
const keyPatterns = buildKeyPatterns(context.issuerKey.privateKey, context.issuerKey.publicKey);
|
|
1407
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
1408
|
-
const exp = input.ttl_seconds !== void 0 ? now + input.ttl_seconds : void 0;
|
|
1409
1395
|
try {
|
|
1410
|
-
|
|
1396
|
+
if (input.policy && !input.policy.digest) {
|
|
1397
|
+
return {
|
|
1398
|
+
text: "Issue failed: policy.digest is required when policy block is provided",
|
|
1399
|
+
structured: {
|
|
1400
|
+
ok: false,
|
|
1401
|
+
code: "E_MCP_ISSUE_FAILED",
|
|
1402
|
+
message: "policy.digest is required when policy block is provided (uri/version alone is insufficient for binding)"
|
|
1403
|
+
},
|
|
1404
|
+
isError: true
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
const policyBlock = input.policy?.digest ? { digest: input.policy.digest, uri: input.policy.uri, version: input.policy.version } : void 0;
|
|
1408
|
+
const result = await issueWire02({
|
|
1411
1409
|
iss: context.issuerId,
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
network: input.network,
|
|
1420
|
-
evidence: input.evidence,
|
|
1421
|
-
subject: input.subject,
|
|
1422
|
-
exp,
|
|
1410
|
+
kind: input.kind,
|
|
1411
|
+
type: input.type,
|
|
1412
|
+
sub: input.sub,
|
|
1413
|
+
pillars: input.pillars,
|
|
1414
|
+
occurred_at: input.occurred_at,
|
|
1415
|
+
extensions: input.extensions,
|
|
1416
|
+
policy: policyBlock,
|
|
1423
1417
|
privateKey: context.issuerKey.privateKey,
|
|
1424
1418
|
kid: context.issuerKey.kid
|
|
1425
1419
|
});
|
|
1426
1420
|
const { payload } = decode(result.jws);
|
|
1427
1421
|
const claimsSummary = {
|
|
1428
1422
|
iss: payload.iss,
|
|
1429
|
-
|
|
1423
|
+
kind: payload.kind,
|
|
1424
|
+
type: payload.type,
|
|
1430
1425
|
iat: payload.iat,
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
cur: payload.cur
|
|
1426
|
+
jti: payload.jti,
|
|
1427
|
+
...payload.sub !== void 0 ? { sub: payload.sub } : {},
|
|
1428
|
+
...payload.pillars !== void 0 ? { pillars: payload.pillars } : {}
|
|
1435
1429
|
};
|
|
1436
1430
|
const tr = truncateResponse(
|
|
1437
|
-
`Receipt issued:
|
|
1431
|
+
`Receipt issued: jti=${claimsSummary.jti}, kind=${claimsSummary.kind}, type=${claimsSummary.type}`,
|
|
1438
1432
|
policy
|
|
1439
1433
|
);
|
|
1440
1434
|
const safeText = sanitizeOutput(tr.text, keyPatterns);
|
|
@@ -1858,18 +1852,41 @@ var DecodeOutputSchema = z.object({
|
|
|
1858
1852
|
verified: z.literal(false)
|
|
1859
1853
|
});
|
|
1860
1854
|
var IssueInputSchema = z.object({
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1855
|
+
kind: z.enum(["evidence", "challenge"]).describe("Structural kind: evidence (records interaction) or challenge (requests action)"),
|
|
1856
|
+
type: z.string().min(1).max(256).refine(
|
|
1857
|
+
(v) => /^https?:\/\//.test(v) || /^[a-zA-Z0-9][a-zA-Z0-9._-]*\.[a-zA-Z0-9._-]+\/[a-zA-Z0-9]/.test(v),
|
|
1858
|
+
{
|
|
1859
|
+
message: "type must be reverse-DNS (e.g. org.peacprotocol/payment) or absolute URI (https://...)"
|
|
1860
|
+
}
|
|
1861
|
+
).describe("Semantic type in reverse-DNS or absolute URI form (e.g. org.peacprotocol/payment)"),
|
|
1862
|
+
sub: z.string().max(2048).optional().describe("Subject identifier (resource or interaction target)"),
|
|
1863
|
+
pillars: z.array(
|
|
1864
|
+
z.enum([
|
|
1865
|
+
"access",
|
|
1866
|
+
"attribution",
|
|
1867
|
+
"commerce",
|
|
1868
|
+
"compliance",
|
|
1869
|
+
"consent",
|
|
1870
|
+
"identity",
|
|
1871
|
+
"privacy",
|
|
1872
|
+
"provenance",
|
|
1873
|
+
"purpose",
|
|
1874
|
+
"safety"
|
|
1875
|
+
])
|
|
1876
|
+
).optional().refine(
|
|
1877
|
+
(arr) => !arr || new Set(arr).size === arr.length && [...arr].sort().every((v, i) => v === arr[i]),
|
|
1878
|
+
{ message: "pillars must be unique and sorted ascending" }
|
|
1879
|
+
).describe("Evidence pillars from closed 10-value taxonomy (sorted ascending)"),
|
|
1880
|
+
occurred_at: z.string().optional().refine((v) => !v || !isNaN(Date.parse(v)), {
|
|
1881
|
+
message: "occurred_at must be a valid ISO 8601 timestamp"
|
|
1882
|
+
}).describe("ISO 8601 timestamp when interaction occurred (evidence kind only)"),
|
|
1883
|
+
extensions: z.record(z.string(), z.unknown()).optional().describe("Extension groups keyed by reverse-DNS identifier"),
|
|
1884
|
+
policy: z.object({
|
|
1885
|
+
uri: z.string().url().max(2048).refine((v) => v.startsWith("https://"), { message: "policy.uri must use HTTPS" }).describe("Policy document URI (HTTPS only)"),
|
|
1886
|
+
version: z.string().max(256).optional().describe("Policy version"),
|
|
1887
|
+
digest: z.string().regex(/^sha256:[0-9a-f]{64}$/).optional().describe("Policy digest in sha256:<64 hex> format")
|
|
1888
|
+
}).optional().describe("Policy binding block"),
|
|
1889
|
+
ttl_seconds: z.number().int().positive().optional().describe("Reserved for future use (Wire 0.2 receipts do not expire)")
|
|
1873
1890
|
});
|
|
1874
1891
|
var MetaSchema4 = z.object({
|
|
1875
1892
|
serverVersion: z.string(),
|
|
@@ -1878,12 +1895,12 @@ var MetaSchema4 = z.object({
|
|
|
1878
1895
|
});
|
|
1879
1896
|
var ClaimsSummarySchema = z.object({
|
|
1880
1897
|
iss: z.string(),
|
|
1881
|
-
|
|
1898
|
+
kind: z.string(),
|
|
1899
|
+
type: z.string(),
|
|
1882
1900
|
iat: z.number(),
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
cur: z.string()
|
|
1901
|
+
jti: z.string(),
|
|
1902
|
+
sub: z.string().optional(),
|
|
1903
|
+
pillars: z.array(z.string()).optional()
|
|
1887
1904
|
});
|
|
1888
1905
|
var IssueOutputSchema = z.object({
|
|
1889
1906
|
_meta: MetaSchema4,
|
|
@@ -1919,7 +1936,8 @@ function makeMeta(ctx, serverName) {
|
|
|
1919
1936
|
serverName,
|
|
1920
1937
|
serverVersion: ctx.version,
|
|
1921
1938
|
policyHash: ctx.policyHash,
|
|
1922
|
-
protocolVersion: ctx.protocolVersion
|
|
1939
|
+
protocolVersion: ctx.protocolVersion,
|
|
1940
|
+
wireFormatVersion: "0.2"
|
|
1923
1941
|
};
|
|
1924
1942
|
}
|
|
1925
1943
|
function handlerResultToCallToolResult(result, meta) {
|
|
@@ -2111,8 +2129,8 @@ function createPeacMcpServer(options) {
|
|
|
2111
2129
|
register(
|
|
2112
2130
|
"peac_issue",
|
|
2113
2131
|
{
|
|
2114
|
-
title: "Issue PEAC Receipt",
|
|
2115
|
-
description: "Sign and return a
|
|
2132
|
+
title: "Issue Wire 0.2 PEAC Receipt",
|
|
2133
|
+
description: "Sign and return a Wire 0.2 PEAC receipt JWS. Accepts kind, type, pillars, extensions, and policy fields. Wire 0.2 only: Wire 0.1 fields are not accepted. Requires server configured with an Ed25519 issuer key (--issuer-key and --issuer-id).",
|
|
2116
2134
|
inputSchema: IssueInputSchema,
|
|
2117
2135
|
outputSchema: IssueOutputSchema,
|
|
2118
2136
|
annotations: ISSUE_TOOL_ANNOTATIONS
|