@agentpress/sdk 0.2.114 → 0.3.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 +221 -18
- package/dist/index.cjs +256 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +177 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +177 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +253 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
package/dist/index.d.mts
CHANGED
|
@@ -11,11 +11,106 @@ interface AgentPressOptions {
|
|
|
11
11
|
timeout?: number;
|
|
12
12
|
/** Organization identifier sent with requests. @default "default-org" */
|
|
13
13
|
org?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Partner MCP Spec v1 configuration. Required only if you call
|
|
16
|
+
* {@link PartnersClient.verifyToken} or {@link WebhooksClient.verifyKeyRotation}.
|
|
17
|
+
*
|
|
18
|
+
* Each environment (staging / production) needs its own {@link AgentPress}
|
|
19
|
+
* instance with its own `partnerMcp` block — never share a client between
|
|
20
|
+
* environments. JWKS cache state is per-instance, so side-by-side staging
|
|
21
|
+
* and prod clients have no cross-talk.
|
|
22
|
+
*/
|
|
23
|
+
partnerMcp?: PartnerMcpOptions;
|
|
14
24
|
/** Hook called before every outbound HTTP request (useful for logging/tracing). */
|
|
15
25
|
onRequest?: (url: string, init: RequestInit) => void;
|
|
16
26
|
/** Hook called after every HTTP response is received. */
|
|
17
27
|
onResponse?: (url: string, response: Response) => void;
|
|
18
28
|
}
|
|
29
|
+
/** Partner MCP Spec v1 configuration. See {@link AgentPressOptions.partnerMcp}. */
|
|
30
|
+
interface PartnerMcpOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Full URL to the issuing AgentPress org's JWKS.
|
|
33
|
+
* Per-org as of Partner MCP Spec v1 (per-org signing keys), e.g.
|
|
34
|
+
* `https://api.agent.press/orgs/<org-slug>/.well-known/jwks.json`.
|
|
35
|
+
* The org admin who registered you as a partner will give you the
|
|
36
|
+
* exact URL along with their `<org-slug>`.
|
|
37
|
+
*/
|
|
38
|
+
jwksUrl: string;
|
|
39
|
+
/**
|
|
40
|
+
* Exact match for the JWT `iss` claim. Per-org scoped, e.g.
|
|
41
|
+
* `https://api.agent.press/orgs/<org-slug>`. The JWKS URL above is
|
|
42
|
+
* always `<issuer>/.well-known/jwks.json`.
|
|
43
|
+
*/
|
|
44
|
+
issuer: string;
|
|
45
|
+
/** Exact match for the JWT `aud` claim — your partner MCP's stable URL. */
|
|
46
|
+
audience: string;
|
|
47
|
+
/** Required value for the `ext_provider` claim, e.g. `"localfalcon"`. */
|
|
48
|
+
expectedExtProvider: string;
|
|
49
|
+
/**
|
|
50
|
+
* Clock skew tolerance for `iat` / `exp` validation. Accepts a jose duration
|
|
51
|
+
* string (`"30s"`, `"1m"`) or a number of seconds.
|
|
52
|
+
* @default "30s"
|
|
53
|
+
*/
|
|
54
|
+
clockTolerance?: string | number;
|
|
55
|
+
/**
|
|
56
|
+
* JWKS cache max age in milliseconds. Cache is per-instance, not module-global.
|
|
57
|
+
* @default 3_600_000 (1 hour)
|
|
58
|
+
*/
|
|
59
|
+
jwksCacheMaxAgeMs?: number;
|
|
60
|
+
}
|
|
61
|
+
/** A verified Partner MCP Spec v1 JWT claim set. */
|
|
62
|
+
interface PartnerTokenClaims {
|
|
63
|
+
/** The external user id (verified non-empty). */
|
|
64
|
+
sub: string;
|
|
65
|
+
/** Space-separated scope string, per RFC 8693. May be empty but always present. */
|
|
66
|
+
scope: string;
|
|
67
|
+
/** External auth provider name; verified against {@link PartnerMcpOptions.expectedExtProvider}. */
|
|
68
|
+
ext_provider: string;
|
|
69
|
+
/** Unique token id. Non-empty. Partners build replay caches keyed by this. */
|
|
70
|
+
jti: string;
|
|
71
|
+
/** Already validated against {@link PartnerMcpOptions.issuer}; returned for audit logs. */
|
|
72
|
+
iss: string;
|
|
73
|
+
/** Already validated against {@link PartnerMcpOptions.audience}; returned for audit logs. */
|
|
74
|
+
aud: string;
|
|
75
|
+
/** Unix seconds. */
|
|
76
|
+
iat: number;
|
|
77
|
+
/** Unix seconds. */
|
|
78
|
+
exp: number;
|
|
79
|
+
/** AgentPress org identifier, optional. */
|
|
80
|
+
org_id?: string;
|
|
81
|
+
/** AgentPress thread identifier, optional. */
|
|
82
|
+
thread_id?: string;
|
|
83
|
+
/** Reserved for multi-tenant partner flows. */
|
|
84
|
+
settings_id?: string;
|
|
85
|
+
/** Forward-compat: any additional claims pass through. */
|
|
86
|
+
[key: string]: unknown;
|
|
87
|
+
}
|
|
88
|
+
/** Parameters for {@link WebhooksClient.verifyKeyRotation}. */
|
|
89
|
+
interface KeyRotationVerifyParams {
|
|
90
|
+
/** Raw request body (string or Buffer) — must not be parsed/modified. */
|
|
91
|
+
payload: string | Buffer;
|
|
92
|
+
/**
|
|
93
|
+
* Incoming HTTP headers. Accepts plain `Record<string, string | undefined>`
|
|
94
|
+
* so Hono / Fastify / Express / Fetch / Worker all work interchangeably.
|
|
95
|
+
* Must include `x-agentpress-signature` and `x-agentpress-timestamp`.
|
|
96
|
+
*/
|
|
97
|
+
headers: Record<string, string | undefined>;
|
|
98
|
+
}
|
|
99
|
+
/** A verified `signing_key_rotation` webhook payload. */
|
|
100
|
+
interface KeyRotationEvent {
|
|
101
|
+
event: "signing_key_rotation";
|
|
102
|
+
type: "scheduled" | "emergency";
|
|
103
|
+
retiredKid: string;
|
|
104
|
+
newCurrentKid: string;
|
|
105
|
+
/** ISO 8601 timestamp. */
|
|
106
|
+
retiredAt: string;
|
|
107
|
+
/** ISO 8601 timestamp. */
|
|
108
|
+
effectiveAt: string;
|
|
109
|
+
/** Matches the configured partner JWKS URL. */
|
|
110
|
+
jwksUrl: string;
|
|
111
|
+
/** Present only on `type: "emergency"` rotations. */
|
|
112
|
+
reason?: string;
|
|
113
|
+
}
|
|
19
114
|
/** Parameters for {@link WebhooksClient.send}. */
|
|
20
115
|
interface WebhookSendParams {
|
|
21
116
|
/** Webhook action name (matches an action rule on the server). */
|
|
@@ -219,9 +314,19 @@ interface ResolvedOptions {
|
|
|
219
314
|
org: string;
|
|
220
315
|
webhookSecret?: string;
|
|
221
316
|
apiKey?: string;
|
|
317
|
+
partnerMcp?: ResolvedPartnerMcpOptions;
|
|
222
318
|
onRequest?: AgentPressOptions["onRequest"];
|
|
223
319
|
onResponse?: AgentPressOptions["onResponse"];
|
|
224
320
|
}
|
|
321
|
+
/** @internal Resolved (validated, defaulted) partner MCP options. */
|
|
322
|
+
interface ResolvedPartnerMcpOptions {
|
|
323
|
+
jwksUrl: string;
|
|
324
|
+
issuer: string;
|
|
325
|
+
audience: string;
|
|
326
|
+
expectedExtProvider: string;
|
|
327
|
+
clockTolerance: string | number;
|
|
328
|
+
jwksCacheMaxAgeMs: number;
|
|
329
|
+
}
|
|
225
330
|
//#endregion
|
|
226
331
|
//#region src/http.d.ts
|
|
227
332
|
/**
|
|
@@ -291,6 +396,44 @@ declare class ActionsClient {
|
|
|
291
396
|
private manage;
|
|
292
397
|
}
|
|
293
398
|
//#endregion
|
|
399
|
+
//#region src/partners/client.d.ts
|
|
400
|
+
/**
|
|
401
|
+
* Client for Partner MCP Spec v1 helpers. Created automatically when
|
|
402
|
+
* {@link AgentPressOptions.partnerMcp} is provided.
|
|
403
|
+
*
|
|
404
|
+
* State (JWKS cache) is per-instance, NOT module-global, so staging and
|
|
405
|
+
* production clients can run side-by-side without cross-talk.
|
|
406
|
+
*/
|
|
407
|
+
declare class PartnersClient {
|
|
408
|
+
private readonly options;
|
|
409
|
+
private readonly partnerMcp;
|
|
410
|
+
private jwks;
|
|
411
|
+
private jwksKeyFn;
|
|
412
|
+
constructor(options: ResolvedOptions);
|
|
413
|
+
/**
|
|
414
|
+
* Verify an inbound Partner MCP Spec v1 JWT against AgentPress's JWKS.
|
|
415
|
+
*
|
|
416
|
+
* Enforces the full spec: `algorithms: ["EdDSA"]` pinned; `iss`, `aud`,
|
|
417
|
+
* `ext_provider` validated; `sub`, `jti`, `scope` required and non-empty;
|
|
418
|
+
* `kid` header required; `exp` / `iat` validated with ±30s skew (configurable).
|
|
419
|
+
*
|
|
420
|
+
* @param token - Bare JWT string (no `Bearer ` prefix).
|
|
421
|
+
* @returns Typed {@link PartnerTokenClaims}.
|
|
422
|
+
* @throws {PartnerTokenError} with a typed `reason` for RFC 6750 mapping.
|
|
423
|
+
* @throws {ConfigurationError} if `partnerMcp` is not configured.
|
|
424
|
+
*/
|
|
425
|
+
verifyToken(token: string): Promise<PartnerTokenClaims>;
|
|
426
|
+
/**
|
|
427
|
+
* Force the JWKS cache to refetch immediately. Call this from your
|
|
428
|
+
* `signing_key_rotation` webhook handler after verifying the webhook —
|
|
429
|
+
* otherwise the cache picks up new keys on the next `kid` miss (which
|
|
430
|
+
* works, but with one failed verify latency penalty).
|
|
431
|
+
*/
|
|
432
|
+
refreshJwks(): Promise<void>;
|
|
433
|
+
private requireConfig;
|
|
434
|
+
private getJwks;
|
|
435
|
+
}
|
|
436
|
+
//#endregion
|
|
294
437
|
//#region src/userApprovals/client.d.ts
|
|
295
438
|
/**
|
|
296
439
|
* Client for managing per-user auto-approval rules — the SDK equivalent of the
|
|
@@ -406,6 +549,16 @@ declare class WebhooksClient {
|
|
|
406
549
|
* @throws AgentPressError if payload is not valid JSON
|
|
407
550
|
*/
|
|
408
551
|
constructEvent(params: WebhookVerifyParams): ActionCallbackPayload;
|
|
552
|
+
/**
|
|
553
|
+
* Verify an inbound `signing_key_rotation` webhook (HMAC-SHA256 + timestamp
|
|
554
|
+
* + typed payload) from AgentPress. See the Partner MCP Spec v1 for the
|
|
555
|
+
* full contract.
|
|
556
|
+
*
|
|
557
|
+
* @throws {KeyRotationVerifyError} with a typed `reason` for HTTP mapping
|
|
558
|
+
* (401 for signature errors, 400 for malformed payload, 413 for oversize).
|
|
559
|
+
* @throws {ConfigurationError} if `webhookSecret` is not configured.
|
|
560
|
+
*/
|
|
561
|
+
verifyKeyRotation(params: KeyRotationVerifyParams): KeyRotationEvent;
|
|
409
562
|
}
|
|
410
563
|
//#endregion
|
|
411
564
|
//#region src/client.d.ts
|
|
@@ -431,6 +584,8 @@ declare class AgentPress {
|
|
|
431
584
|
readonly actions: ActionsClient;
|
|
432
585
|
/** Per-user auto-approval rules (read / create / update / delete). */
|
|
433
586
|
readonly userApprovals: UserApprovalsClient;
|
|
587
|
+
/** Partner MCP Spec v1 helpers (inbound JWT verification, JWKS refresh). */
|
|
588
|
+
readonly partners: PartnersClient;
|
|
434
589
|
/**
|
|
435
590
|
* @param options - SDK configuration. All fields are optional with sensible defaults.
|
|
436
591
|
* @throws {ConfigurationError} If `timeout` is non-positive or `webhookSecret` has an invalid prefix.
|
|
@@ -475,6 +630,27 @@ declare class TimeoutError extends AgentPressError {
|
|
|
475
630
|
declare class WebhookSignatureError extends AgentPressError {
|
|
476
631
|
constructor(message: string);
|
|
477
632
|
}
|
|
633
|
+
/** Reason codes for {@link PartnerTokenError}. Maps 1:1 to RFC 6750 `error_description` values. */
|
|
634
|
+
type PartnerTokenErrorReason = "signature_invalid" | "issuer_mismatch" | "audience_mismatch" | "expired" | "not_yet_valid" | "missing_claim" | "ext_provider_mismatch" | "algorithm_not_allowed" | "kid_missing_or_unknown" | "malformed";
|
|
635
|
+
/**
|
|
636
|
+
* Thrown by {@link PartnersClient.verifyToken} when a Partner MCP Spec v1 JWT
|
|
637
|
+
* fails verification. Partners map `reason` to their RFC 6750 `WWW-Authenticate`
|
|
638
|
+
* response (`401 invalid_token` for all reasons in this class).
|
|
639
|
+
*/
|
|
640
|
+
declare class PartnerTokenError extends AgentPressError {
|
|
641
|
+
readonly reason: PartnerTokenErrorReason;
|
|
642
|
+
constructor(reason: PartnerTokenErrorReason, message: string);
|
|
643
|
+
}
|
|
644
|
+
/** Reason codes for {@link KeyRotationVerifyError}. */
|
|
645
|
+
type KeyRotationVerifyErrorReason = "invalid_signature" | "invalid_signature_format" | "timestamp_out_of_window" | "invalid_timestamp" | "payload_too_large" | "malformed_payload";
|
|
646
|
+
/**
|
|
647
|
+
* Thrown by {@link WebhooksClient.verifyKeyRotation} when a `signing_key_rotation`
|
|
648
|
+
* webhook fails HMAC / timestamp / payload validation.
|
|
649
|
+
*/
|
|
650
|
+
declare class KeyRotationVerifyError extends AgentPressError {
|
|
651
|
+
readonly reason: KeyRotationVerifyErrorReason;
|
|
652
|
+
constructor(reason: KeyRotationVerifyErrorReason, message: string);
|
|
653
|
+
}
|
|
478
654
|
//#endregion
|
|
479
|
-
export { type ActionCallbackPayload, type ActionEventType, type ActionManageResponse, type ActionStatus, ActionsClient, AgentPress, AgentPressError, type AgentPressOptions, type AgentResponse, type ApprovalMode, type ApproveActionParams, ConfigurationError, type CreateUserApprovalParams, type DeleteUserApprovalParams, HttpError, type ListUserApprovalsParams, type ListUserApprovalsResponse, type RejectActionParams, type StagedToolCall, TimeoutError, type ToolCallResult, type UpdateUserApprovalParams, UserApprovalsClient, type UserToolApproval, type WebhookResponse, type WebhookSendParams, WebhookSignatureError, type WebhookVerifyParams };
|
|
655
|
+
export { type ActionCallbackPayload, type ActionEventType, type ActionManageResponse, type ActionStatus, ActionsClient, AgentPress, AgentPressError, type AgentPressOptions, type AgentResponse, type ApprovalMode, type ApproveActionParams, ConfigurationError, type CreateUserApprovalParams, type DeleteUserApprovalParams, HttpError, type KeyRotationEvent, KeyRotationVerifyError, type KeyRotationVerifyErrorReason, type KeyRotationVerifyParams, type ListUserApprovalsParams, type ListUserApprovalsResponse, type PartnerMcpOptions, type PartnerTokenClaims, PartnerTokenError, type PartnerTokenErrorReason, PartnersClient, type RejectActionParams, type StagedToolCall, TimeoutError, type ToolCallResult, type UpdateUserApprovalParams, UserApprovalsClient, type UserToolApproval, type WebhookResponse, type WebhookSendParams, WebhookSignatureError, type WebhookVerifyParams, WebhooksClient };
|
|
480
656
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/http.ts","../src/actions/client.ts","../src/userApprovals/client.ts","../src/webhooks/client.ts","../src/client.ts","../src/errors.ts"],"mappings":";;UACiB,iBAAA;EAAiB;EAEhC,aAAA;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/http.ts","../src/actions/client.ts","../src/partners/client.ts","../src/userApprovals/client.ts","../src/webhooks/client.ts","../src/client.ts","../src/errors.ts"],"mappings":";;UACiB,iBAAA;EAAiB;EAEhC,aAAA;EAkBa;EAhBb,MAAA;EAoBqC;EAlBrC,OAAA;EAkB6C;EAhB7C,OAAA;EAJA;EAMA,GAAA;EAFA;;;;;;;;;EAYA,UAAA,GAAa,iBAAA;EAIwB;EAFrC,SAAA,IAAa,GAAA,UAAa,IAAA,EAAM,WAAA;EAEa;EAA7C,UAAA,IAAc,GAAA,UAAa,QAAA,EAAU,QAAA;AAAA;;UAItB,iBAAA;EAAiB;;;;;;;EAQhC,OAAA;EAqBiB;AAInB;;;;EAnBE,MAAA;EAuBA;EArBA,QAAA;EAyBA;EAvBA,mBAAA;EA2BA;;;;;EArBA,cAAA;EAiCC;;;AAIH;EAhCE,iBAAA;AAAA;;UAIe,kBAAA;EA8BG;EA5BlB,GAAA;EAkCS;EAhCT,KAAA;EAgCe;EA9Bf,YAAA;EAkC+B;EAhC/B,GAAA;EAgC+B;EA9B/B,GAAA;EAgCA;EA9BA,GAAA;EAgCA;EA9BA,GAAA;EAkCA;EAhCA,GAAA;EAoCA;EAlCA,MAAA;EAkCM;EAhCN,SAAA;EAoCgC;EAlChC,WAAA;EAsCe;EAAA,CApCd,GAAA;AAAA;;UAIc,uBAAA;EAgCA;EA9Bf,OAAA,WAAkB,MAAA;EAkCgB;;;;;EA5BlC,OAAA,EAAS,MAAA;AAAA;;UAIM,gBAAA;EACf,KAAA;EACA,IAAA;EACA,UAAA;EACA,aAAA;;EAEA,SAAA;EA+BA;EA7BA,WAAA;EAiCA;EA/BA,OAAA;EAiCA;EA/BA,MAAA;AAAA;;UAIe,iBAAA;EAiCU;EA/BzB,MAAA;EA+ByB;EA7BzB,OAAA,EAAS,MAAA;AAAA;;UAIM,mBAAA;EAqCE;EAnCjB,OAAA,WAAkB,MAAA;EAkClB;EAhCA,OAAA;IACE,SAAA;IACA,gBAAA;IACA,gBAAA;EAAA;AAAA;;UAKa,eAAA;EACf,OAAA;EAgCA;EA9BA,QAAA;EAgCE;EA9BF,aAAA;EACA,OAAA;EACA,IAAA,GAAO,MAAA;AAAA;AA0CT;AAAA,KApCY,eAAA;;UASK,cAAA;EACf,QAAA;EACA,UAAA;EACA,SAAA,EAAW,MAAA;AAAA;;UAII,mBAAA;EA8Bf;EA5BA,MAAA;EA6BQ;EA3BR,cAAA;IACE,QAAA;IACA,SAAA,EAAW,MAAA;EAAA;;;;AAyCf;;;;;EA/BE,QAAA;AAAA;;UAIe,kBAAA;EA8BT;EA5BN,MAAA;EAgC4B;EA9B5B,MAAA;AAAA;;UAIe,oBAAA;EACf,OAAA;EACA,QAAA;EACA,MAAA,EAAQ,YAAA;AAAA;;KAME,YAAA;;UAUK,cAAA;EACf,QAAA;EACA,SAAA,EAAW,MAAA;EACX,MAAA;AAAA;;UAIe,aAAA;EAaf;EAXA,IAAA;EAYA;EAVA,SAAA,EAAW,cAAA;AAAA;;;;;UAOI,qBAAA;EACf,QAAA;EACA,MAAA,EAAQ,YAAA;EACR,UAAA;EAgBA;EAdA,SAAA,EAAW,eAAA;EAgBI;EAdf,aAAA;EAkBA;EAhBA,cAAA,EAAgB,cAAA;EAkBJ;EAhBZ,WAAA;EAsBU;EApBV,UAAA,EAAY,MAAA;;EAEZ,UAAA;EAkBsB;EAhBtB,MAAA;EAuB+B;EArB/B,QAAA;EA2BkB;EAzBlB,aAAA,EAAe,aAAA;EAqBf;EAnBA,YAAA;EAqBA;EAnBA,eAAA;EAqBA;EAAA,CAnBC,GAAA;AAAA;;KAMS,YAAA;;;AAuBZ;;;UAhBiB,gBAAA;EACf,EAAA;EACA,KAAA;EACA,MAAA;EACA,eAAA;EACA,QAAA;EACA,IAAA,EAAM,YAAA;EA4BkC;EA1BxC,SAAA;EA2BA;EAzBA,SAAA;EA6Be;EA3Bf,SAAA;AAAA;;UAIe,uBAAA;EA+Bf;EA7BA,iBAAA;EAsCA;;;;;EAhCA,MAAA;EAsCgB;;AAIlB;;;EApCE,YAAA;AAAA;;UAIe,yBAAA;EACf,SAAA,EAAW,gBAAA;AAAA;;UAII,wBAAA;EAmCA;EAjCf,iBAAA;;;;AAuCF;;EAjCE,MAAA;EAuCa;;;;;;EAhCb,YAAA;EA6BA;EA3BA,eAAA;EA6BA;EA3BA,QAAA;EA4Ba;EA1Bb,IAAA,GAAO,YAAA;EA2BK;EAzBZ,SAAA,GAAY,IAAA;AAAA;;UAIG,wBAAA;EA0BA;EAxBf,iBAAA;EACA,IAAA,GAAO,YAAA;EACP,SAAA,GAAY,IAAA;AAAA;;UAIG,wBAAA;EAsBf;EApBA,iBAAA;AAAA;;UAIe,eAAA;EACf,OAAA;EACA,OAAA;EACA,GAAA;EACA,aAAA;EACA,MAAA;EACA,UAAA,GAAa,yBAAA;EACb,SAAA,GAAY,iBAAA;EACZ,UAAA,GAAa,iBAAA;AAAA;;UAIE,yBAAA;EACf,OAAA;EACA,MAAA;EACA,QAAA;EACA,mBAAA;EACA,cAAA;EACA,iBAAA;AAAA;;;AAjXF;;;;;AAAA,cCOa,UAAA;EAAA,iBACM,OAAA;EAAA,iBACA,OAAA;EAAA,iBACA,SAAA;EAAA,iBACA,UAAA;cAEL,OAAA,EAAS,eAAA;EDLrB;;;;;;;;;ECqBM,OAAA,GAAA,CAAW,IAAA,UAAc,IAAA,EAAM,WAAA,GAAc,OAAA,CAAQ,CAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;cCChD,aAAA;EAAA,iBACM,OAAA;EAAA,iBACA,IAAA;cAEL,OAAA,EAAS,eAAA,EAAiB,IAAA,EAAM,UAAA;EFN7B;;;;;;;EEkBT,OAAA,CACJ,QAAA,UACA,MAAA,EAAQ,mBAAA,GACP,OAAA,CAAQ,oBAAA;EFGX;;;;AASF;;;EEMQ,MAAA,CACJ,QAAA,UACA,MAAA,EAAQ,kBAAA,GACP,OAAA,CAAQ,oBAAA;EAAA,QAMG,MAAA;AAAA;;;AF5EhB;;;;;;;AAAA,cGwBa,cAAA;EAAA,iBACM,OAAA;EAAA,iBACA,UAAA;EAAA,QACT,IAAA;EAAA,QACA,SAAA;cAEI,OAAA,EAAS,eAAA;EHVrB;;;;;;;;;;;;EG2BM,WAAA,CAAY,KAAA,WAAgB,OAAA,CAAQ,kBAAA;EHnBV;;;;;;EG+G1B,WAAA,CAAA,GAAe,OAAA;EAAA,QASb,aAAA;EAAA,QASA,OAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;AHjIV;;;;;;cIea,mBAAA;EAAA,iBACM,OAAA;EAAA,iBACA,IAAA;cAEL,OAAA,EAAS,eAAA,EAAiB,IAAA,EAAM,UAAA;EJU3B;;AAInB;;;;;EIFQ,IAAA,CACJ,MAAA,EAAQ,uBAAA,GACP,OAAA,CAAQ,yBAAA;EJMX;;;;;;;;;EIeM,MAAA,CAAO,MAAA,EAAQ,wBAAA,GAA2B,OAAA,CAAQ,gBAAA;EJG5C;;AAId;;;;;EIoBQ,MAAA,CACJ,EAAA,UACA,MAAA,EAAQ,wBAAA,GACP,OAAA,CAAQ,gBAAA;EJfX;;;;AAIF;;;;EIiCQ,MAAA,CACJ,EAAA,UACA,MAAA,EAAQ,wBAAA,GACP,OAAA;IAAU,OAAA;EAAA;EJhCb;EAAA,QIyCc,IAAA;AAAA;;;cChIH,cAAA;EAAA,iBACM,OAAA;EAAA,iBACA,IAAA;cAEL,OAAA,EAAS,eAAA,EAAiB,IAAA,EAAM,UAAA;ELEP;;;;;;;;EKW/B,IAAA,CAAK,MAAA,EAAQ,iBAAA,GAAoB,OAAA,CAAQ,eAAA;ELflC;;;;;;EK6Cb,MAAA,CAAO,MAAA,EAAQ,mBAAA;ELzCsB;;;;AAIvC;;;EK0DE,aAAA,CAAc,MAAA,EAAQ,mBAAA;ELlDtB;;;;;;;;AAyBF;EKwCE,cAAA,CAAe,MAAA,EAAQ,mBAAA,GAAsB,qBAAA;;;;;;;;;;EAsB7C,iBAAA,CAAkB,MAAA,EAAQ,uBAAA,GAA0B,gBAAA;AAAA;;;;;;;;;;;;;;;;;;cCjGzC,UAAA;ENFG;EAAA,SMIE,QAAA,EAAU,cAAA;ENJC;EAAA,SMMX,OAAA,EAAS,aAAA;ENNoB;EAAA,SMQ7B,aAAA,EAAe,mBAAA;ENJC;EAAA,SMMhB,QAAA,EAAU,cAAA;ENNM;;;;cMYpB,OAAA,GAAS,iBAAA;AAAA;;;;ANxCvB;;;cOGa,eAAA,SAAwB,KAAA;cACvB,OAAA;AAAA;;;;;cAWD,kBAAA,SAA2B,eAAA;cAC1B,OAAA;AAAA;;;;;;;;;cAeD,SAAA,SAAkB,eAAA;EAAA,SACb,UAAA;EAAA,SACA,YAAA;EAAA,SACA,GAAA;cAEJ,UAAA,UAAoB,YAAA,UAAsB,GAAA;AAAA;;cAW3C,YAAA,SAAqB,eAAA;cACpB,GAAA,UAAa,OAAA;AAAA;;cAQd,qBAAA,SAA8B,eAAA;cAC7B,OAAA;AAAA;;KAQF,uBAAA;APJZ;;;;;AAAA,cOqBa,iBAAA,SAA0B,eAAA;EAAA,SACrB,MAAA,EAAQ,uBAAA;cAEZ,MAAA,EAAQ,uBAAA,EAAyB,OAAA;AAAA;;KASnC,4BAAA;;;;;cAYC,sBAAA,SAA+B,eAAA;EAAA,SAC1B,MAAA,EAAQ,4BAAA;cAEZ,MAAA,EAAQ,4BAAA,EAA8B,OAAA;AAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { createRemoteJWKSet, errors, jwtVerify } from "jose";
|
|
2
3
|
//#region src/errors.ts
|
|
3
4
|
/**
|
|
4
5
|
* Base error class for all SDK errors. Catch this to handle any error
|
|
@@ -59,6 +60,33 @@ var WebhookSignatureError = class extends AgentPressError {
|
|
|
59
60
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
60
61
|
}
|
|
61
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Thrown by {@link PartnersClient.verifyToken} when a Partner MCP Spec v1 JWT
|
|
65
|
+
* fails verification. Partners map `reason` to their RFC 6750 `WWW-Authenticate`
|
|
66
|
+
* response (`401 invalid_token` for all reasons in this class).
|
|
67
|
+
*/
|
|
68
|
+
var PartnerTokenError = class extends AgentPressError {
|
|
69
|
+
reason;
|
|
70
|
+
constructor(reason, message) {
|
|
71
|
+
super(message);
|
|
72
|
+
this.name = "PartnerTokenError";
|
|
73
|
+
this.reason = reason;
|
|
74
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Thrown by {@link WebhooksClient.verifyKeyRotation} when a `signing_key_rotation`
|
|
79
|
+
* webhook fails HMAC / timestamp / payload validation.
|
|
80
|
+
*/
|
|
81
|
+
var KeyRotationVerifyError = class extends AgentPressError {
|
|
82
|
+
reason;
|
|
83
|
+
constructor(reason, message) {
|
|
84
|
+
super(message);
|
|
85
|
+
this.name = "KeyRotationVerifyError";
|
|
86
|
+
this.reason = reason;
|
|
87
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
62
90
|
//#endregion
|
|
63
91
|
//#region src/utils.ts
|
|
64
92
|
function randomMessageId() {
|
|
@@ -66,7 +94,7 @@ function randomMessageId() {
|
|
|
66
94
|
}
|
|
67
95
|
//#endregion
|
|
68
96
|
//#region src/webhooks/signing.ts
|
|
69
|
-
const SIGNATURE_PREFIX = "v1,";
|
|
97
|
+
const SIGNATURE_PREFIX$1 = "v1,";
|
|
70
98
|
const DEFAULT_TOLERANCE_SECONDS = 300;
|
|
71
99
|
/**
|
|
72
100
|
* Sign a webhook payload using Svix-compatible HMAC-SHA256.
|
|
@@ -80,7 +108,7 @@ const DEFAULT_TOLERANCE_SECONDS = 300;
|
|
|
80
108
|
function sign(secret, msgId, timestamp, body) {
|
|
81
109
|
const secretBytes = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
|
|
82
110
|
const message = `${msgId}.${timestamp}.${body}`;
|
|
83
|
-
return `${SIGNATURE_PREFIX}${createHmac("sha256", secretBytes).update(message).digest("base64")}`;
|
|
111
|
+
return `${SIGNATURE_PREFIX$1}${createHmac("sha256", secretBytes).update(message).digest("base64")}`;
|
|
84
112
|
}
|
|
85
113
|
/**
|
|
86
114
|
* Verify a Svix webhook signature.
|
|
@@ -233,6 +261,121 @@ var HttpClient = class {
|
|
|
233
261
|
}
|
|
234
262
|
};
|
|
235
263
|
//#endregion
|
|
264
|
+
//#region src/partners/client.ts
|
|
265
|
+
const ALGORITHMS = ["EdDSA"];
|
|
266
|
+
/**
|
|
267
|
+
* Client for Partner MCP Spec v1 helpers. Created automatically when
|
|
268
|
+
* {@link AgentPressOptions.partnerMcp} is provided.
|
|
269
|
+
*
|
|
270
|
+
* State (JWKS cache) is per-instance, NOT module-global, so staging and
|
|
271
|
+
* production clients can run side-by-side without cross-talk.
|
|
272
|
+
*/
|
|
273
|
+
var PartnersClient = class {
|
|
274
|
+
options;
|
|
275
|
+
partnerMcp;
|
|
276
|
+
jwks = null;
|
|
277
|
+
jwksKeyFn = null;
|
|
278
|
+
constructor(options) {
|
|
279
|
+
this.options = options;
|
|
280
|
+
this.partnerMcp = options.partnerMcp;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Verify an inbound Partner MCP Spec v1 JWT against AgentPress's JWKS.
|
|
284
|
+
*
|
|
285
|
+
* Enforces the full spec: `algorithms: ["EdDSA"]` pinned; `iss`, `aud`,
|
|
286
|
+
* `ext_provider` validated; `sub`, `jti`, `scope` required and non-empty;
|
|
287
|
+
* `kid` header required; `exp` / `iat` validated with ±30s skew (configurable).
|
|
288
|
+
*
|
|
289
|
+
* @param token - Bare JWT string (no `Bearer ` prefix).
|
|
290
|
+
* @returns Typed {@link PartnerTokenClaims}.
|
|
291
|
+
* @throws {PartnerTokenError} with a typed `reason` for RFC 6750 mapping.
|
|
292
|
+
* @throws {ConfigurationError} if `partnerMcp` is not configured.
|
|
293
|
+
*/
|
|
294
|
+
async verifyToken(token) {
|
|
295
|
+
const cfg = this.requireConfig();
|
|
296
|
+
const jwks = this.getJwks();
|
|
297
|
+
let payload;
|
|
298
|
+
let protectedHeader;
|
|
299
|
+
try {
|
|
300
|
+
const result = await jwtVerify(token, jwks, {
|
|
301
|
+
algorithms: [...ALGORITHMS],
|
|
302
|
+
issuer: cfg.issuer,
|
|
303
|
+
audience: cfg.audience,
|
|
304
|
+
clockTolerance: cfg.clockTolerance
|
|
305
|
+
});
|
|
306
|
+
payload = result.payload;
|
|
307
|
+
protectedHeader = result.protectedHeader;
|
|
308
|
+
} catch (err) {
|
|
309
|
+
throw mapJoseError(err);
|
|
310
|
+
}
|
|
311
|
+
if (!protectedHeader.kid || typeof protectedHeader.kid !== "string") throw new PartnerTokenError("kid_missing_or_unknown", "JWT header missing required 'kid'");
|
|
312
|
+
const claims = payload;
|
|
313
|
+
if (typeof claims.iat !== "number" || !Number.isFinite(claims.iat)) throw new PartnerTokenError("missing_claim", "'iat' claim must be a number");
|
|
314
|
+
const toleranceSeconds = toSeconds(cfg.clockTolerance);
|
|
315
|
+
const nowSec = Math.floor(Date.now() / 1e3);
|
|
316
|
+
if (claims.iat - nowSec > toleranceSeconds) throw new PartnerTokenError("not_yet_valid", `'iat' is ${claims.iat - nowSec}s in the future, beyond ${toleranceSeconds}s tolerance`);
|
|
317
|
+
if (typeof claims.sub !== "string" || claims.sub.length === 0) throw new PartnerTokenError("missing_claim", "'sub' claim is required");
|
|
318
|
+
if (typeof claims.jti !== "string" || claims.jti.length === 0) throw new PartnerTokenError("missing_claim", "'jti' claim is required");
|
|
319
|
+
if (typeof claims.scope !== "string") throw new PartnerTokenError("missing_claim", "'scope' claim must be a string");
|
|
320
|
+
if (typeof claims.ext_provider !== "string" || claims.ext_provider.length === 0) throw new PartnerTokenError("missing_claim", "'ext_provider' claim is required");
|
|
321
|
+
if (claims.ext_provider !== cfg.expectedExtProvider) throw new PartnerTokenError("ext_provider_mismatch", `ext_provider '${claims.ext_provider}' does not match expected '${cfg.expectedExtProvider}'`);
|
|
322
|
+
return claims;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Force the JWKS cache to refetch immediately. Call this from your
|
|
326
|
+
* `signing_key_rotation` webhook handler after verifying the webhook —
|
|
327
|
+
* otherwise the cache picks up new keys on the next `kid` miss (which
|
|
328
|
+
* works, but with one failed verify latency penalty).
|
|
329
|
+
*/
|
|
330
|
+
async refreshJwks() {
|
|
331
|
+
const anyJwks = this.getJwks();
|
|
332
|
+
if (typeof anyJwks.reload === "function") await anyJwks.reload();
|
|
333
|
+
}
|
|
334
|
+
requireConfig() {
|
|
335
|
+
if (!this.partnerMcp) throw new ConfigurationError("partnerMcp options are required for partner token operations");
|
|
336
|
+
return this.partnerMcp;
|
|
337
|
+
}
|
|
338
|
+
getJwks() {
|
|
339
|
+
const cfg = this.requireConfig();
|
|
340
|
+
if (!this.jwks) {
|
|
341
|
+
this.jwks = createRemoteJWKSet(new URL(cfg.jwksUrl), {
|
|
342
|
+
cacheMaxAge: cfg.jwksCacheMaxAgeMs,
|
|
343
|
+
cooldownDuration: 3e4
|
|
344
|
+
});
|
|
345
|
+
this.jwksKeyFn = this.jwks;
|
|
346
|
+
}
|
|
347
|
+
return this.jwks;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
function toSeconds(tolerance) {
|
|
351
|
+
if (typeof tolerance === "number") return tolerance;
|
|
352
|
+
const match = tolerance.trim().match(/^(\d+)\s*(s|m|h)$/i);
|
|
353
|
+
if (!match) return 30;
|
|
354
|
+
const n = Number.parseInt(match[1], 10);
|
|
355
|
+
const unit = match[2].toLowerCase();
|
|
356
|
+
if (unit === "s") return n;
|
|
357
|
+
if (unit === "m") return n * 60;
|
|
358
|
+
if (unit === "h") return n * 3600;
|
|
359
|
+
return 30;
|
|
360
|
+
}
|
|
361
|
+
function mapJoseError(err) {
|
|
362
|
+
if (err instanceof PartnerTokenError) return err;
|
|
363
|
+
if (err instanceof errors.JWSSignatureVerificationFailed) return new PartnerTokenError("signature_invalid", "JWT signature verification failed");
|
|
364
|
+
if (err instanceof errors.JWKSNoMatchingKey) return new PartnerTokenError("kid_missing_or_unknown", "No JWKS key matches the JWT 'kid' header");
|
|
365
|
+
if (err instanceof errors.JOSEAlgNotAllowed) return new PartnerTokenError("algorithm_not_allowed", "JWT 'alg' is not EdDSA");
|
|
366
|
+
if (err instanceof errors.JWTExpired) return new PartnerTokenError("expired", "JWT has expired");
|
|
367
|
+
if (err instanceof errors.JWTClaimValidationFailed) {
|
|
368
|
+
const claim = err.claim;
|
|
369
|
+
if (claim === "iss") return new PartnerTokenError("issuer_mismatch", "JWT 'iss' does not match expected issuer");
|
|
370
|
+
if (claim === "aud") return new PartnerTokenError("audience_mismatch", "JWT 'aud' does not match expected audience");
|
|
371
|
+
if (claim === "iat") return new PartnerTokenError("not_yet_valid", "JWT 'iat' is in the future beyond clock tolerance");
|
|
372
|
+
return new PartnerTokenError("missing_claim", err.message || "Claim validation failed");
|
|
373
|
+
}
|
|
374
|
+
if (err instanceof errors.JWTInvalid || err instanceof errors.JWSInvalid) return new PartnerTokenError("malformed", err.message || "Malformed JWT");
|
|
375
|
+
if (err instanceof Error) return new PartnerTokenError("malformed", err.message);
|
|
376
|
+
return new PartnerTokenError("malformed", String(err));
|
|
377
|
+
}
|
|
378
|
+
//#endregion
|
|
236
379
|
//#region src/userApprovals/client.ts
|
|
237
380
|
/**
|
|
238
381
|
* Client for managing per-user auto-approval rules — the SDK equivalent of the
|
|
@@ -348,6 +491,74 @@ var UserApprovalsClient = class {
|
|
|
348
491
|
}
|
|
349
492
|
};
|
|
350
493
|
//#endregion
|
|
494
|
+
//#region src/webhooks/keyRotation.ts
|
|
495
|
+
const MAX_PAYLOAD_BYTES = 8 * 1024;
|
|
496
|
+
const TIMESTAMP_SKEW_SECONDS = 300;
|
|
497
|
+
const SIGNATURE_PREFIX = "sha256=";
|
|
498
|
+
/**
|
|
499
|
+
* Verify a `signing_key_rotation` webhook signed by AgentPress with
|
|
500
|
+
* HMAC-SHA256 over the raw request body. Returns the typed
|
|
501
|
+
* {@link KeyRotationEvent} payload.
|
|
502
|
+
*
|
|
503
|
+
* @throws {KeyRotationVerifyError} with a typed `reason` for HTTP mapping.
|
|
504
|
+
* @throws {ConfigurationError} if `webhookSecret` is not configured.
|
|
505
|
+
*/
|
|
506
|
+
function verifyKeyRotation(secret, params) {
|
|
507
|
+
if (!secret) throw new ConfigurationError("webhookSecret is required for key rotation webhook verification");
|
|
508
|
+
const body = typeof params.payload === "string" ? params.payload : params.payload.toString("utf-8");
|
|
509
|
+
if ((typeof params.payload === "string" ? Buffer.byteLength(params.payload, "utf-8") : params.payload.length) > MAX_PAYLOAD_BYTES) throw new KeyRotationVerifyError("payload_too_large", `Payload exceeds ${MAX_PAYLOAD_BYTES} bytes`);
|
|
510
|
+
const signatureHeader = readHeader(params.headers, "x-agentpress-signature");
|
|
511
|
+
const timestampHeader = readHeader(params.headers, "x-agentpress-timestamp");
|
|
512
|
+
if (!signatureHeader?.startsWith(SIGNATURE_PREFIX)) throw new KeyRotationVerifyError("invalid_signature_format", `Signature header missing or does not start with '${SIGNATURE_PREFIX}'`);
|
|
513
|
+
const providedHex = signatureHeader.slice(7).toLowerCase();
|
|
514
|
+
if (!/^[0-9a-f]+$/.test(providedHex)) throw new KeyRotationVerifyError("invalid_signature_format", "Signature is not a hex string");
|
|
515
|
+
if (!timestampHeader) throw new KeyRotationVerifyError("invalid_timestamp", "x-agentpress-timestamp header is required");
|
|
516
|
+
const timestamp = Number.parseInt(timestampHeader, 10);
|
|
517
|
+
if (!Number.isFinite(timestamp) || String(timestamp) !== timestampHeader.trim()) throw new KeyRotationVerifyError("invalid_timestamp", "x-agentpress-timestamp is not a valid unix seconds integer");
|
|
518
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
519
|
+
if (Math.abs(now - timestamp) > TIMESTAMP_SKEW_SECONDS) throw new KeyRotationVerifyError("timestamp_out_of_window", `Timestamp skew ${Math.abs(now - timestamp)}s exceeds ${TIMESTAMP_SKEW_SECONDS}s tolerance`);
|
|
520
|
+
const expectedHex = createHmac("sha256", secret).update(body).digest("hex");
|
|
521
|
+
const providedBuf = Buffer.from(providedHex, "hex");
|
|
522
|
+
const expectedBuf = Buffer.from(expectedHex, "hex");
|
|
523
|
+
if (providedBuf.length !== expectedBuf.length || !timingSafeEqual(providedBuf, expectedBuf)) throw new KeyRotationVerifyError("invalid_signature", "HMAC signature mismatch");
|
|
524
|
+
let parsed;
|
|
525
|
+
try {
|
|
526
|
+
parsed = JSON.parse(body);
|
|
527
|
+
} catch {
|
|
528
|
+
throw new KeyRotationVerifyError("malformed_payload", "Payload is not valid JSON");
|
|
529
|
+
}
|
|
530
|
+
return validatePayload(parsed);
|
|
531
|
+
}
|
|
532
|
+
function readHeader(headers, name) {
|
|
533
|
+
const lowered = name.toLowerCase();
|
|
534
|
+
for (const [k, v] of Object.entries(headers)) if (k.toLowerCase() === lowered && typeof v === "string" && v.length > 0) return v;
|
|
535
|
+
}
|
|
536
|
+
function validatePayload(raw) {
|
|
537
|
+
if (!raw || typeof raw !== "object") throw new KeyRotationVerifyError("malformed_payload", "Payload must be a JSON object");
|
|
538
|
+
const obj = raw;
|
|
539
|
+
if (obj.event !== "signing_key_rotation") throw new KeyRotationVerifyError("malformed_payload", `Unexpected event '${String(obj.event)}'`);
|
|
540
|
+
if (obj.type !== "scheduled" && obj.type !== "emergency") throw new KeyRotationVerifyError("malformed_payload", "'type' must be 'scheduled' or 'emergency'");
|
|
541
|
+
for (const key of [
|
|
542
|
+
"retiredKid",
|
|
543
|
+
"newCurrentKid",
|
|
544
|
+
"retiredAt",
|
|
545
|
+
"effectiveAt",
|
|
546
|
+
"jwksUrl"
|
|
547
|
+
]) if (typeof obj[key] !== "string" || obj[key].length === 0) throw new KeyRotationVerifyError("malformed_payload", `'${key}' must be a non-empty string`);
|
|
548
|
+
if (obj.reason !== void 0 && typeof obj.reason !== "string") throw new KeyRotationVerifyError("malformed_payload", "'reason' must be a string when present");
|
|
549
|
+
const event = {
|
|
550
|
+
event: "signing_key_rotation",
|
|
551
|
+
type: obj.type,
|
|
552
|
+
retiredKid: obj.retiredKid,
|
|
553
|
+
newCurrentKid: obj.newCurrentKid,
|
|
554
|
+
retiredAt: obj.retiredAt,
|
|
555
|
+
effectiveAt: obj.effectiveAt,
|
|
556
|
+
jwksUrl: obj.jwksUrl
|
|
557
|
+
};
|
|
558
|
+
if (typeof obj.reason === "string") event.reason = obj.reason;
|
|
559
|
+
return event;
|
|
560
|
+
}
|
|
561
|
+
//#endregion
|
|
351
562
|
//#region src/webhooks/client.ts
|
|
352
563
|
var WebhooksClient = class {
|
|
353
564
|
options;
|
|
@@ -419,6 +630,18 @@ var WebhooksClient = class {
|
|
|
419
630
|
throw new AgentPressError("Webhook payload is not valid JSON");
|
|
420
631
|
}
|
|
421
632
|
}
|
|
633
|
+
/**
|
|
634
|
+
* Verify an inbound `signing_key_rotation` webhook (HMAC-SHA256 + timestamp
|
|
635
|
+
* + typed payload) from AgentPress. See the Partner MCP Spec v1 for the
|
|
636
|
+
* full contract.
|
|
637
|
+
*
|
|
638
|
+
* @throws {KeyRotationVerifyError} with a typed `reason` for HTTP mapping
|
|
639
|
+
* (401 for signature errors, 400 for malformed payload, 413 for oversize).
|
|
640
|
+
* @throws {ConfigurationError} if `webhookSecret` is not configured.
|
|
641
|
+
*/
|
|
642
|
+
verifyKeyRotation(params) {
|
|
643
|
+
return verifyKeyRotation(this.options.webhookSecret, params);
|
|
644
|
+
}
|
|
422
645
|
};
|
|
423
646
|
//#endregion
|
|
424
647
|
//#region src/client.ts
|
|
@@ -444,6 +667,8 @@ var AgentPress = class {
|
|
|
444
667
|
actions;
|
|
445
668
|
/** Per-user auto-approval rules (read / create / update / delete). */
|
|
446
669
|
userApprovals;
|
|
670
|
+
/** Partner MCP Spec v1 helpers (inbound JWT verification, JWKS refresh). */
|
|
671
|
+
partners;
|
|
447
672
|
/**
|
|
448
673
|
* @param options - SDK configuration. All fields are optional with sensible defaults.
|
|
449
674
|
* @throws {ConfigurationError} If `timeout` is non-positive or `webhookSecret` has an invalid prefix.
|
|
@@ -454,6 +679,7 @@ var AgentPress = class {
|
|
|
454
679
|
this.webhooks = new WebhooksClient(resolved, http);
|
|
455
680
|
this.actions = new ActionsClient(resolved, http);
|
|
456
681
|
this.userApprovals = new UserApprovalsClient(resolved, http);
|
|
682
|
+
this.partners = new PartnersClient(resolved);
|
|
457
683
|
}
|
|
458
684
|
};
|
|
459
685
|
function resolveOptions(options) {
|
|
@@ -468,11 +694,35 @@ function resolveOptions(options) {
|
|
|
468
694
|
org,
|
|
469
695
|
webhookSecret: options.webhookSecret,
|
|
470
696
|
apiKey: options.apiKey,
|
|
697
|
+
partnerMcp: resolvePartnerMcp(options.partnerMcp),
|
|
471
698
|
onRequest: options.onRequest,
|
|
472
699
|
onResponse: options.onResponse
|
|
473
700
|
};
|
|
474
701
|
}
|
|
702
|
+
function resolvePartnerMcp(options) {
|
|
703
|
+
if (!options) return void 0;
|
|
704
|
+
if (typeof options.jwksUrl !== "string" || options.jwksUrl.length === 0) throw new ConfigurationError("partnerMcp.jwksUrl is required");
|
|
705
|
+
try {
|
|
706
|
+
new URL(options.jwksUrl);
|
|
707
|
+
} catch {
|
|
708
|
+
throw new ConfigurationError("partnerMcp.jwksUrl must be a valid URL");
|
|
709
|
+
}
|
|
710
|
+
if (typeof options.issuer !== "string" || options.issuer.length === 0) throw new ConfigurationError("partnerMcp.issuer is required");
|
|
711
|
+
if (typeof options.audience !== "string" || options.audience.length === 0) throw new ConfigurationError("partnerMcp.audience is required");
|
|
712
|
+
if (typeof options.expectedExtProvider !== "string" || options.expectedExtProvider.length === 0) throw new ConfigurationError("partnerMcp.expectedExtProvider is required");
|
|
713
|
+
const clockTolerance = options.clockTolerance ?? "30s";
|
|
714
|
+
const jwksCacheMaxAgeMs = options.jwksCacheMaxAgeMs ?? 36e5;
|
|
715
|
+
if (jwksCacheMaxAgeMs <= 0 || !Number.isFinite(jwksCacheMaxAgeMs)) throw new ConfigurationError("partnerMcp.jwksCacheMaxAgeMs must be a positive number");
|
|
716
|
+
return {
|
|
717
|
+
jwksUrl: options.jwksUrl,
|
|
718
|
+
issuer: options.issuer,
|
|
719
|
+
audience: options.audience,
|
|
720
|
+
expectedExtProvider: options.expectedExtProvider,
|
|
721
|
+
clockTolerance,
|
|
722
|
+
jwksCacheMaxAgeMs
|
|
723
|
+
};
|
|
724
|
+
}
|
|
475
725
|
//#endregion
|
|
476
|
-
export { ActionsClient, AgentPress, AgentPressError, ConfigurationError, HttpError, TimeoutError, UserApprovalsClient, WebhookSignatureError };
|
|
726
|
+
export { ActionsClient, AgentPress, AgentPressError, ConfigurationError, HttpError, KeyRotationVerifyError, PartnerTokenError, PartnersClient, TimeoutError, UserApprovalsClient, WebhookSignatureError, WebhooksClient };
|
|
477
727
|
|
|
478
728
|
//# sourceMappingURL=index.mjs.map
|