aotrust-mcp 0.0.0-stage → 0.1.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 +21 -0
- package/README.md +106 -2
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +25 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +29 -0
- package/dist/client.js +104 -0
- package/dist/client.js.map +1 -0
- package/dist/env.d.ts +13 -0
- package/dist/env.js +14 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +181 -0
- package/dist/index.js.map +1 -0
- package/dist/payment.d.ts +13 -0
- package/dist/payment.js +97 -0
- package/dist/payment.js.map +1 -0
- package/dist/tools.d.ts +63 -0
- package/dist/tools.js +213 -0
- package/dist/tools.js.map +1 -0
- package/package.json +39 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GitSerge-crypto
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,107 @@
|
|
|
1
|
-
#
|
|
1
|
+
# aotrust-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<!-- mcp-name: aotrust-mcp -->
|
|
4
|
+
|
|
5
|
+
Local stdio MCP server for **AOTrust** notarization: cryptographic
|
|
6
|
+
proof-of-existence for AI artifacts, wired into any MCP-capable agent
|
|
7
|
+
(Claude Code, Codex, and friends) with a one-line config.
|
|
8
|
+
|
|
9
|
+
Five tools over the AOTrust HTTP API (`https://api.aotrust.link`):
|
|
10
|
+
|
|
11
|
+
| Tool | Cost | What it does |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| `notary_status` | free | job_id → `{status, result{pdr_b64, payment_hash, near_anchor_tx,...}}` (upstream JSON verbatim) |
|
|
14
|
+
| `notary_verify` | free | full server-side PDR verification by base64 bundle |
|
|
15
|
+
| `notary_lookup` | free | 8-hex Shield ID → record (server-form 400 guard locally for bad shape) |
|
|
16
|
+
| `notary_free` | free | UNPAID notarization, no wallet, 5/IP/24h — pass `work_hash` OR `content` (≤60KB) |
|
|
17
|
+
| `notary_notarize` | **$0.01 USDC per receipt** | PAID via x402 (challenge → EIP-3009 sign → retry); **requires `AOTRUST_EVM_PRIVATE_KEY`** |
|
|
18
|
+
|
|
19
|
+
All tool replies pass the upstream JSON through **verbatim** — no invented
|
|
20
|
+
fields, error codes unmodified (`FREE_TIER_LIMIT_REACHED` on free tier is
|
|
21
|
+
quota, not a defect).
|
|
22
|
+
|
|
23
|
+
## Install & run
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g aotrust-mcp # or: npx aotrust-mcp
|
|
27
|
+
aotrust-mcp # starts the stdio MCP server
|
|
28
|
+
aotrust-mcp --tools # print tool-spec JSON and exit
|
|
29
|
+
aotrust-mcp --version # 0.1.0
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Claude Code config
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"mcpServers": {
|
|
37
|
+
"aotrust": {
|
|
38
|
+
"command": "npx",
|
|
39
|
+
"args": ["-y", "aotrust-mcp"],
|
|
40
|
+
"env": {
|
|
41
|
+
"AOTRUST_EVM_PRIVATE_KEY": "0x..."
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Free tools work with no env at all; only `notary_notarize` needs the key.
|
|
49
|
+
|
|
50
|
+
## Environment variables
|
|
51
|
+
|
|
52
|
+
| Var | Required | Meaning |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `AOTRUST_EVM_PRIVATE_KEY` | only for `notary_notarize` | EVM wallet private key (0x-prefixed). Consumed by the x402 EIP-3009 signer. **Never logged or shipped in errors.** |
|
|
55
|
+
| `AOTRUST_BASE_URL` | optional | API base, default `https://api.aotrust.link` (no `/v1` suffix — the client appends paths) |
|
|
56
|
+
|
|
57
|
+
## Paid path notes (v0.1)
|
|
58
|
+
|
|
59
|
+
- **Base-only.** The HTTP `/notarize` rail settles EIP-3009 USDC on Base
|
|
60
|
+
(`eip155:8453`). Solana payments exist only on the remote MCP server
|
|
61
|
+
(`link.aotrust/notary` in the registry) and are out of scope for this
|
|
62
|
+
stdio wrapper in v0.1 — point Solana-capable agents at the remote server.
|
|
63
|
+
- challenge/sign/retry is done by `@x402/fetch` (challenge from the server's
|
|
64
|
+
402 response, EIP-3009 signature, retry with the `x-payment` header).
|
|
65
|
+
No facilitator client-side.
|
|
66
|
+
- `AOTRUST_EVM_PRIVATE_KEY` never appears in logs, error messages, or
|
|
67
|
+
tool output. A missing key yields a plain
|
|
68
|
+
`MISSING_PRIVATE_KEY / set AOTRUST_EVM_PRIVATE_KEY ...` reply before any
|
|
69
|
+
network call.
|
|
70
|
+
|
|
71
|
+
## Limits
|
|
72
|
+
|
|
73
|
+
- Free tier: **5 notarizations per IP per 24h** (1000/day global). 429 →
|
|
74
|
+
wait, or switch to the paid rail.
|
|
75
|
+
- Paid: flat **$0.01** per receipt, no subscription.
|
|
76
|
+
- Verification: free forever, offline-capable via the 239-byte PDR format.
|
|
77
|
+
|
|
78
|
+
## Verification of proofs
|
|
79
|
+
|
|
80
|
+
PDRs are Ed25519-signed 239-byte bundles anchored daily in Merkle trees on
|
|
81
|
+
NEAR mainnet. Verify any receipt at <https://verify.aotrust.link>, or with
|
|
82
|
+
`notary_verify` / `notary_lookup` from this server.
|
|
83
|
+
|
|
84
|
+
## Docs
|
|
85
|
+
|
|
86
|
+
- AOTrust docs: <https://docs.aotrust.link>
|
|
87
|
+
- Python SDK: <https://pypi.org/project/aotrust-protocol/>
|
|
88
|
+
- x402: <https://x402.org>
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## aotrust-mcp (кратко, RU)
|
|
97
|
+
|
|
98
|
+
Локальный stdio MCP-сервер нотариата AOTrust — 5 инструментов поверх HTTP API:
|
|
99
|
+
`notary_status`, `notary_verify`, `notary_lookup` (бесплатные, read-only),
|
|
100
|
+
`notary_free` (бесплатный PDR, лимит 5/IP/24h) и `notary_notarize`
|
|
101
|
+
(**$0.01 USDC за PDR**, платный; требует `AOTRUST_EVM_PRIVATE_KEY`).
|
|
102
|
+
Ключ расходуется только на EIP-3009-подпись через x402 и никогда не попадает
|
|
103
|
+
в логи/ошибки. Платная рельса v0.1 — **только Base**; Solana доступна через
|
|
104
|
+
удалённый MCP-сервер из registry (`link.aotrust/notary`). Конфиг Claude Code —
|
|
105
|
+
одна строка (`npx aotrust-mcp`) + env-ключ. Ответы тулов — upstream JSON
|
|
106
|
+
без изменений; коды ошибок (`FREE_TIER_LIMIT_REACHED` и др.) пробрасываются
|
|
107
|
+
как есть.
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* cli.ts — stdio bootstrap for aotrust-mcp.
|
|
4
|
+
*
|
|
5
|
+
* Flags:
|
|
6
|
+
* --tools print JSON tool-specs and exit 0
|
|
7
|
+
* --version print package version and exit 0
|
|
8
|
+
* default: start the MCP stdio server (src/index.ts).
|
|
9
|
+
*/
|
|
10
|
+
import { createRequire } from "node:module";
|
|
11
|
+
import { TOOL_SPECS } from "./tools.js";
|
|
12
|
+
import { runServer } from "./index.js";
|
|
13
|
+
const require = createRequire(import.meta.url);
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
if (args.includes("--version")) {
|
|
16
|
+
const pkg = require("../package.json");
|
|
17
|
+
process.stdout.write(`${pkg.version}\n`);
|
|
18
|
+
process.exit(0);
|
|
19
|
+
}
|
|
20
|
+
if (args.includes("--tools")) {
|
|
21
|
+
process.stdout.write(`${JSON.stringify({ tools: TOOL_SPECS }, null, 2)}\n`);
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
await runServer();
|
|
25
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;IAC9D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;IAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,SAAS,EAAE,CAAC"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare class ApiError extends Error {
|
|
2
|
+
/** HTTP status of the failed call. */
|
|
3
|
+
readonly status: number;
|
|
4
|
+
/** Upstream error code, verbatim (never rephrased). */
|
|
5
|
+
readonly code: string;
|
|
6
|
+
/** Upstream raw body, verbatim JSON if parseable. */
|
|
7
|
+
readonly body: unknown;
|
|
8
|
+
constructor(status: number, code: string, body: unknown);
|
|
9
|
+
}
|
|
10
|
+
export declare function getBaseUrl(): string;
|
|
11
|
+
/** quote_plus equivalent: '+' → %2B, '/' → %2F, '=' → %3D (percent-tolerant path). */
|
|
12
|
+
export declare function encodePdrB64(pdr_b64: string): string;
|
|
13
|
+
export type UpstreamResponse = {
|
|
14
|
+
status: number;
|
|
15
|
+
body: unknown;
|
|
16
|
+
};
|
|
17
|
+
/** GET /v1/status/{job_id} — passthrough, never touched. */
|
|
18
|
+
export declare function getStatus(jobId: string): Promise<UpstreamResponse>;
|
|
19
|
+
/** GET /v1/pdr/verify/{pdr_b64} — pdr_b64 quote_plus-encoded. */
|
|
20
|
+
export declare function verifyPdr(pdrB64: string): Promise<UpstreamResponse>;
|
|
21
|
+
/**
|
|
22
|
+
* GET /v1/shield/lookup/{shield_id} — shield_id must be EXACTLY 8 hex.
|
|
23
|
+
* Non-conforming shape is rejected LOCALLY with the server's verbatim error
|
|
24
|
+
* form (400/INVALID_SHIELD_ID/"Shield ID must be 8 hexadecimal characters")
|
|
25
|
+
* — zero network for a call the server would reject anyway.
|
|
26
|
+
*/
|
|
27
|
+
export declare function shieldLookup(shieldId: string): Promise<UpstreamResponse>;
|
|
28
|
+
/** POST /v1/shield/free — body verbatim from the tool layer. */
|
|
29
|
+
export declare function shieldFree(body: Record<string, unknown>): Promise<UpstreamResponse>;
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* client.ts — HTTP layer for the AOTrust API.
|
|
3
|
+
*
|
|
4
|
+
* Base URL comes from env AOTRUST_BASE_URL (default https://api.aotrust.link).
|
|
5
|
+
* No host constants live in tool code — env-aware, same pattern as the server.
|
|
6
|
+
*
|
|
7
|
+
* URL-encoding contract (verified against the live API, 16.10):
|
|
8
|
+
* /v1/pdr/verify/{pdr_b64} expects Python quote_plus equivalents:
|
|
9
|
+
* '+' → %2B, '/' → %2F, '=' → '%3D'. The API regex tolerates the percent
|
|
10
|
+
* escapes; encodeURI/encodeURIComponent default sets are NOT sufficient
|
|
11
|
+
* (encodeURIComponent leaves '+' intact and encodes '/' as %2F — that part
|
|
12
|
+
* matches, but '+' must be escaped too because '+' in a URL path decodes
|
|
13
|
+
* to a space in some frontends).
|
|
14
|
+
*
|
|
15
|
+
* Everything about response bodies is passed through verbatim: the AOTrust
|
|
16
|
+
* error fields (error / message / detail) are load-bearing for clients.
|
|
17
|
+
*/
|
|
18
|
+
import { AOTRUST_BASE_URL_ENV, DEFAULT_BASE_URL, INVALID_SHIELD_ID_ERR, INVALID_SHIELD_ID_MSG, USER_AGENT } from "./env.js";
|
|
19
|
+
export class ApiError extends Error {
|
|
20
|
+
/** HTTP status of the failed call. */
|
|
21
|
+
status;
|
|
22
|
+
/** Upstream error code, verbatim (never rephrased). */
|
|
23
|
+
code;
|
|
24
|
+
/** Upstream raw body, verbatim JSON if parseable. */
|
|
25
|
+
body;
|
|
26
|
+
constructor(status, code, body) {
|
|
27
|
+
super(code);
|
|
28
|
+
this.name = "ApiError";
|
|
29
|
+
this.status = status;
|
|
30
|
+
this.code = code;
|
|
31
|
+
this.body = body;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function getBaseUrl() {
|
|
35
|
+
const env = process.env[AOTRUST_BASE_URL_ENV];
|
|
36
|
+
const raw = env && env.trim().length > 0 ? env : DEFAULT_BASE_URL;
|
|
37
|
+
return raw.replace(/\/+$/, "");
|
|
38
|
+
}
|
|
39
|
+
/** quote_plus equivalent: '+' → %2B, '/' → %2F, '=' → %3D (percent-tolerant path). */
|
|
40
|
+
export function encodePdrB64(pdr_b64) {
|
|
41
|
+
return pdr_b64
|
|
42
|
+
.replace(/\+/g, "%2B")
|
|
43
|
+
.replace(/\//g, "%2F")
|
|
44
|
+
.replace(/=/g, "%3D");
|
|
45
|
+
}
|
|
46
|
+
async function requestJson(method, path, body, extraHeaders) {
|
|
47
|
+
const url = `${getBaseUrl()}${path}`;
|
|
48
|
+
const headers = {
|
|
49
|
+
"User-Agent": USER_AGENT,
|
|
50
|
+
...(extraHeaders ?? {}),
|
|
51
|
+
};
|
|
52
|
+
let payload;
|
|
53
|
+
if (body !== undefined) {
|
|
54
|
+
headers["Content-Type"] = "application/json";
|
|
55
|
+
payload = JSON.stringify(body);
|
|
56
|
+
}
|
|
57
|
+
const res = await fetch(url, {
|
|
58
|
+
method,
|
|
59
|
+
headers,
|
|
60
|
+
body: payload,
|
|
61
|
+
});
|
|
62
|
+
let parsed = null;
|
|
63
|
+
const text = await res.text();
|
|
64
|
+
try {
|
|
65
|
+
parsed = JSON.parse(text);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
parsed = text;
|
|
69
|
+
}
|
|
70
|
+
if (!res.ok) {
|
|
71
|
+
const obj = (parsed && typeof parsed === "object" ? parsed : {});
|
|
72
|
+
const code = typeof obj["error"] === "string" ? obj["error"] : `HTTP_${res.status}`;
|
|
73
|
+
throw new ApiError(res.status, code, parsed);
|
|
74
|
+
}
|
|
75
|
+
return { status: res.status, body: parsed };
|
|
76
|
+
}
|
|
77
|
+
/** GET /v1/status/{job_id} — passthrough, never touched. */
|
|
78
|
+
export async function getStatus(jobId) {
|
|
79
|
+
return requestJson("GET", `/v1/status/${encodeURIComponent(jobId)}`);
|
|
80
|
+
}
|
|
81
|
+
/** GET /v1/pdr/verify/{pdr_b64} — pdr_b64 quote_plus-encoded. */
|
|
82
|
+
export async function verifyPdr(pdrB64) {
|
|
83
|
+
return requestJson("GET", `/v1/pdr/verify/${encodePdrB64(pdrB64)}`);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* GET /v1/shield/lookup/{shield_id} — shield_id must be EXACTLY 8 hex.
|
|
87
|
+
* Non-conforming shape is rejected LOCALLY with the server's verbatim error
|
|
88
|
+
* form (400/INVALID_SHIELD_ID/"Shield ID must be 8 hexadecimal characters")
|
|
89
|
+
* — zero network for a call the server would reject anyway.
|
|
90
|
+
*/
|
|
91
|
+
export async function shieldLookup(shieldId) {
|
|
92
|
+
if (!/^[0-9a-fA-F]{8}$/.test(shieldId)) {
|
|
93
|
+
throw new ApiError(400, INVALID_SHIELD_ID_ERR, {
|
|
94
|
+
error: INVALID_SHIELD_ID_ERR,
|
|
95
|
+
message: INVALID_SHIELD_ID_MSG,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return requestJson("GET", `/v1/shield/lookup/${encodeURIComponent(shieldId)}`);
|
|
99
|
+
}
|
|
100
|
+
/** POST /v1/shield/free — body verbatim from the tool layer. */
|
|
101
|
+
export async function shieldFree(body) {
|
|
102
|
+
return requestJson("POST", "/v1/shield/free", body);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* env.ts — env-var names and defaults (single source of truth).
|
|
3
|
+
*
|
|
4
|
+
* AOTRUST_EVM_PRIVATE_KEY is NEVER read into a string here or printed
|
|
5
|
+
* anywhere; the x402 wrapper consumes it through its own signer.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_BASE_URL = "https://api.aotrust.link";
|
|
8
|
+
export declare const AOTRUST_BASE_URL_ENV = "AOTRUST_BASE_URL";
|
|
9
|
+
export declare const AOTRUST_EVM_PRIVATE_KEY_ENV = "AOTRUST_EVM_PRIVATE_KEY";
|
|
10
|
+
export declare const USER_AGENT = "aotrust-mcp/0.1.0 (+https://aotrust.link)";
|
|
11
|
+
/** Server-form error for an invalid shield_id (verbatim, load-bearing). */
|
|
12
|
+
export declare const INVALID_SHIELD_ID_ERR = "INVALID_SHIELD_ID";
|
|
13
|
+
export declare const INVALID_SHIELD_ID_MSG = "Shield ID must be 8 hexadecimal characters";
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* env.ts — env-var names and defaults (single source of truth).
|
|
3
|
+
*
|
|
4
|
+
* AOTRUST_EVM_PRIVATE_KEY is NEVER read into a string here or printed
|
|
5
|
+
* anywhere; the x402 wrapper consumes it through its own signer.
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_BASE_URL = "https://api.aotrust.link";
|
|
8
|
+
export const AOTRUST_BASE_URL_ENV = "AOTRUST_BASE_URL";
|
|
9
|
+
export const AOTRUST_EVM_PRIVATE_KEY_ENV = "AOTRUST_EVM_PRIVATE_KEY";
|
|
10
|
+
export const USER_AGENT = "aotrust-mcp/0.1.0 (+https://aotrust.link)";
|
|
11
|
+
/** Server-form error for an invalid shield_id (verbatim, load-bearing). */
|
|
12
|
+
export const INVALID_SHIELD_ID_ERR = "INVALID_SHIELD_ID";
|
|
13
|
+
export const INVALID_SHIELD_ID_MSG = "Shield ID must be 8 hexadecimal characters";
|
|
14
|
+
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAC3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AACvD,MAAM,CAAC,MAAM,2BAA2B,GAAG,yBAAyB,CAAC;AACrE,MAAM,CAAC,MAAM,UAAU,GAAG,2CAA2C,CAAC;AAEtE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,mBAAmB,CAAC;AACzD,MAAM,CAAC,MAAM,qBAAqB,GAAG,4CAA4C,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runServer(): Promise<void>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* index.ts — MCP stdio server registration (five tools).
|
|
3
|
+
*
|
|
4
|
+
* Responses follow src/tools.ts: upstream JSON verbatim in structuredContent
|
|
5
|
+
* + content[0]; errors passed through with code + message (no rephrasing).
|
|
6
|
+
* Registration uses ZodRawShape (plain objects) — the @modelcontextprotocol/sdk
|
|
7
|
+
* 1.32 `registerTool` contract (not z.object wrappers).
|
|
8
|
+
*/
|
|
9
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import { toolNotaryFree, toolNotaryLookup, toolNotaryStatus, toolNotaryVerify, toolNotaryNotarize, } from "./tools.js";
|
|
13
|
+
const RAW_STATUS = { job_id: z.string().min(1).describe("Job id from notarization response") };
|
|
14
|
+
const RAW_VERIFY = { pdr_b64: z.string().min(1).describe("PDR bundle in base64") };
|
|
15
|
+
const RAW_LOOKUP = { shield_id: z.string().min(1).describe("Shield ID — 8 hex characters") };
|
|
16
|
+
const RAW_FREE = {
|
|
17
|
+
work_hash: z.string().optional().describe("sha256 hex (64 chars) — Mode A"),
|
|
18
|
+
content: z.string().optional().describe("raw text/code ≤60KB — Mode B"),
|
|
19
|
+
agent_sig: z.string().optional().describe("optional bilateral signature"),
|
|
20
|
+
agent_pubkey: z.string().optional().describe("optional bilateral public key"),
|
|
21
|
+
};
|
|
22
|
+
const RAW_NOTARIZE = RAW_FREE;
|
|
23
|
+
function validateFree(raw, toolName) {
|
|
24
|
+
const r = (raw ?? {});
|
|
25
|
+
const hasWh = typeof r["work_hash"] === "string" && r["work_hash"] !== "";
|
|
26
|
+
const hasContent = typeof r["content"] === "string" && r["content"] !== "";
|
|
27
|
+
if (hasWh === hasContent) {
|
|
28
|
+
return {
|
|
29
|
+
errorReply: {
|
|
30
|
+
error: "VALIDATION_ERROR",
|
|
31
|
+
message: `${toolName}: exactly one of work_hash or content is required`,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const out = {};
|
|
36
|
+
if (hasWh)
|
|
37
|
+
out["work_hash"] = r["work_hash"];
|
|
38
|
+
if (hasContent)
|
|
39
|
+
out["content"] = r["content"];
|
|
40
|
+
for (const k of ["agent_sig", "agent_pubkey"]) {
|
|
41
|
+
const v = r[k];
|
|
42
|
+
if (typeof v === "string" && v !== "")
|
|
43
|
+
out[k] = v;
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
export async function runServer() {
|
|
48
|
+
const server = new McpServer({ name: "aotrust-mcp", version: "0.1.1" }, {
|
|
49
|
+
instructions: "AOTrust notary: cryptographic proof-of-existence for AI artifacts. " +
|
|
50
|
+
"Start with notary_free (no wallet) or notary_notarize ($0.01 USDC, Base). " +
|
|
51
|
+
"notary_status / notary_verify / notary_lookup are read-only.",
|
|
52
|
+
});
|
|
53
|
+
const okReply = (structured) => ({
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: "text",
|
|
57
|
+
text: typeof structured === "string" ? structured : JSON.stringify(structured, null, 2),
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
structuredContent: structured,
|
|
61
|
+
isError: false,
|
|
62
|
+
});
|
|
63
|
+
const errReply = (structured) => ({
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: typeof structured === "string" ? structured : JSON.stringify(structured, null, 2),
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
structuredContent: structured,
|
|
71
|
+
isError: true,
|
|
72
|
+
});
|
|
73
|
+
server.registerTool("notary_status", {
|
|
74
|
+
description: TOOL_DESC_STATUS,
|
|
75
|
+
inputSchema: RAW_STATUS,
|
|
76
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
77
|
+
}, async (args) => {
|
|
78
|
+
try {
|
|
79
|
+
const out = await toolNotaryStatus(args);
|
|
80
|
+
return okReply(out.structuredContent ?? out.content[0]?.text ?? null);
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
return errReply(structuredFromError(e));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
server.registerTool("notary_verify", {
|
|
87
|
+
description: TOOL_DESC_VERIFY,
|
|
88
|
+
inputSchema: RAW_VERIFY,
|
|
89
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
90
|
+
}, async (args) => {
|
|
91
|
+
try {
|
|
92
|
+
const out = await toolNotaryVerify(args);
|
|
93
|
+
return okReply(out.structuredContent ?? out.content[0]?.text ?? null);
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
return errReply(structuredFromError(e));
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
server.registerTool("notary_lookup", {
|
|
100
|
+
description: TOOL_DESC_LOOKUP,
|
|
101
|
+
inputSchema: RAW_LOOKUP,
|
|
102
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
103
|
+
}, async (args) => {
|
|
104
|
+
try {
|
|
105
|
+
const out = await toolNotaryLookup(args);
|
|
106
|
+
return okReply(out.structuredContent ?? out.content[0]?.text ?? null);
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
return errReply(structuredFromError(e));
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
server.registerTool("notary_free", {
|
|
113
|
+
description: TOOL_DESC_FREE,
|
|
114
|
+
inputSchema: RAW_FREE,
|
|
115
|
+
annotations: { openWorldHint: true },
|
|
116
|
+
}, async (raw) => {
|
|
117
|
+
const v = validateFree(raw, "notary_free");
|
|
118
|
+
if ("errorReply" in v) {
|
|
119
|
+
return errReply(v.errorReply);
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
const out = await toolNotaryFree(v);
|
|
123
|
+
return okReply(out.structuredContent ?? out.content[0]?.text ?? null);
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
return errReply(structuredFromError(e));
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
server.registerTool("notary_notarize", {
|
|
130
|
+
description: TOOL_DESC_NOTARIZE,
|
|
131
|
+
inputSchema: RAW_NOTARIZE,
|
|
132
|
+
annotations: { openWorldHint: true },
|
|
133
|
+
}, async (raw) => {
|
|
134
|
+
const v = validateFree(raw, "notary_notarize");
|
|
135
|
+
if ("errorReply" in v) {
|
|
136
|
+
return errReply(v.errorReply);
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
const out = await toolNotaryNotarize(v);
|
|
140
|
+
return okReply(out.structuredContent ?? out.content[0]?.text ?? null);
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
return errReply(structuredFromError(e));
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
const transport = new StdioServerTransport();
|
|
147
|
+
await server.connect(transport);
|
|
148
|
+
// Keep the event loop alive while the client holds stdin open. Without a
|
|
149
|
+
// ref-anchored handle the process exits immediately after connect() when
|
|
150
|
+
// spawned programmatically (vitest / child_process) — the stdio transport
|
|
151
|
+
// leaves no other active handle. Closing stdin ends the server naturally.
|
|
152
|
+
const keepAlive = setInterval(() => { }, 60_000);
|
|
153
|
+
process.stdin.on("close", () => {
|
|
154
|
+
clearInterval(keepAlive);
|
|
155
|
+
void server.close().catch(() => { });
|
|
156
|
+
process.exit(0);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
import { ApiError, } from "./client.js";
|
|
160
|
+
import { PaymentConfigError } from "./payment.js";
|
|
161
|
+
import { TOOL_SPECS } from "./tools.js";
|
|
162
|
+
const TOOL_DESC_STATUS = TOOL_SPECS[0]?.description ?? "Check notarization status by job_id";
|
|
163
|
+
const TOOL_DESC_VERIFY = TOOL_SPECS[1]?.description ?? "Server-side PDR verification";
|
|
164
|
+
const TOOL_DESC_LOOKUP = TOOL_SPECS[2]?.description ?? "Find record by Shield ID (8 hex)";
|
|
165
|
+
const TOOL_DESC_FREE = TOOL_SPECS[3]?.description ?? "Free UNPAID notarization (5/IP/24h)";
|
|
166
|
+
const TOOL_DESC_NOTARIZE = TOOL_SPECS[4]?.description ??
|
|
167
|
+
"PAID notarization $0.01 USDC on Base; requires AOTRUST_EVM_PRIVATE_KEY";
|
|
168
|
+
/** Error → verbatim upstream code+message (never rephrased, never key-revealing). */
|
|
169
|
+
function structuredFromError(e) {
|
|
170
|
+
if (e instanceof PaymentConfigError) {
|
|
171
|
+
return { error: "MISSING_PRIVATE_KEY", message: e.message };
|
|
172
|
+
}
|
|
173
|
+
if (e instanceof ApiError) {
|
|
174
|
+
if (e.body && typeof e.body === "object" && !Array.isArray(e.body)) {
|
|
175
|
+
return e.body;
|
|
176
|
+
}
|
|
177
|
+
return { error: e.code };
|
|
178
|
+
}
|
|
179
|
+
return { error: "LOCAL_ERROR", message: e instanceof Error ? e.message : String(e) };
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type PaidResult = {
|
|
2
|
+
status: number;
|
|
3
|
+
body: unknown;
|
|
4
|
+
};
|
|
5
|
+
export declare class PaymentConfigError extends Error {
|
|
6
|
+
readonly code = "MISSING_PRIVATE_KEY";
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
export declare function buildPaidFetch(): Promise<typeof fetch>;
|
|
10
|
+
/** Test seam: reset the cached wrapper (tests never hold a real key). */
|
|
11
|
+
export declare function resetPaidFetchCache(): void;
|
|
12
|
+
/** One paid POST against {base}/notarize. Response passed through verbatim. */
|
|
13
|
+
export declare function paidPost(baseUrl: string, body: Record<string, unknown>, fetchFn?: typeof fetch): Promise<PaidResult>;
|
package/dist/payment.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* payment.ts — paid notarize via @x402/fetch (challenge → EIP-3009 sign → retry).
|
|
3
|
+
*
|
|
4
|
+
* Real installed surface (verified in node_modules, @x402/fetch 2.28.0 +
|
|
5
|
+
* @x402/evm 2.28.0):
|
|
6
|
+
* x402Client from "@x402/core/client"
|
|
7
|
+
* registerExactEvmScheme from "@x402/evm/exact/client" ← root index does
|
|
8
|
+
* NOT re-export it; the README example points at ".../exact/client/register"
|
|
9
|
+
* which does not exist in the package exports of 2.28.0 — use ./exact/client.
|
|
10
|
+
* toClientEvmSigner from "@x402/evm"
|
|
11
|
+
* privateKeyToAccount from "viem/accounts"
|
|
12
|
+
* wrapFetchWithPayment from "@x402/fetch"
|
|
13
|
+
*
|
|
14
|
+
* The private key comes from env AOTRUST_EVM_PRIVATE_KEY and flows only into
|
|
15
|
+
* the viem signer factory — it is NEVER printed, logged, or embedded in error
|
|
16
|
+
* messages (a missing key produces a plain instruction, never the value).
|
|
17
|
+
*/
|
|
18
|
+
import { x402Client } from "@x402/core/client";
|
|
19
|
+
import { registerExactEvmScheme } from "@x402/evm/exact/client";
|
|
20
|
+
import { toClientEvmSigner } from "@x402/evm";
|
|
21
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
22
|
+
import { wrapFetchWithPayment } from "@x402/fetch";
|
|
23
|
+
import { AOTRUST_EVM_PRIVATE_KEY_ENV, USER_AGENT, } from "./env.js";
|
|
24
|
+
export class PaymentConfigError extends Error {
|
|
25
|
+
code = "MISSING_PRIVATE_KEY";
|
|
26
|
+
constructor(message) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = "PaymentConfigError";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build the x402 fetch wrapper once per process (lazy).
|
|
33
|
+
* Returns a fetch-like callable: POST → 402 challenge → EIP-3009 sign →
|
|
34
|
+
* retry with x-payment header — all inside the wrapper.
|
|
35
|
+
*/
|
|
36
|
+
let _paidFetch = null;
|
|
37
|
+
export async function buildPaidFetch() {
|
|
38
|
+
if (_paidFetch) {
|
|
39
|
+
return _paidFetch;
|
|
40
|
+
}
|
|
41
|
+
const keyEnv = process.env[AOTRUST_EVM_PRIVATE_KEY_ENV];
|
|
42
|
+
if (!keyEnv || keyEnv.trim().length === 0) {
|
|
43
|
+
throw new PaymentConfigError("set AOTRUST_EVM_PRIVATE_KEY (EVM wallet private key, 0x-prefixed) to use notary_notarize");
|
|
44
|
+
}
|
|
45
|
+
const account = privateKeyToAccount(trimKey(keyEnv));
|
|
46
|
+
const signer = toClientEvmSigner(account);
|
|
47
|
+
const client = new x402Client();
|
|
48
|
+
// Base mainnet = eip155:8453 — the ONLY paid rail in v0.1 (HTTP /notarize
|
|
49
|
+
// is Base by server design; Solana = remote-MCP-only, see README).
|
|
50
|
+
registerExactEvmScheme(client, { signer });
|
|
51
|
+
_paidFetch = wrapFetchWithPayment(globalThis.fetch, client);
|
|
52
|
+
return _paidFetch;
|
|
53
|
+
}
|
|
54
|
+
/** Strip whitespace/quotes; never echo the value. */
|
|
55
|
+
function trimKey(raw) {
|
|
56
|
+
let k = raw.trim().replace(/^["']|["']$/g, "");
|
|
57
|
+
if (!k.startsWith("0x")) {
|
|
58
|
+
k = `0x${k}`;
|
|
59
|
+
}
|
|
60
|
+
return k;
|
|
61
|
+
}
|
|
62
|
+
/** Test seam: reset the cached wrapper (tests never hold a real key). */
|
|
63
|
+
export function resetPaidFetchCache() {
|
|
64
|
+
_paidFetch = null;
|
|
65
|
+
}
|
|
66
|
+
/** One paid POST against {base}/notarize. Response passed through verbatim. */
|
|
67
|
+
export async function paidPost(baseUrl, body, fetchFn) {
|
|
68
|
+
const paidFetch = fetchFn ?? (await buildPaidFetch());
|
|
69
|
+
const res = await paidFetch(`${baseUrl}/notarize`, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers: {
|
|
72
|
+
"Content-Type": "application/json",
|
|
73
|
+
"User-Agent": USER_AGENT,
|
|
74
|
+
},
|
|
75
|
+
body: JSON.stringify(body),
|
|
76
|
+
});
|
|
77
|
+
let parsed = null;
|
|
78
|
+
const text = await res.text();
|
|
79
|
+
try {
|
|
80
|
+
parsed = JSON.parse(text);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
parsed = text;
|
|
84
|
+
}
|
|
85
|
+
if (!res.ok) {
|
|
86
|
+
const obj = (parsed && typeof parsed === "object" ? parsed : {});
|
|
87
|
+
const code = typeof obj["error"] === "string" ? obj["error"] : `HTTP_${res.status}`;
|
|
88
|
+
throw Object.assign(new Error(code), {
|
|
89
|
+
name: "ApiError",
|
|
90
|
+
status: res.status,
|
|
91
|
+
code,
|
|
92
|
+
body: parsed,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return { status: res.status, body: parsed };
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=payment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment.js","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EACL,2BAA2B,EAC3B,UAAU,GACX,MAAM,UAAU,CAAC;AAOlB,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,IAAI,GAAG,qBAAqB,CAAC;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;;;GAIG;AACH,IAAI,UAAU,GAAwB,IAAI,CAAC;AAC3C,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,kBAAkB,CAC1B,0FAA0F,CAC3F,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;IAChC,0EAA0E;IAC1E,mEAAmE;IACnE,sBAAsB,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAE3C,UAAU,GAAG,oBAAoB,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC5D,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,qDAAqD;AACrD,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;IACf,CAAC;IACD,OAAO,CAAkB,CAAC;AAC5B,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,mBAAmB;IACjC,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,OAAe,EACf,IAA6B,EAC7B,OAAsB;IAEtB,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,MAAM,cAAc,EAAE,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,OAAO,WAAW,EAAE;QACjD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,YAAY,EAAE,UAAU;SACzB;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,MAAM,GAAY,IAAI,CAAC;IAC3B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAG9D,CAAC;QACF,MAAM,IAAI,GACR,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;QACzE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;YACnC,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI;YACJ,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9C,CAAC"}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tools.ts — the five AOTrust MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Every tool returns the upstream JSON VERBATIM in structuredContent/content:
|
|
5
|
+
* no invented fields, error codes passed through unmodified (clients parse
|
|
6
|
+
* `error`). The only allowed addition is `verify_url` derived from an
|
|
7
|
+
* already-present field.
|
|
8
|
+
*
|
|
9
|
+
* Network policy v0.1: paid notarize is Base-only (the HTTP /notarize rail is
|
|
10
|
+
* Base by server design; Solana exists only on the remote MCP server, not here).
|
|
11
|
+
*/
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { encodePdrB64 } from "./client.js";
|
|
14
|
+
import { INVALID_SHIELD_ID_ERR, USER_AGENT } from "./env.js";
|
|
15
|
+
export type ToolContent = {
|
|
16
|
+
content: Array<{
|
|
17
|
+
type: "text";
|
|
18
|
+
text: string;
|
|
19
|
+
}>;
|
|
20
|
+
structuredContent?: unknown;
|
|
21
|
+
};
|
|
22
|
+
export declare function contentFromError(e: unknown): ToolContent;
|
|
23
|
+
export declare const NotaryStatusArgs: z.ZodObject<{
|
|
24
|
+
job_id: z.ZodString;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
export declare function toolNotaryStatus(args: {
|
|
27
|
+
job_id: string;
|
|
28
|
+
}): Promise<ToolContent>;
|
|
29
|
+
export declare const NotaryVerifyArgs: z.ZodObject<{
|
|
30
|
+
pdr_b64: z.ZodString;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
export declare function toolNotaryVerify(args: {
|
|
33
|
+
pdr_b64: string;
|
|
34
|
+
}): Promise<ToolContent>;
|
|
35
|
+
export declare const NotaryLookupArgs: z.ZodObject<{
|
|
36
|
+
shield_id: z.ZodString;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
export declare function toolNotaryLookup(args: {
|
|
39
|
+
shield_id: string;
|
|
40
|
+
}): Promise<ToolContent>;
|
|
41
|
+
export declare const NotaryFreeArgs: z.ZodObject<{
|
|
42
|
+
work_hash: z.ZodOptional<z.ZodString>;
|
|
43
|
+
content: z.ZodOptional<z.ZodString>;
|
|
44
|
+
agent_sig: z.ZodOptional<z.ZodString>;
|
|
45
|
+
agent_pubkey: z.ZodOptional<z.ZodString>;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
export declare function toolNotaryFree(args: z.infer<typeof NotaryFreeArgs>): Promise<ToolContent>;
|
|
48
|
+
export declare const NotaryNotarizeArgs: z.ZodObject<{
|
|
49
|
+
work_hash: z.ZodOptional<z.ZodString>;
|
|
50
|
+
content: z.ZodOptional<z.ZodString>;
|
|
51
|
+
agent_sig: z.ZodOptional<z.ZodString>;
|
|
52
|
+
agent_pubkey: z.ZodOptional<z.ZodString>;
|
|
53
|
+
}, z.core.$strip>;
|
|
54
|
+
export declare function toolNotaryNotarize(args: z.infer<typeof NotaryNotarizeArgs>): Promise<ToolContent>;
|
|
55
|
+
export type ToolSpec = {
|
|
56
|
+
name: string;
|
|
57
|
+
description: string;
|
|
58
|
+
inputSchema: unknown;
|
|
59
|
+
read_only: boolean;
|
|
60
|
+
env_notes?: string;
|
|
61
|
+
};
|
|
62
|
+
export declare const TOOL_SPECS: ToolSpec[];
|
|
63
|
+
export { INVALID_SHIELD_ID_ERR, USER_AGENT, encodePdrB64 };
|
package/dist/tools.js
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tools.ts — the five AOTrust MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Every tool returns the upstream JSON VERBATIM in structuredContent/content:
|
|
5
|
+
* no invented fields, error codes passed through unmodified (clients parse
|
|
6
|
+
* `error`). The only allowed addition is `verify_url` derived from an
|
|
7
|
+
* already-present field.
|
|
8
|
+
*
|
|
9
|
+
* Network policy v0.1: paid notarize is Base-only (the HTTP /notarize rail is
|
|
10
|
+
* Base by server design; Solana exists only on the remote MCP server, not here).
|
|
11
|
+
*/
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { ApiError, encodePdrB64, getBaseUrl, getStatus, shieldFree, shieldLookup, verifyPdr, } from "./client.js";
|
|
14
|
+
import { paidPost } from "./payment.js";
|
|
15
|
+
import { INVALID_SHIELD_ID_ERR, INVALID_SHIELD_ID_MSG, USER_AGENT, } from "./env.js";
|
|
16
|
+
const FREE_TIER_LIMIT_CODE = "FREE_TIER_LIMIT_REACHED";
|
|
17
|
+
const SHIELD_ID_HEX_RE = /^[0-9a-fA-F]{8}$/;
|
|
18
|
+
/** MCP tool content from an upstream response, verbatim body + error passthrough. */
|
|
19
|
+
function contentFromBody(body) {
|
|
20
|
+
const text = typeof body === "string" ? body : JSON.stringify(body, null, 2);
|
|
21
|
+
return {
|
|
22
|
+
content: [{ type: "text", text }],
|
|
23
|
+
structuredContent: body,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function contentFromError(e) {
|
|
27
|
+
if (e instanceof ApiError) {
|
|
28
|
+
const bodyObj = e.body && typeof e.body === "object" && !Array.isArray(e.body)
|
|
29
|
+
? e.body
|
|
30
|
+
: { error: e.code };
|
|
31
|
+
// Verbatim upstream body (error/message/detail are load-bearing).
|
|
32
|
+
return contentFromBody(bodyObj);
|
|
33
|
+
}
|
|
34
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
35
|
+
return contentFromBody({ error: "LOCAL_ERROR", message });
|
|
36
|
+
}
|
|
37
|
+
// ── tool #1: notary_status ────────────────────────────────────────────────────
|
|
38
|
+
export const NotaryStatusArgs = z.object({
|
|
39
|
+
job_id: z.string().min(1).describe("Job id returned by a notarization call"),
|
|
40
|
+
});
|
|
41
|
+
export async function toolNotaryStatus(args) {
|
|
42
|
+
const { status, body } = await getStatus(args.job_id);
|
|
43
|
+
return contentFromBody(body);
|
|
44
|
+
}
|
|
45
|
+
// ── tool #2: notary_verify ───────────────────────────────────────────────────
|
|
46
|
+
export const NotaryVerifyArgs = z.object({
|
|
47
|
+
pdr_b64: z.string().min(1).describe("PDR bundle in base64 (239 bytes)"),
|
|
48
|
+
});
|
|
49
|
+
export async function toolNotaryVerify(args) {
|
|
50
|
+
const { body } = await verifyPdr(args.pdr_b64);
|
|
51
|
+
return contentFromBody(body);
|
|
52
|
+
}
|
|
53
|
+
// ── tool #3: notary_lookup ───────────────────────────────────────────────────
|
|
54
|
+
export const NotaryLookupArgs = z.object({
|
|
55
|
+
shield_id: z
|
|
56
|
+
.string()
|
|
57
|
+
.regex(SHIELD_ID_HEX_RE)
|
|
58
|
+
.describe("Shield ID — exactly 8 hexadecimal characters"),
|
|
59
|
+
});
|
|
60
|
+
export async function toolNotaryLookup(args) {
|
|
61
|
+
if (!SHIELD_ID_HEX_RE.test(args.shield_id)) {
|
|
62
|
+
// Local guard mirrors the server response form verbatim (throw, not return:
|
|
63
|
+
// the registration layer maps thrown ApiError → isError reply). Zero network
|
|
64
|
+
// for a shape the server would reject anyway.
|
|
65
|
+
throw new ApiError(400, INVALID_SHIELD_ID_ERR, {
|
|
66
|
+
error: INVALID_SHIELD_ID_ERR,
|
|
67
|
+
message: INVALID_SHIELD_ID_MSG,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const { body } = await shieldLookup(args.shield_id);
|
|
71
|
+
return contentFromBody(body);
|
|
72
|
+
}
|
|
73
|
+
// ── tool #4: notary_free ─────────────────────────────────────────────────────
|
|
74
|
+
export const NotaryFreeArgs = z
|
|
75
|
+
.object({
|
|
76
|
+
work_hash: z
|
|
77
|
+
.string()
|
|
78
|
+
.optional()
|
|
79
|
+
.describe("SHA-256 hex (64 chars) of the artifact — Mode A"),
|
|
80
|
+
content: z
|
|
81
|
+
.string()
|
|
82
|
+
.optional()
|
|
83
|
+
.describe("Raw text/code up to 60KB — Mode B (server hashes it, zero retention)"),
|
|
84
|
+
agent_sig: z.string().optional().describe("Optional base64 Ed25519 signature (bilateral)"),
|
|
85
|
+
agent_pubkey: z.string().optional().describe("Optional hex Ed25519 public key (bilateral)"),
|
|
86
|
+
})
|
|
87
|
+
.refine((v) => Boolean(v.work_hash) !== Boolean(v.content), {
|
|
88
|
+
message: "exactly one of work_hash or content is required",
|
|
89
|
+
});
|
|
90
|
+
export async function toolNotaryFree(args) {
|
|
91
|
+
const body = {};
|
|
92
|
+
if (args.work_hash !== undefined && args.work_hash !== "") {
|
|
93
|
+
body["work_hash"] = args.work_hash;
|
|
94
|
+
}
|
|
95
|
+
if (args.content !== undefined && args.content !== "") {
|
|
96
|
+
body["content"] = args.content;
|
|
97
|
+
}
|
|
98
|
+
if (args.agent_sig) {
|
|
99
|
+
body["agent_sig"] = args.agent_sig;
|
|
100
|
+
}
|
|
101
|
+
if (args.agent_pubkey) {
|
|
102
|
+
body["agent_pubkey"] = args.agent_pubkey;
|
|
103
|
+
}
|
|
104
|
+
const { body: upstream } = await shieldFree(body);
|
|
105
|
+
if (typeof upstream === "object" && upstream !== null) {
|
|
106
|
+
const rec = upstream;
|
|
107
|
+
const workHash = typeof rec["work_hash"] === "string" ? rec["work_hash"] : null;
|
|
108
|
+
if (workHash && (workHash.length === 64 || workHash.length === 66)) {
|
|
109
|
+
// Allowed additive field: derived from an already-present work_hash.
|
|
110
|
+
rec["verify_url"] = `https://verify.aotrust.link/s/${workHash.slice(0, 8)}`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return contentFromBody(upstream);
|
|
114
|
+
}
|
|
115
|
+
// ── tool #5: notary_notarize (PAID, x402 over HTTP) ─────────────────────────
|
|
116
|
+
export const NotaryNotarizeArgs = z
|
|
117
|
+
.object({
|
|
118
|
+
work_hash: z
|
|
119
|
+
.string()
|
|
120
|
+
.optional()
|
|
121
|
+
.describe("SHA-256 hex (64 chars) of the artifact — Mode A"),
|
|
122
|
+
content: z
|
|
123
|
+
.string()
|
|
124
|
+
.optional()
|
|
125
|
+
.describe("Raw text/code up to 60KB — Mode B (server hashes it)"),
|
|
126
|
+
agent_sig: z.string().optional().describe("Optional base64 Ed25519 signature (bilateral)"),
|
|
127
|
+
agent_pubkey: z.string().optional().describe("Optional hex Ed25519 public key (bilateral)"),
|
|
128
|
+
})
|
|
129
|
+
.refine((v) => Boolean(v.work_hash) !== Boolean(v.content), {
|
|
130
|
+
message: "exactly one of work_hash or content is required",
|
|
131
|
+
});
|
|
132
|
+
export async function toolNotaryNotarize(args) {
|
|
133
|
+
const body = {};
|
|
134
|
+
if (args.work_hash !== undefined && args.work_hash !== "") {
|
|
135
|
+
body["work_hash"] = args.work_hash;
|
|
136
|
+
}
|
|
137
|
+
if (args.content !== undefined && args.content !== "") {
|
|
138
|
+
body["content"] = args.content;
|
|
139
|
+
}
|
|
140
|
+
if (args.agent_sig) {
|
|
141
|
+
body["agent_sig"] = args.agent_sig;
|
|
142
|
+
}
|
|
143
|
+
if (args.agent_pubkey) {
|
|
144
|
+
body["agent_pubkey"] = args.agent_pubkey;
|
|
145
|
+
}
|
|
146
|
+
// x402 wrapper handles: 402 challenge → EIP-3009 sign → retry with x-payment.
|
|
147
|
+
// No facilitator client-side. Key comes from env, never logged.
|
|
148
|
+
const { body: upstream } = await paidPost(getBaseUrl(), body);
|
|
149
|
+
return contentFromBody(upstream);
|
|
150
|
+
}
|
|
151
|
+
export const TOOL_SPECS = [
|
|
152
|
+
{
|
|
153
|
+
name: "notary_status",
|
|
154
|
+
description: "Check notarization status by job_id. Free. GET /v1/status/{job_id}. Upstream JSON passthrough (status, result.pdr_b64, result.payment_hash, ...).",
|
|
155
|
+
inputSchema: {
|
|
156
|
+
type: "object",
|
|
157
|
+
properties: { job_id: { type: "string", description: "Job id from notarization response" } },
|
|
158
|
+
required: ["job_id"],
|
|
159
|
+
},
|
|
160
|
+
read_only: true,
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: "notary_verify",
|
|
164
|
+
description: "Full server-side PDR verification by base64 bundle. Free. GET /v1/pdr/verify/{pdr_b64} (the b64 is quote_plus-encoded in the URL path).",
|
|
165
|
+
inputSchema: {
|
|
166
|
+
type: "object",
|
|
167
|
+
properties: { pdr_b64: { type: "string", description: "PDR bundle in base64" } },
|
|
168
|
+
required: ["pdr_b64"],
|
|
169
|
+
},
|
|
170
|
+
read_only: true,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: "notary_lookup",
|
|
174
|
+
description: "Find a notarization record by Shield ID (8 hex chars returned by the free tier). Free. Local 8-hex guard mirrors the server 400 INVALID_SHIELD_ID form.",
|
|
175
|
+
inputSchema: {
|
|
176
|
+
type: "object",
|
|
177
|
+
properties: { shield_id: { type: "string", description: "8 hex characters" } },
|
|
178
|
+
required: ["shield_id"],
|
|
179
|
+
},
|
|
180
|
+
read_only: true,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: "notary_free",
|
|
184
|
+
description: "Free UNPAID notarization (PDR proof-of-existence, no wallet). Rate limited 5/IP/24h (429 FREE_TIER_LIMIT_REACHED is quota, not a defect). Pass work_hash OR content.",
|
|
185
|
+
inputSchema: {
|
|
186
|
+
type: "object",
|
|
187
|
+
properties: {
|
|
188
|
+
work_hash: { type: "string", description: "sha256 hex (64 chars)" },
|
|
189
|
+
content: { type: "string", description: "raw text/code ≤60KB" },
|
|
190
|
+
agent_sig: { type: "string", description: "optional bilateral signature" },
|
|
191
|
+
agent_pubkey: { type: "string", description: "optional bilateral public key" },
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
read_only: false,
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: "notary_notarize",
|
|
198
|
+
description: "PAID notarization, $0.01 USDC on Base (EIP-3009 via x402; HTTP rail is Base-only — Solana exists only via the remote MCP server). Requires AOTRUST_EVM_PRIVATE_KEY in env. Free-tier body shape; the x402 wrapper takes the 402 challenge, signs, and retries.",
|
|
199
|
+
inputSchema: {
|
|
200
|
+
type: "object",
|
|
201
|
+
properties: {
|
|
202
|
+
work_hash: { type: "string", description: "sha256 hex (64 chars)" },
|
|
203
|
+
content: { type: "string", description: "raw text/code ≤60KB" },
|
|
204
|
+
agent_sig: { type: "string", description: "optional bilateral signature" },
|
|
205
|
+
agent_pubkey: { type: "string", description: "optional bilateral public key" },
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
read_only: false,
|
|
209
|
+
env_notes: "AOTRUST_EVM_PRIVATE_KEY required; AOTRUST_BASE_URL optional (default https://api.aotrust.link)",
|
|
210
|
+
},
|
|
211
|
+
];
|
|
212
|
+
export { INVALID_SHIELD_ID_ERR, USER_AGENT, encodePdrB64 };
|
|
213
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,SAAS,EACT,UAAU,EACV,YAAY,EACZ,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,UAAU,GACX,MAAM,UAAU,CAAC;AAOlB,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AACvD,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAE5C,qFAAqF;AACrF,SAAS,eAAe,CAAC,IAAa;IACpC,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7E,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACjC,iBAAiB,EAAE,IAAI;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,CAAU;IACzC,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC;QAC1B,MAAM,OAAO,GACX,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5D,CAAC,CAAE,CAAC,CAAC,IAAgC;YACrC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACxB,kEAAkE;QAClE,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3D,OAAO,eAAe,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,iFAAiF;AAEjF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,wCAAwC,CAAC;CAC7E,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAwB;IAC7D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,gFAAgF;AAEhF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC;CACxE,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAyB;IAC9D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/C,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,gFAAgF;AAEhF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,KAAK,CAAC,gBAAgB,CAAC;SACvB,QAAQ,CAAC,8CAA8C,CAAC;CAC5D,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAA2B;IAChE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3C,4EAA4E;QAC5E,6EAA6E;QAC7E,8CAA8C;QAC9C,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,qBAAqB,EAAE;YAC7C,KAAK,EAAE,qBAAqB;YAC5B,OAAO,EAAE,qBAAqB;SAC/B,CAAC,CAAC;IACL,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpD,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,gFAAgF;AAEhF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC5B,MAAM,CAAC;IACN,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,iDAAiD,CAAC;IAC9D,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,sEAAsE,CAAC;IACnF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;IAC1F,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;CAC5F,CAAC;KACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE;IAC1D,OAAO,EAAE,iDAAiD;CAC3D,CAAC,CAAC;AAEL,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAoC;IAEpC,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,EAAE,EAAE,CAAC;QAC1D,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;IACrC,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,EAAE,EAAE,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;IACjC,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;IACrC,CAAC;IACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,IAAI,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;IAC3C,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,QAAmC,CAAC;QAChD,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAChF,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,EAAE,IAAI,QAAQ,CAAC,MAAM,KAAK,EAAE,CAAC,EAAE,CAAC;YACnE,qEAAqE;YACrE,GAAG,CAAC,YAAY,CAAC,GAAG,iCAAiC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC9E,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,+EAA+E;AAE/E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,iDAAiD,CAAC;IAC9D,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,sDAAsD,CAAC;IACnE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;IAC1F,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;CAC5F,CAAC;KACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE;IAC1D,OAAO,EAAE,iDAAiD;CAC3D,CAAC,CAAC;AAEL,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAwC;IAExC,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,EAAE,EAAE,CAAC;QAC1D,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;IACrC,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,EAAE,EAAE,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;IACjC,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;IACrC,CAAC;IACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,IAAI,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;IAC3C,CAAC;IACD,8EAA8E;IAC9E,gEAAgE;IAChE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,CAAC;IAC9D,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAYD,MAAM,CAAC,MAAM,UAAU,GAAe;IACpC;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,mJAAmJ;QACrJ,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE,EAAE;YAC5F,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;QACD,SAAS,EAAE,IAAI;KAChB;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,yIAAyI;QAC3I,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE,EAAE;YAChF,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;QACD,SAAS,EAAE,IAAI;KAChB;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,yJAAyJ;QAC3J,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,EAAE;YAC9E,QAAQ,EAAE,CAAC,WAAW,CAAC;SACxB;QACD,SAAS,EAAE,IAAI;KAChB;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EACT,sKAAsK;QACxK,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE;gBACnE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qBAAqB,EAAE;gBAC/D,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;gBAC1E,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+BAA+B,EAAE;aAC/E;SACF;QACD,SAAS,EAAE,KAAK;KACjB;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EACT,gQAAgQ;QAClQ,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE;gBACnE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qBAAqB,EAAE;gBAC/D,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;gBAC1E,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+BAA+B,EAAE;aAC/E;SACF;QACD,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,gGAAgG;KAC5G;CACF,CAAC;AAEF,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aotrust-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "AOTrust notary MCP stdio server — 5 tools over the AOTrust HTTP API: status, verify, shield lookup, free notarization, and $0.01 x402 paid notarization (Base).",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"aotrust-mcp": "dist/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"README.md",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc -p tsconfig.json",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"smoke": "node dist/cli.js --tools"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
25
|
+
"@x402/evm": ">=2.19 <2.29",
|
|
26
|
+
"@x402/fetch": ">=2.19 <2.29",
|
|
27
|
+
"viem": "^2.57.7",
|
|
28
|
+
"zod": "^4.6.7"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"typescript": "^5.9.3",
|
|
32
|
+
"@types/node": "^26.6.5",
|
|
33
|
+
"vitest": "^5.0.5"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"mcp",
|
|
37
|
+
"aotrust",
|
|
38
|
+
"x402",
|
|
39
|
+
"notarization",
|
|
40
|
+
"modelcontextprotocol"
|
|
41
|
+
]
|
|
6
42
|
}
|