@atrib/agent 0.2.23 → 0.3.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/LICENSE CHANGED
@@ -201,7 +201,7 @@
201
201
  See the License for the specific language governing permissions and
202
202
  limitations under the License.
203
203
 
204
- Copyright 2025-2026 Atrib contributors
204
+ Copyright 2025-2026 atrib contributors
205
205
 
206
206
  Licensed under the Apache License, Version 2.0 (the "License");
207
207
  you may not use this file except in compliance with the License.
package/README.md CHANGED
@@ -1,26 +1,42 @@
1
1
  # `@atrib/agent`
2
2
 
3
- **Verifiable agent actions, client side. Outbound MCP tool calls carry atrib/W3C context, consume upstream signed records, record local gap nodes, and emit signed fallback transaction records when commerce closes. Works with every major MCP framework. Sits above every major agent payment protocol so commerce-closing evidence can join the same trace.**
3
+ **Client-side middleware for atrib's verifiable action layer. Outbound MCP tool calls carry atrib/W3C context, consume upstream signed records, record local gap nodes, and emit signed fallback transaction records when commerce closes. Works with major MCP framework surfaces. Sits above every major agent payment protocol so commerce-closing evidence can join the same trace.**
4
4
 
5
- `@atrib/agent` is the client-side half of the [atrib protocol](https://github.com/creatornader/atrib/blob/main/atrib-spec.md). It keeps outbound MCP calls in the atrib session lifecycle: context goes out, upstream atrib tokens come back in, unsigned hops become local gap nodes, and transaction-shaped responses can produce signed agent-side fallback records. Ordinary `tool_call` records are signed at the tool boundary by `@atrib/mcp`, `@atrib/mcp-wrap`, or an instrumented upstream server.
5
+ `@atrib/agent` is the client-side half of the [atrib protocol](https://github.com/creatornader/atrib/blob/main/atrib-spec.md). It keeps outbound MCP calls in the atrib session lifecycle: context goes out, upstream atrib tokens come back in, unsigned hops become local gap nodes, and transaction-shaped responses can produce signed agent-side fallback records. That makes agent work easier to coordinate across calls, handoffs, and later verification. Ordinary `tool_call` records are signed at the tool boundary by `@atrib/mcp`, `@atrib/mcp-wrap`, or an instrumented upstream server.
6
6
 
7
7
  You set up one `atrib()` interceptor, plug it into your framework's adapter, and every outbound `tools/call` from that point on carries W3C trace context, an atrib chain token, and the full atrib session lifecycle. When a payment completes through a supported commerce protocol, the interceptor can consume an upstream atrib record or emit an agent-side fallback `transaction` record. When commerce never closes the chain, the substrate still serves recall, audit, and cross-agent provenance.
8
8
 
9
9
  Two coverage surfaces define what you get:
10
10
 
11
+ Boundary: this package covers framework middleware and client-side call flow.
12
+ Full host runtime integrations are a separate adapter family. Runtimes such as
13
+ Claude Code, Codex, OpenClaw, Hermes, Cursor, Goose, and hosted agent systems
14
+ own sessions, native tool hooks, approvals, subagents, checkpoints, telemetry,
15
+ and run logs. Those integrations compose `@atrib/mcp-wrap`, host-specific proof
16
+ code, `@atrib/openinference`, `@atrib/runtime-log`, `@atrib/verify`, and
17
+ hook-class producers instead of turning `@atrib/agent` into the harness layer.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pnpm add @atrib/agent
23
+ ```
24
+
25
+ Verify a local build with `pnpm --filter @atrib/agent test`.
26
+
11
27
  ## Coverage Matrix 1: MCP Framework Adapters
12
28
 
13
- | Framework | Package | Adapter helper | Integration shape | Status |
14
- | ------------------------------------------ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------- |
15
- | **Raw `@modelcontextprotocol/sdk` Client** | `@modelcontextprotocol/sdk` | `wrapMcpClient(client, interceptor, { serverUrl? })` | Proxy-based wrapper, returns new client | ✅ Shipped |
16
- | **Claude Agent SDK** | `@anthropic-ai/claude-agent-sdk` | **Case A (in-process tools):** zero code. the SDK's `createSdkMcpServer` returns a real `McpServer` that `@atrib/mcp` wraps directly | Reuses `@atrib/mcp`'s `atrib()` middleware on the server side | ✅ Shipped |
17
- | | | **Case B (third-party servers):** `createAtribProxy({ upstream, interceptor })` from `@atrib/mcp`. in-process surrogate `McpServer` that forwards to an upstream | Proxy McpServer between SDK and upstream transport | ✅ Shipped |
18
- | **Cloudflare Agents** | `agents` | `attributeCloudflareAgentMcp(agent, { interceptor, serverUrls })` | Walks `agent.mcp.mcpConnections`, replaces `.client` via `wrapMcpClient` | ✅ Shipped |
19
- | **Vercel AI SDK MCP** | `@ai-sdk/mcp` | `attributeVercelAiSdkMcp(mcpClient, { interceptor, serverUrl })` | Monkey-patches `mcpClient.request()` (custom JSON-RPC, not SDK Client) | ✅ Shipped |
20
- | **LangChain JS MCP adapters** | `@langchain/mcp-adapters` | **High-level:** `attributeLangchainMcp(multiClient, { interceptor, serverUrls })` | Walks `multiClient.config.mcpServers`, monkey-patches `callTool` + `fork` on each internal Client | ✅ Shipped |
21
- | | | **Low-level:** `wrapMcpClient(rawClient, interceptor)` passed to `loadMcpTools(name, wrapped)` | Reuses raw-SDK wrapper path | ✅ Shipped |
22
- | **OpenAI Agents SDK** | `@openai/agents` | _(planned. custom transport architecture, not `@modelcontextprotocol/sdk`)_ | Planned: subclass `MCPServerSSE` / `MCPServerStdio` / `MCPServerStreamableHttp` | ⏳ Planned |
23
- | **Mastra** | `@mastra/mcp` | _(planned. receipt proof covers `MCPClient` + `MCPServer` over stdio)_ | Adapter pending | 🧪 Proof |
29
+ | Framework | Package | Adapter helper | Integration shape | Status |
30
+ | ------------------------------------------ | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ---------- |
31
+ | **Raw `@modelcontextprotocol/sdk` Client** | `@modelcontextprotocol/sdk` | `wrapMcpClient(client, interceptor, { serverUrl? })` | Proxy-based wrapper, returns new client | ✅ Shipped |
32
+ | **Claude Agent SDK** | `@anthropic-ai/claude-agent-sdk` | **Case A (in-process tools):** zero code. the SDK's `createSdkMcpServer` returns a real `McpServer` that `@atrib/mcp` wraps directly | Reuses `@atrib/mcp`'s `atrib()` middleware on the server side | ✅ Shipped |
33
+ | | | **Case B (third-party servers):** `createAtribProxy({ upstream, interceptor })` from `@atrib/mcp`. in-process surrogate `McpServer` that forwards to an upstream | Proxy McpServer between SDK and upstream transport | ✅ Shipped |
34
+ | **Cloudflare Agents** | `agents` | `attributeCloudflareAgentMcp(agent, { interceptor, serverUrls })` | Walks `agent.mcp.mcpConnections`, replaces `.client` via `wrapMcpClient` | ✅ Shipped |
35
+ | **Vercel AI SDK MCP** | `@ai-sdk/mcp` | `attributeVercelAiSdkMcp(mcpClient, { interceptor, serverUrl })` | Monkey-patches `mcpClient.request()` (custom JSON-RPC, not SDK Client) | ✅ Shipped |
36
+ | **LangChain JS MCP adapters** | `@langchain/mcp-adapters` | **High-level:** `attributeLangchainMcp(multiClient, { interceptor, serverUrls })` | Walks `multiClient.config.mcpServers`, monkey-patches `callTool` + `fork` on each internal Client | ✅ Shipped |
37
+ | | | **Low-level:** `wrapMcpClient(rawClient, interceptor)` passed to `loadMcpTools(name, wrapped)` | Reuses raw-SDK wrapper path | ✅ Shipped |
38
+ | **OpenAI Agents SDK** | `@openai/agents` | _(planned. custom transport architecture, not `@modelcontextprotocol/sdk`)_ | Planned: subclass `MCPServerSSE` / `MCPServerStdio` / `MCPServerStreamableHttp` | ⏳ Planned |
39
+ | **Mastra** | `@mastra/mcp` | _(planned. receipt proof covers `MCPClient` + `MCPServer` over stdio)_ | Adapter pending | 🧪 Proof |
24
40
 
25
41
  **The pattern across every row is identical:** one `atrib()` interceptor object, one adapter helper call, zero changes to your existing tool invocation code. The name of the helper varies because each host framework exposes a structurally different integration surface, but the `ToolCallInterceptor` type, the options shape, and the observable behavior are uniform.
26
42
 
@@ -30,14 +46,14 @@ Two coverage surfaces define what you get:
30
46
 
31
47
  All detection logic lives in `packages/agent/src/transaction.ts` and runs against unit tests for each protocol's published spec.
32
48
 
33
- | Protocol | Sponsor / origin | Detection signal | Spec reference |
34
- | ------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
35
- | **ACP**. Agentic Commerce Protocol | Stripe / OpenAI; `github.com/agentic-commerce-protocol` | `status === "completed"` + embedded `order` on `/checkout_sessions/{id}/complete`, or `order_create` / `order_update` webhook | [§1.7.1](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#171-acp-agentic-commerce-protocol) |
36
- | **UCP**. Universal Commerce Protocol | `github.com/universal-commerce-protocol/ucp` | Same shape as ACP + top-level `ucp.version` envelope | [§1.7.2](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#172-ucp-universal-commerce-protocol) |
37
- | **x402** | Coinbase. `github.com/coinbase/x402` | HTTP `PAYMENT-RESPONSE` header (v2) or legacy `X-PAYMENT-RESPONSE` (v1) on the 200 response | [§1.7.3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#173-x402) |
38
- | **MPP**. Machine Payments Protocol | Tempo Labs / Stripe; IETF `draft-ryan-httpauth-payment-01` | HTTP `Payment-Receipt` header on 200 success response | [§1.7.4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#174-mpp-machine-payments-protocol) |
39
- | **AP2**. Agentic Payment Protocol | Google; `github.com/google-agentic-commerce/AP2` | Successful AP2 `PaymentReceipt` or `CheckoutReceipt`; v0.1 `ap2.mandates.PaymentMandate` remains a fallback | [§1.7.5](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#175-ap2-and-a2a-x402) |
40
- | **a2a-x402** | Google. `github.com/google-agentic-commerce/a2a-x402` | A2A task `status.message.metadata["x402.payment.status"] === "payment-completed"` + `receipts[].success === true` | [§1.7.5](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#175-ap2-and-a2a-x402) (reported as AP2 crypto path) |
49
+ | Protocol | Sponsor / origin | Detection signal | Spec reference |
50
+ | ------------------------------------ | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
51
+ | **ACP**. Agentic Commerce Protocol | Stripe / OpenAI; `github.com/agentic-commerce-protocol` | `status === "completed"` + embedded `order` on `/checkout_sessions/{id}/complete`, or `order_create` / `order_update` webhook | [§1.7.1](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#171-acp-agentic-commerce-protocol) |
52
+ | **UCP**. Universal Commerce Protocol | `github.com/universal-commerce-protocol/ucp` | Same shape as ACP + top-level `ucp.version` envelope | [§1.7.2](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#172-ucp-universal-commerce-protocol) |
53
+ | **x402** | Coinbase. `github.com/coinbase/x402` | HTTP `PAYMENT-RESPONSE` header (v2) or legacy `X-PAYMENT-RESPONSE` (v1) on the 200 response | [§1.7.3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#173-x402) |
54
+ | **MPP**. Machine Payments Protocol | Tempo Labs / Stripe; IETF `draft-ryan-httpauth-payment-01` | HTTP `Payment-Receipt` header on 200 success response | [§1.7.4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#174-mpp-machine-payments-protocol) |
55
+ | **AP2**. Agentic Payment Protocol | Google; `github.com/google-agentic-commerce/AP2` | Successful AP2 `PaymentReceipt` or `CheckoutReceipt`; v0.1 `ap2.mandates.PaymentMandate` remains a fallback | [§1.7.5](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#175-ap2-and-a2a-x402) |
56
+ | **a2a-x402** | Google. `github.com/google-agentic-commerce/a2a-x402` | A2A task `status.message.metadata["x402.payment.status"] === "payment-completed"` + `receipts[].success === true` | [§1.7.5](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#175-ap2-and-a2a-x402) (reported as AP2 crypto path) |
41
57
 
42
58
  **The linking mechanism is the same across all six:** the session `context_id` (16-byte anchor, equal to the W3C OTel trace-id by default) travels with the outbound payment request; via `X-atrib-Context` HTTP header for protocols that don't expose a free-form metadata field, or via `params._meta.atrib` for any payment protocol running over MCP transport. When the merchant's side sees the payment-completed signal, atrib writes a transaction record with that `context_id`, and the attribution graph can reconstruct the full chain from contributing tool calls → transaction → settlement.
43
59
 
@@ -45,7 +61,7 @@ All detection logic lives in `packages/agent/src/transaction.ts` and runs agains
45
61
 
46
62
  ### What each detector actually looks for on the wire
47
63
 
48
- These are the exact shapes the production `detectTransaction()` function in [`packages/agent/src/transaction.ts`](https://github.com/creatornader/atrib/blob/main/packages/agent/src/transaction.ts) matches against. Every shape below is covered by a unit test against a real spec fixture in [`packages/agent/test/fixtures/`](https://github.com/creatornader/atrib/blob/main/packages/agent/test/fixtures/), the customer-facing question "what does atrib actually detect" has a one-paragraph answer per protocol.
64
+ These are the exact shapes the production `detectTransaction()` function in [`packages/agent/src/transaction.ts`](https://github.com/creatornader/atrib/blob/main/packages/agent/src/transaction.ts) matches against. Every shape below is covered by a unit test against a real spec fixture in [`packages/agent/test/fixtures/`](https://github.com/creatornader/atrib/blob/main/packages/agent/test/fixtures/), and the verifier question "what does atrib actually detect" has a one-paragraph answer per protocol.
49
65
 
50
66
  #### ACP: Stripe / OpenAI Agentic Commerce Protocol
51
67
 
@@ -188,7 +204,11 @@ const interceptor = atrib({
188
204
  })
189
205
  ```
190
206
 
191
- That's the interceptor. Now plug it into whichever framework you use:
207
+ That's the interceptor. Now plug it into whichever framework you use.
208
+ `@atrib/agent` types against each host framework structurally and does not
209
+ depend on any of them, so install the framework package you use
210
+ (`@modelcontextprotocol/sdk`, `@ai-sdk/mcp`, `agents`, `@langchain/mcp-adapters`,
211
+ or `@anthropic-ai/claude-agent-sdk`) alongside `@atrib/agent`.
192
212
 
193
213
  ### Raw `@modelcontextprotocol/sdk`
194
214
 
@@ -209,6 +229,7 @@ const client = wrapMcpClient(raw, interceptor, {
209
229
  ```ts
210
230
  import { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk'
211
231
  import { atrib as wrapServer } from '@atrib/mcp' // note: server-side package
232
+ import { z } from 'zod' // ships with the Claude Agent SDK
212
233
 
213
234
  const sdkServer = createSdkMcpServer({
214
235
  name: 'my-tools',
@@ -333,21 +354,25 @@ The entire atrib integration is wrapped in defensive error handling at every ada
333
354
 
334
355
  ## Spec references
335
356
 
336
- | Spec section | What it defines |
337
- | ------------ | ------------------------------------------------------------ |
338
- | [§1.3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#13-canonical-serialization) | JCS canonical serialization of records |
339
- | [§1.4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#14-signing-and-verification) | Ed25519 signing and verification |
340
- | [§1.5](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#15-context-propagation) | Context propagation via `params._meta` and W3C trace context |
341
- | [§1.7](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#17-transaction-event-hooks) | Transaction event hooks for all 6 payment protocols |
342
- | [§2](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#2-merkle-log-protocol) | Merkle log protocol (Tessera-backed, tlog-tiles spec) |
343
- | [§3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#3-graph-query-interface) | Graph query interface (fact layer only) |
344
- | [§4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#4-attribution-policy-format) | Policy format (merchant-side value distribution) |
345
- | [§5.3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#53-atribmcp-mcp-server-middleware) | Agent-side middleware behavior |
346
- | [§5.4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#54-atribagent-agent-middleware) | Path 1 / Path 2 transaction detection |
347
- | [§5.8](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#58-degradation-contract) | Degradation contract; silent failure never breaks the host |
357
+ | Spec section | What it defines |
358
+ | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
359
+ | [§1.3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#13-canonical-serialization) | JCS canonical serialization of records |
360
+ | [§1.4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#14-signing-and-verification) | Ed25519 signing and verification |
361
+ | [§1.5](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#15-context-propagation) | Context propagation via `params._meta` and W3C trace context |
362
+ | [§1.7](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#17-transaction-event-hooks) | Transaction event hooks for all 6 payment protocols |
363
+ | [§2](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#2-merkle-log-protocol) | Merkle log protocol (Tessera-backed, tlog-tiles spec) |
364
+ | [§3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#3-graph-query-interface) | Graph query interface (fact layer only) |
365
+ | [§4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#4-attribution-policy-format) | Policy format (merchant-side value distribution) |
366
+ | [§5.3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#53-atribmcp-mcp-server-middleware) | Agent-side middleware behavior |
367
+ | [§5.4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#54-atribagent-agent-middleware) | Path 1 / Path 2 transaction detection |
368
+ | [§5.8](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#58-degradation-contract) | Degradation contract; silent failure never breaks the host |
348
369
 
349
370
  The full protocol spec is at [`atrib-spec.md`](https://github.com/creatornader/atrib/blob/main/atrib-spec.md).
350
371
 
351
372
  ---
352
373
 
353
374
  > **A note on documentation links.** The atrib protocol repository is currently private (in-progress public preparation). Links in this README to the spec and sister packages (`atrib-spec.md`, `packages/agent/README.md`, etc.) point at `github.com/creatornader/atrib/blob/main/...` URLs that will resolve once the repository goes public. Until then, see [`atrib.dev`](https://atrib.dev) for the protocol overview.
375
+
376
+ ## Part of atrib
377
+
378
+ atrib is an open protocol for verifiable agent actions. Every action becomes a signed, chain-linked record that anyone can verify against a public Merkle log, with no operator to trust. This package is one entrypoint. See the [full package family](https://github.com/creatornader/atrib#packages) and the [protocol spec](https://github.com/creatornader/atrib/blob/main/atrib-spec.md).
@@ -0,0 +1,76 @@
1
+ import type { AtribRecord } from '@atrib/mcp';
2
+ export declare const ATTRIBUTION_EXTENSION_ID = "dev.atrib/attribution";
3
+ export declare const ATTRIBUTION_EXTENSION_VERSION = "0.1";
4
+ export declare const MCP_CLIENT_CAPABILITIES_META_KEY = "io.modelcontextprotocol/clientCapabilities";
5
+ /** Receipt verbosities a client can request (extension spec §4.2 `accept`). */
6
+ export declare const ATTRIBUTION_ACCEPT_VALUES: readonly ["token", "record"];
7
+ export type AttributionAcceptValue = (typeof ATTRIBUTION_ACCEPT_VALUES)[number];
8
+ /** The v0.1 receipt object (extension spec §6.2). */
9
+ export interface AttributionReceipt {
10
+ record_hash: string;
11
+ creator_key: string;
12
+ context_id: string;
13
+ event_type: string;
14
+ chain_root: string;
15
+ /** Queue status at response time — a claim of local signing, never an awaited proof. */
16
+ log_submission: 'queued' | 'submitted' | 'disabled' | 'failed';
17
+ }
18
+ /** The parsed, consistency-checked result block. */
19
+ export interface AttributionResultBlock {
20
+ /** Propagation token of the record named by the receipt. */
21
+ token: string;
22
+ receipt: AttributionReceipt;
23
+ /** Full signed record, present only when the server honored `accept: ["record"]`. */
24
+ record?: AtribRecord;
25
+ }
26
+ /** Options for {@link declareAttributionExtension}. */
27
+ export interface DeclareAttributionExtensionOptions {
28
+ /**
29
+ * Receipt verbosity negotiation (extension spec §4.2). Defaults to
30
+ * `['token']`. Add `'record'` to request the full signed record body in
31
+ * receipts for immediate signature re-verification.
32
+ */
33
+ accept?: readonly AttributionAcceptValue[];
34
+ /**
35
+ * Optional §1.5.2 propagation token to carry in the prefixed request
36
+ * block (extension spec §5). Malformed tokens are dropped with a warning.
37
+ */
38
+ token?: string;
39
+ /**
40
+ * Optional explicit 32-lowercase-hex context_id to carry in the prefixed
41
+ * request block. Malformed values are dropped with a warning.
42
+ */
43
+ contextId?: string;
44
+ }
45
+ /**
46
+ * Return a NEW `_meta` object that declares `dev.atrib/attribution` on this
47
+ * request (per-request client capabilities, stateless MCP model) and — when
48
+ * `token` / `contextId` are supplied — carries the prefixed request block.
49
+ *
50
+ * Non-destructive: existing `_meta` keys, existing `clientCapabilities`
51
+ * fields, and other declared extensions are preserved; only this extension's
52
+ * settings entry (and the prefixed block, when requested) are (re)written,
53
+ * which also makes the helper idempotent. The caller's object is never
54
+ * mutated. §5.8: any internal failure returns the caller's `_meta` shape
55
+ * unchanged (a shallow copy) with an `atrib:` warning — never a throw.
56
+ */
57
+ export declare function declareAttributionExtension(meta?: Record<string, unknown>, options?: DeclareAttributionExtensionOptions): Record<string, unknown>;
58
+ /**
59
+ * Parse the gated `dev.atrib/attribution` block from a tool result's
60
+ * `_meta` (extension spec §6). Returns the typed, consistency-checked block,
61
+ * or `undefined` when:
62
+ *
63
+ * - the block is absent (server pre-extension, or client undeclared) —
64
+ * silent, this is the normal legacy path;
65
+ * - the block is structurally malformed or internally inconsistent —
66
+ * `atrib:`-logged and DISCARDED per extension spec §6.2 ("a consumer
67
+ * that detects an internal inconsistency MUST treat the receipt as
68
+ * invalid and discard it").
69
+ *
70
+ * §5.8: never throws; receipt invalidity never invalidates the tool result.
71
+ * A valid return is a *claim of local signing*, not a proof: callers wanting
72
+ * Tier-3 assurance verify the attached record's signature (`verifyRecord`
73
+ * from @atrib/mcp) and log inclusion independently.
74
+ */
75
+ export declare function parseAttributionReceipt(resultMeta: unknown): AttributionResultBlock | undefined;
76
+ //# sourceMappingURL=extension-attribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-attribution.d.ts","sourceRoot":"","sources":["../src/extension-attribution.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAK7C,eAAO,MAAM,wBAAwB,0BAA0B,CAAA;AAC/D,eAAO,MAAM,6BAA6B,QAAQ,CAAA;AAClD,eAAO,MAAM,gCAAgC,+CAA+C,CAAA;AAE5F,+EAA+E;AAC/E,eAAO,MAAM,yBAAyB,8BAA+B,CAAA;AACrE,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAA;AAU/E,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,wFAAwF;IACxF,cAAc,EAAE,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAA;CAC/D;AAED,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACrC,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,kBAAkB,CAAA;IAC3B,qFAAqF;IACrF,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED,uDAAuD;AACvD,MAAM,WAAW,kCAAkC;IACjD;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAA;IAC1C;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,OAAO,GAAE,kCAAuC,GAC/C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAmDzB;AA4CD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,OAAO,GAClB,sBAAsB,GAAG,SAAS,CAkBpC"}
@@ -0,0 +1,199 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * `dev.atrib/attribution` MCP extension v0.1 — client-side helpers (D141 /
4
+ * spec §1.5.4.1; extension spec docs/extensions/dev.atrib-attribution/v0.1.md).
5
+ *
6
+ * Two surfaces, both opt-in and §5.8-shaped:
7
+ *
8
+ * - {@link declareAttributionExtension}: return a NEW outbound `_meta`
9
+ * that declares the extension per-request under the core-reserved
10
+ * `io.modelcontextprotocol/clientCapabilities` key (and optionally
11
+ * carries the prefixed request block: propagation token + explicit
12
+ * context_id). Never mutates the caller's object; idempotent.
13
+ * - {@link parseAttributionReceipt}: read the gated result block from
14
+ * `result._meta`, validate its structure and internal consistency per
15
+ * extension spec §6.2, and return a typed receipt — or `undefined` with
16
+ * an `atrib:`-prefixed warning when the block is absent, malformed, or
17
+ * inconsistent. Receipt invalidity never invalidates the tool result.
18
+ *
19
+ * Clients using these helpers keep writing the legacy carriers
20
+ * (`buildOutboundMeta` already emits `atrib`, `tracestate`, `X-Atrib-Chain`)
21
+ * so non-adopting servers keep chaining: the extension is upside, not a
22
+ * dependency.
23
+ */
24
+ import { base64urlEncode, canonicalRecord, decodeToken, encodeToken, hexEncode, sha256, } from '@atrib/mcp';
25
+ // Protocol-frozen strings, mirroring @atrib/mcp's extension-attribution
26
+ // module (the identifier freezes on publication per extension spec §3;
27
+ // breaking changes require a new identifier).
28
+ export const ATTRIBUTION_EXTENSION_ID = 'dev.atrib/attribution';
29
+ export const ATTRIBUTION_EXTENSION_VERSION = '0.1';
30
+ export const MCP_CLIENT_CAPABILITIES_META_KEY = 'io.modelcontextprotocol/clientCapabilities';
31
+ /** Receipt verbosities a client can request (extension spec §4.2 `accept`). */
32
+ export const ATTRIBUTION_ACCEPT_VALUES = ['token', 'record'];
33
+ const LOG_SUBMISSION_STATUSES = new Set([
34
+ 'queued',
35
+ 'submitted',
36
+ 'disabled',
37
+ 'failed',
38
+ ]);
39
+ const HEX32 = /^[0-9a-f]{32}$/;
40
+ function isPlainObject(value) {
41
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
42
+ }
43
+ /**
44
+ * Return a NEW `_meta` object that declares `dev.atrib/attribution` on this
45
+ * request (per-request client capabilities, stateless MCP model) and — when
46
+ * `token` / `contextId` are supplied — carries the prefixed request block.
47
+ *
48
+ * Non-destructive: existing `_meta` keys, existing `clientCapabilities`
49
+ * fields, and other declared extensions are preserved; only this extension's
50
+ * settings entry (and the prefixed block, when requested) are (re)written,
51
+ * which also makes the helper idempotent. The caller's object is never
52
+ * mutated. §5.8: any internal failure returns the caller's `_meta` shape
53
+ * unchanged (a shallow copy) with an `atrib:` warning — never a throw.
54
+ */
55
+ export function declareAttributionExtension(meta = {}, options = {}) {
56
+ const out = { ...meta };
57
+ try {
58
+ // Settings object per extension spec §4.2. Unknown accept values would
59
+ // be ignored server-side; we only ever emit recognized ones.
60
+ const accept = (options.accept ?? ['token']).filter((v) => ATTRIBUTION_ACCEPT_VALUES.includes(v));
61
+ const settings = {
62
+ version: ATTRIBUTION_EXTENSION_VERSION,
63
+ accept: accept.length > 0 ? [...new Set(accept)] : ['token'],
64
+ };
65
+ const existingCaps = out[MCP_CLIENT_CAPABILITIES_META_KEY];
66
+ const caps = isPlainObject(existingCaps) ? { ...existingCaps } : {};
67
+ const existingExtensions = caps.extensions;
68
+ const extensions = isPlainObject(existingExtensions)
69
+ ? { ...existingExtensions }
70
+ : {};
71
+ extensions[ATTRIBUTION_EXTENSION_ID] = settings;
72
+ caps.extensions = extensions;
73
+ out[MCP_CLIENT_CAPABILITIES_META_KEY] = caps;
74
+ // Prefixed request block (extension spec §5): exactly two fields in
75
+ // v0.1, both optional; malformed values are dropped, never thrown.
76
+ const block = {};
77
+ if (options.token !== undefined) {
78
+ if (typeof options.token === 'string' && decodeToken(options.token) !== null) {
79
+ block.token = options.token;
80
+ }
81
+ else {
82
+ console.warn('atrib: malformed propagation token, omitting from extension block');
83
+ }
84
+ }
85
+ if (options.contextId !== undefined) {
86
+ if (typeof options.contextId === 'string' && HEX32.test(options.contextId)) {
87
+ block.context_id = options.contextId;
88
+ }
89
+ else {
90
+ console.warn('atrib: malformed context_id, omitting from extension block');
91
+ }
92
+ }
93
+ if (Object.keys(block).length > 0) {
94
+ const existingBlock = out[ATTRIBUTION_EXTENSION_ID];
95
+ out[ATTRIBUTION_EXTENSION_ID] = isPlainObject(existingBlock)
96
+ ? { ...existingBlock, ...block }
97
+ : block;
98
+ }
99
+ return out;
100
+ }
101
+ catch (err) {
102
+ console.warn('atrib: declareAttributionExtension failed, passing meta through', err);
103
+ return { ...meta };
104
+ }
105
+ }
106
+ function isStructurallyReceiptBlock(block) {
107
+ if (!isPlainObject(block))
108
+ return false;
109
+ if (typeof block.token !== 'string')
110
+ return false;
111
+ const receipt = block.receipt;
112
+ if (!isPlainObject(receipt))
113
+ return false;
114
+ for (const field of [
115
+ 'record_hash',
116
+ 'creator_key',
117
+ 'context_id',
118
+ 'event_type',
119
+ 'chain_root',
120
+ 'log_submission',
121
+ ]) {
122
+ if (typeof receipt[field] !== 'string')
123
+ return false;
124
+ }
125
+ if (block.record !== undefined && !isPlainObject(block.record))
126
+ return false;
127
+ return true;
128
+ }
129
+ /**
130
+ * Internal-consistency check per extension spec §6.2: the token,
131
+ * `record_hash`, and `creator_key` must agree with each other and — when
132
+ * the full record body is attached — recompute from the record's canonical
133
+ * bytes. Mirrors `verifyAttributionReceipt` in @atrib/mcp.
134
+ */
135
+ function receiptIsConsistent(block) {
136
+ const decoded = decodeToken(block.token);
137
+ if (!decoded)
138
+ return false;
139
+ if (block.receipt.record_hash !== `sha256:${hexEncode(decoded.recordHash)}`)
140
+ return false;
141
+ if (block.receipt.creator_key !== base64urlEncode(decoded.creatorKey))
142
+ return false;
143
+ if (!LOG_SUBMISSION_STATUSES.has(block.receipt.log_submission))
144
+ return false;
145
+ if (block.record) {
146
+ if (block.token !== encodeToken(block.record))
147
+ return false;
148
+ const recordHashHex = hexEncode(sha256(canonicalRecord(block.record)));
149
+ if (block.receipt.record_hash !== `sha256:${recordHashHex}`)
150
+ return false;
151
+ if (block.receipt.creator_key !== block.record.creator_key)
152
+ return false;
153
+ if (block.receipt.context_id !== block.record.context_id)
154
+ return false;
155
+ if (block.receipt.chain_root !== block.record.chain_root)
156
+ return false;
157
+ }
158
+ return true;
159
+ }
160
+ /**
161
+ * Parse the gated `dev.atrib/attribution` block from a tool result's
162
+ * `_meta` (extension spec §6). Returns the typed, consistency-checked block,
163
+ * or `undefined` when:
164
+ *
165
+ * - the block is absent (server pre-extension, or client undeclared) —
166
+ * silent, this is the normal legacy path;
167
+ * - the block is structurally malformed or internally inconsistent —
168
+ * `atrib:`-logged and DISCARDED per extension spec §6.2 ("a consumer
169
+ * that detects an internal inconsistency MUST treat the receipt as
170
+ * invalid and discard it").
171
+ *
172
+ * §5.8: never throws; receipt invalidity never invalidates the tool result.
173
+ * A valid return is a *claim of local signing*, not a proof: callers wanting
174
+ * Tier-3 assurance verify the attached record's signature (`verifyRecord`
175
+ * from @atrib/mcp) and log inclusion independently.
176
+ */
177
+ export function parseAttributionReceipt(resultMeta) {
178
+ try {
179
+ if (!isPlainObject(resultMeta))
180
+ return undefined;
181
+ if (!(ATTRIBUTION_EXTENSION_ID in resultMeta))
182
+ return undefined;
183
+ const block = resultMeta[ATTRIBUTION_EXTENSION_ID];
184
+ if (!isStructurallyReceiptBlock(block)) {
185
+ console.warn('atrib: malformed dev.atrib/attribution receipt block, discarding');
186
+ return undefined;
187
+ }
188
+ if (!receiptIsConsistent(block)) {
189
+ console.warn('atrib: inconsistent dev.atrib/attribution receipt, discarding');
190
+ return undefined;
191
+ }
192
+ return block;
193
+ }
194
+ catch (err) {
195
+ console.warn('atrib: failed to parse dev.atrib/attribution receipt, discarding', err);
196
+ return undefined;
197
+ }
198
+ }
199
+ //# sourceMappingURL=extension-attribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-attribution.js","sourceRoot":"","sources":["../src/extension-attribution.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -15,4 +15,6 @@ export { attributeVercelAiSdkMcp } from './adapters/vercel-ai-sdk-mcp.js';
15
15
  export type { VercelAiSdkMcpClientLike, AttributeVercelAiSdkMcpOptions, } from './adapters/vercel-ai-sdk-mcp.js';
16
16
  export { attributeLangchainMcp } from './adapters/langchain-mcp.js';
17
17
  export type { LangchainMcpClientLike, LangchainMultiServerMcpClientLike, AttributeLangchainMcpOptions, } from './adapters/langchain-mcp.js';
18
+ export { ATTRIBUTION_ACCEPT_VALUES, ATTRIBUTION_EXTENSION_ID, ATTRIBUTION_EXTENSION_VERSION, MCP_CLIENT_CAPABILITIES_META_KEY, declareAttributionExtension, parseAttributionReceipt, } from './extension-attribution.js';
19
+ export type { AttributionAcceptValue, AttributionReceipt, AttributionResultBlock, DeclareAttributionExtensionOptions, } from './extension-attribution.js';
18
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAG7E,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AACzF,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC/D,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAG5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAG5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACrD,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAG1F,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAKtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AAC5E,YAAY,EACV,mBAAmB,EACnB,kCAAkC,GACnC,MAAM,gCAAgC,CAAA;AAMvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AACzE,YAAY,EACV,wBAAwB,EACxB,8BAA8B,GAC/B,MAAM,iCAAiC,CAAA;AAMxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA;AACnE,YAAY,EACV,sBAAsB,EACtB,iCAAiC,EACjC,4BAA4B,GAC7B,MAAM,6BAA6B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAG7E,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AACzF,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC/D,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAG5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAG5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACrD,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAG1F,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAKtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AAC5E,YAAY,EACV,mBAAmB,EACnB,kCAAkC,GACnC,MAAM,gCAAgC,CAAA;AAMvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AACzE,YAAY,EACV,wBAAwB,EACxB,8BAA8B,GAC/B,MAAM,iCAAiC,CAAA;AAMxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA;AACnE,YAAY,EACV,sBAAsB,EACtB,iCAAiC,EACjC,4BAA4B,GAC7B,MAAM,6BAA6B,CAAA;AAKpC,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,gCAAgC,EAChC,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,4BAA4B,CAAA;AACnC,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,kCAAkC,GACnC,MAAM,4BAA4B,CAAA"}
package/dist/index.js CHANGED
@@ -24,4 +24,8 @@ export { attributeVercelAiSdkMcp } from './adapters/vercel-ai-sdk-mcp.js';
24
24
  // outbound `tools/call` (and every forked client from per-call-header
25
25
  // workflows) flows through atrib's interceptor.
26
26
  export { attributeLangchainMcp } from './adapters/langchain-mcp.js';
27
+ // dev.atrib/attribution MCP extension v0.1, client side (D141 / spec
28
+ // §1.5.4.1). Declare the extension per-request and parse gated receipts
29
+ // from result._meta; both §5.8-safe, both opt-in.
30
+ export { ATTRIBUTION_ACCEPT_VALUES, ATTRIBUTION_EXTENSION_ID, ATTRIBUTION_EXTENSION_VERSION, MCP_CLIENT_CAPABILITIES_META_KEY, declareAttributionExtension, parseAttributionReceipt, } from './extension-attribution.js';
27
31
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,2BAA2B;AAE3B,8BAA8B;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAGvC,qCAAqC;AACrC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAIzF,wBAAwB;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAGpD,qBAAqB;AACrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAGrD,qBAAqB;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAGxD,2EAA2E;AAC3E,wEAAwE;AACxE,yCAAyC;AACzC,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AAM5E,4EAA4E;AAC5E,2EAA2E;AAC3E,6DAA6D;AAC7D,0EAA0E;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAMzE,+EAA+E;AAC/E,8EAA8E;AAC9E,sEAAsE;AACtE,gDAAgD;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,2BAA2B;AAE3B,8BAA8B;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAGvC,qCAAqC;AACrC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAIzF,wBAAwB;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAGpD,qBAAqB;AACrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAGrD,qBAAqB;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAGxD,2EAA2E;AAC3E,wEAAwE;AACxE,yCAAyC;AACzC,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AAM5E,4EAA4E;AAC5E,2EAA2E;AAC3E,6DAA6D;AAC7D,0EAA0E;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAMzE,+EAA+E;AAC/E,8EAA8E;AAC9E,sEAAsE;AACtE,gDAAgD;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA;AAOnE,qEAAqE;AACrE,wEAAwE;AACxE,kDAAkD;AAClD,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,gCAAgC,EAChC,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,4BAA4B,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atrib/agent",
3
- "version": "0.2.23",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -13,10 +13,13 @@
13
13
  "files": [
14
14
  "dist"
15
15
  ],
16
- "description": "Agent middleware for atrib. Interceptor plus framework adapters for MCP attribution. Supports raw SDK, Claude Agent SDK, Cloudflare Agents, Vercel AI SDK, LangChain JS.",
16
+ "description": "Client-side middleware for atrib's verifiable action layer. Adds chain context, gap records, and transaction fallback records across MCP framework adapters.",
17
17
  "author": "atrib <hello@atrib.dev>",
18
18
  "license": "Apache-2.0",
19
19
  "homepage": "https://atrib.dev",
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
20
23
  "keywords": [
21
24
  "mcp",
22
25
  "model-context-protocol",
@@ -33,8 +36,8 @@
33
36
  "@noble/ed25519": "^3.1.0",
34
37
  "@noble/hashes": "^2.2.0",
35
38
  "canonicalize": "^3.0.0",
36
- "@atrib/mcp": "0.18.1",
37
- "@atrib/verify": "0.7.10"
39
+ "@atrib/mcp": "0.19.1",
40
+ "@atrib/verify": "0.8.1"
38
41
  },
39
42
  "devDependencies": {
40
43
  "@types/node": "^25.9.3",