@atrib/agent 0.2.22 → 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 +42 -34
- package/dist/extension-attribution.d.ts +76 -0
- package/dist/extension-attribution.d.ts.map +1 -0
- package/dist/extension-attribution.js +199 -0
- package/dist/extension-attribution.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,26 +1,34 @@
|
|
|
1
1
|
# `@atrib/agent`
|
|
2
2
|
|
|
3
|
-
**
|
|
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
|
+
|
|
11
19
|
## Coverage Matrix 1: MCP Framework Adapters
|
|
12
20
|
|
|
13
|
-
| Framework | Package | Adapter helper
|
|
14
|
-
| ------------------------------------------ | -------------------------------- |
|
|
15
|
-
| **Raw `@modelcontextprotocol/sdk` Client** | `@modelcontextprotocol/sdk` | `wrapMcpClient(client, interceptor, { serverUrl? })`
|
|
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 })`
|
|
19
|
-
| **Vercel AI SDK MCP** | `@ai-sdk/mcp` | `attributeVercelAiSdkMcp(mcpClient, { interceptor, serverUrl })`
|
|
20
|
-
| **LangChain JS MCP adapters** | `@langchain/mcp-adapters` | **High-level:** `attributeLangchainMcp(multiClient, { interceptor, serverUrls })`
|
|
21
|
-
| | | **Low-level:** `wrapMcpClient(rawClient, interceptor)` passed to `loadMcpTools(name, wrapped)`
|
|
22
|
-
| **OpenAI Agents SDK** | `@openai/agents` | _(planned. custom transport architecture, not `@modelcontextprotocol/sdk`)_
|
|
23
|
-
| **Mastra** | `@mastra/mcp` | _(planned. receipt proof covers `MCPClient` + `MCPServer` over stdio)_
|
|
21
|
+
| Framework | Package | Adapter helper | Integration shape | Status |
|
|
22
|
+
| ------------------------------------------ | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ---------- |
|
|
23
|
+
| **Raw `@modelcontextprotocol/sdk` Client** | `@modelcontextprotocol/sdk` | `wrapMcpClient(client, interceptor, { serverUrl? })` | Proxy-based wrapper, returns new client | ✅ Shipped |
|
|
24
|
+
| **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 |
|
|
25
|
+
| | | **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 |
|
|
26
|
+
| **Cloudflare Agents** | `agents` | `attributeCloudflareAgentMcp(agent, { interceptor, serverUrls })` | Walks `agent.mcp.mcpConnections`, replaces `.client` via `wrapMcpClient` | ✅ Shipped |
|
|
27
|
+
| **Vercel AI SDK MCP** | `@ai-sdk/mcp` | `attributeVercelAiSdkMcp(mcpClient, { interceptor, serverUrl })` | Monkey-patches `mcpClient.request()` (custom JSON-RPC, not SDK Client) | ✅ Shipped |
|
|
28
|
+
| **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 |
|
|
29
|
+
| | | **Low-level:** `wrapMcpClient(rawClient, interceptor)` passed to `loadMcpTools(name, wrapped)` | Reuses raw-SDK wrapper path | ✅ Shipped |
|
|
30
|
+
| **OpenAI Agents SDK** | `@openai/agents` | _(planned. custom transport architecture, not `@modelcontextprotocol/sdk`)_ | Planned: subclass `MCPServerSSE` / `MCPServerStdio` / `MCPServerStreamableHttp` | ⏳ Planned |
|
|
31
|
+
| **Mastra** | `@mastra/mcp` | _(planned. receipt proof covers `MCPClient` + `MCPServer` over stdio)_ | Adapter pending | 🧪 Proof |
|
|
24
32
|
|
|
25
33
|
**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
34
|
|
|
@@ -30,14 +38,14 @@ Two coverage surfaces define what you get:
|
|
|
30
38
|
|
|
31
39
|
All detection logic lives in `packages/agent/src/transaction.ts` and runs against unit tests for each protocol's published spec.
|
|
32
40
|
|
|
33
|
-
| Protocol
|
|
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`
|
|
37
|
-
| **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
|
|
40
|
-
| **a2a-x402**
|
|
41
|
+
| Protocol | Sponsor / origin | Detection signal | Spec reference |
|
|
42
|
+
| ------------------------------------ | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| **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) |
|
|
44
|
+
| **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) |
|
|
45
|
+
| **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) |
|
|
46
|
+
| **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) |
|
|
47
|
+
| **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) |
|
|
48
|
+
| **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
49
|
|
|
42
50
|
**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
51
|
|
|
@@ -45,7 +53,7 @@ All detection logic lives in `packages/agent/src/transaction.ts` and runs agains
|
|
|
45
53
|
|
|
46
54
|
### What each detector actually looks for on the wire
|
|
47
55
|
|
|
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
|
|
56
|
+
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
57
|
|
|
50
58
|
#### ACP: Stripe / OpenAI Agentic Commerce Protocol
|
|
51
59
|
|
|
@@ -333,18 +341,18 @@ The entire atrib integration is wrapped in defensive error handling at every ada
|
|
|
333
341
|
|
|
334
342
|
## Spec references
|
|
335
343
|
|
|
336
|
-
| Spec section
|
|
337
|
-
|
|
|
338
|
-
| [§1.3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#13-canonical-serialization)
|
|
339
|
-
| [§1.4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#14-signing-and-verification)
|
|
340
|
-
| [§1.5](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#15-context-propagation)
|
|
341
|
-
| [§1.7](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#17-transaction-event-hooks)
|
|
342
|
-
| [§2](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#2-merkle-log-protocol)
|
|
343
|
-
| [§3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#3-graph-query-interface)
|
|
344
|
-
| [§4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#4-attribution-policy-format)
|
|
345
|
-
| [§5.3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#53-atribmcp-mcp-server-middleware)
|
|
346
|
-
| [§5.4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#54-atribagent-agent-middleware)
|
|
347
|
-
| [§5.8](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#58-degradation-contract)
|
|
344
|
+
| Spec section | What it defines |
|
|
345
|
+
| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
346
|
+
| [§1.3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#13-canonical-serialization) | JCS canonical serialization of records |
|
|
347
|
+
| [§1.4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#14-signing-and-verification) | Ed25519 signing and verification |
|
|
348
|
+
| [§1.5](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#15-context-propagation) | Context propagation via `params._meta` and W3C trace context |
|
|
349
|
+
| [§1.7](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#17-transaction-event-hooks) | Transaction event hooks for all 6 payment protocols |
|
|
350
|
+
| [§2](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#2-merkle-log-protocol) | Merkle log protocol (Tessera-backed, tlog-tiles spec) |
|
|
351
|
+
| [§3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#3-graph-query-interface) | Graph query interface (fact layer only) |
|
|
352
|
+
| [§4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#4-attribution-policy-format) | Policy format (merchant-side value distribution) |
|
|
353
|
+
| [§5.3](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#53-atribmcp-mcp-server-middleware) | Agent-side middleware behavior |
|
|
354
|
+
| [§5.4](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#54-atribagent-agent-middleware) | Path 1 / Path 2 transaction detection |
|
|
355
|
+
| [§5.8](https://github.com/creatornader/atrib/blob/main/atrib-spec.md#58-degradation-contract) | Degradation contract; silent failure never breaks the host |
|
|
348
356
|
|
|
349
357
|
The full protocol spec is at [`atrib-spec.md`](https://github.com/creatornader/atrib/blob/main/atrib-spec.md).
|
|
350
358
|
|
|
@@ -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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"files": [
|
|
14
14
|
"dist"
|
|
15
15
|
],
|
|
16
|
-
"description": "
|
|
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",
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
"@noble/ed25519": "^3.1.0",
|
|
34
34
|
"@noble/hashes": "^2.2.0",
|
|
35
35
|
"canonicalize": "^3.0.0",
|
|
36
|
-
"@atrib/mcp": "0.
|
|
37
|
-
"@atrib/verify": "0.
|
|
36
|
+
"@atrib/mcp": "0.19.0",
|
|
37
|
+
"@atrib/verify": "0.8.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@types/node": "^25.9.
|
|
40
|
+
"@types/node": "^25.9.3",
|
|
41
41
|
"typescript": "^6.0.3",
|
|
42
42
|
"vitest": "^4.1.8"
|
|
43
43
|
},
|