ton-mesh-harness 0.13.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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +444 -0
  3. package/dist/cli.js +38739 -0
  4. package/dist/daemon/installer-utils.d.ts +103 -0
  5. package/dist/daemon/installer.d.ts +30 -0
  6. package/dist/daemon/linger.d.ts +10 -0
  7. package/dist/daemon/platform.d.ts +47 -0
  8. package/dist/daemon/ports.d.ts +14 -0
  9. package/dist/daemon/rldp-http-proxy-installer.d.ts +10 -0
  10. package/dist/daemon/service.d.ts +36 -0
  11. package/dist/daemon/tonutils-installer.d.ts +10 -0
  12. package/dist/daemon/tonutils-process.d.ts +90 -0
  13. package/dist/deeplink.d.ts +25 -0
  14. package/dist/dns.d.ts +39 -0
  15. package/dist/mcp.js +38097 -0
  16. package/dist/network.d.ts +5 -0
  17. package/dist/sdk/abort.d.ts +25 -0
  18. package/dist/sdk/agentic-config.d.ts +199 -0
  19. package/dist/sdk/agentic-sign.d.ts +48 -0
  20. package/dist/sdk/check.d.ts +24 -0
  21. package/dist/sdk/deploy.d.ts +96 -0
  22. package/dist/sdk/dns-helpers.d.ts +158 -0
  23. package/dist/sdk/dns-onchain.d.ts +39 -0
  24. package/dist/sdk/dns.d.ts +125 -0
  25. package/dist/sdk/endpoints.d.ts +58 -0
  26. package/dist/sdk/json-schemas.d.ts +38 -0
  27. package/dist/sdk/log.d.ts +43 -0
  28. package/dist/sdk/provenance.d.ts +87 -0
  29. package/dist/sdk/resolve-tx.d.ts +70 -0
  30. package/dist/sdk/schemas.d.ts +885 -0
  31. package/dist/sdk/site-record.d.ts +25 -0
  32. package/dist/sdk/status.d.ts +23 -0
  33. package/dist/sdk/walletkit-network.d.ts +30 -0
  34. package/dist/sdk.d.ts +46 -0
  35. package/dist/sdk.js +37789 -0
  36. package/dist/utils/http.d.ts +25 -0
  37. package/dist/utils/tunnel-config.d.ts +20 -0
  38. package/dist/version.d.ts +13 -0
  39. package/dist/wallet/FSStorage.d.ts +12 -0
  40. package/dist/wallet/SendProvider.d.ts +17 -0
  41. package/dist/wallet/Storage.d.ts +5 -0
  42. package/dist/wallet/TonConnectProvider.d.ts +48 -0
  43. package/dist/wallet/constants.d.ts +12 -0
  44. package/dist/wallet/ui.d.ts +13 -0
  45. package/package.json +105 -0
  46. package/skills/mesh-deploy.md +283 -0
  47. package/templates/.well-known/mcp.json +44 -0
  48. package/templates/github-workflow-agentic.yml +94 -0
  49. package/templates/github-workflow.yml +76 -0
@@ -0,0 +1,25 @@
1
+ export interface HttpResponse<T = unknown> {
2
+ statusCode: number;
3
+ headers: Record<string, string | string[] | undefined>;
4
+ body: T;
5
+ }
6
+ export interface HttpOptions {
7
+ headers?: Record<string, string>;
8
+ timeout?: number;
9
+ /**
10
+ * Cap the response body size to defend against a buggy or malicious
11
+ * server returning unbounded data. Defaults to 8 MiB, which is far
12
+ * above any expected TONAPI / Toncenter response (typical: 1-20 KB).
13
+ * Codex pre-GA self-audit class — resource-exhaustion defence.
14
+ */
15
+ maxBodyBytes?: number;
16
+ }
17
+ /**
18
+ * Perform an HTTPS GET request and parse JSON response.
19
+ *
20
+ * @param url - The URL to request
21
+ * @param options - Optional headers and timeout
22
+ * @returns Parsed JSON response
23
+ * @throws {Error} On HTTP errors or invalid JSON
24
+ */
25
+ export declare function httpsGet<T = unknown>(url: string, options?: HttpOptions): Promise<T>;
@@ -0,0 +1,20 @@
1
+ export interface ResolvedTunnel {
2
+ /** Absolute path after `~` expansion. */
3
+ absPath: string;
4
+ /** Best-effort count of intermediate nodes in the pool. */
5
+ nodeCount: number;
6
+ }
7
+ /** `~` and `~/foo` expansion — Node's `path.resolve()` does NOT do this. */
8
+ export declare function expandTilde(p: string): string;
9
+ export type TunnelConfigErrorReason = 'not_found' | 'unparseable' | 'empty_pool';
10
+ export declare class TunnelConfigError extends Error {
11
+ readonly reason: TunnelConfigErrorReason;
12
+ readonly absPath: string;
13
+ constructor(reason: TunnelConfigErrorReason, absPath: string, message: string);
14
+ }
15
+ /**
16
+ * Resolve, validate, and summarise a tunnel-config file. Throws
17
+ * `TunnelConfigError` on every failure mode — callers map to their own
18
+ * error class (CLI: plain Error / SDK: SdkError(ERR_INVALID_INPUT)).
19
+ */
20
+ export declare function resolveTunnelConfig(rawPath: string): ResolvedTunnel;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Single source of truth for the kit's version string. Imported by
3
+ * `src/cli.ts` and `src/mcp.ts`; previously each file hardcoded its
4
+ * own copy and they drifted (rc2 → rc5 sync was missed twice).
5
+ *
6
+ * MUST match `package.json#version` exactly. The `scripts/cli-smoke.cjs`
7
+ * CI step validates the published binary surfaces a semver-shaped
8
+ * string, so a forgotten bump here triggers a build-time failure even
9
+ * if `package.json` is correct.
10
+ *
11
+ * NO `console.*` IN THIS FILE — lint-enforced.
12
+ */
13
+ export declare const MESH_HARNESS_VERSION = "0.13.0";
@@ -0,0 +1,12 @@
1
+ import type { Storage } from './Storage';
2
+ export declare class FSStorage implements Storage {
3
+ private readonly path;
4
+ constructor(path: string);
5
+ private mutationChain;
6
+ private serialize;
7
+ private readObject;
8
+ private writeObject;
9
+ setItem(key: string, value: string): Promise<void>;
10
+ getItem(key: string): Promise<string | null>;
11
+ removeItem(key: string): Promise<void>;
12
+ }
@@ -0,0 +1,17 @@
1
+ import type { Address, Cell, StateInit } from '@ton/core';
2
+ export interface SendProvider {
3
+ connect(): Promise<void>;
4
+ sendTransaction(address: Address, amount: bigint, payload?: Cell, stateInit?: StateInit): Promise<unknown>;
5
+ sendTransactionMulti(messages: Array<{
6
+ address: Address;
7
+ amount: bigint;
8
+ payload?: Cell;
9
+ stateInit?: StateInit;
10
+ }>): Promise<unknown>;
11
+ address(): Address | undefined;
12
+ /**
13
+ * Stop the bridge HTTP listener so the Node event loop can drain. Does
14
+ * NOT unpair the wallet (the next run still finds the session on disk).
15
+ */
16
+ dispose(): void;
17
+ }
@@ -0,0 +1,5 @@
1
+ export interface Storage {
2
+ setItem(key: string, value: string): Promise<void>;
3
+ getItem(key: string): Promise<string | null>;
4
+ removeItem(key: string): Promise<void>;
5
+ }
@@ -0,0 +1,48 @@
1
+ import { type SendTransactionResponse } from '@tonconnect/sdk';
2
+ import { Address, Cell, type StateInit } from '@ton/core';
3
+ import type { SendProvider } from './SendProvider';
4
+ import type { Storage } from './Storage';
5
+ import type { WalletUI } from './ui';
6
+ export type WalletNetwork = 'mainnet' | 'testnet';
7
+ /** @internal */
8
+ export declare function _enterQuiet_FOR_TEST(): void;
9
+ /** @internal */
10
+ export declare function _leaveQuiet_FOR_TEST(): void;
11
+ export declare class TonConnectProvider implements SendProvider {
12
+ private readonly connector;
13
+ private readonly ui;
14
+ private readonly network;
15
+ constructor(storage: Storage, ui: WalletUI, network: WalletNetwork, manifestUrl: string);
16
+ /**
17
+ * @param onConnectUrl — optional callback fired with the freshly-generated
18
+ * TonConnect connect URL just before we await the wallet pairing. Used by
19
+ * the SDK's `deploy()` generator to emit `awaiting_signature` with
20
+ * `signing_url` set. CLI callers can ignore — the URL is also printed via
21
+ * the QR code in `connectWallet()`.
22
+ */
23
+ connect(onConnectUrl?: (url: string) => void): Promise<void>;
24
+ address(): Address | undefined;
25
+ /**
26
+ * Stop the @tonconnect/sdk bridge HTTP listener (server-sent events) so
27
+ * the Node event loop drains and the CLI can exit after a `--no-watch`
28
+ * deploy. We pause rather than disconnect so the on-disk session stays
29
+ * paired — `connect()` next run finds it via `restoreConnection()`.
30
+ * Caller responsibility: invoke from a `finally` block after the last
31
+ * sendTransaction[Multi] call.
32
+ */
33
+ dispose(): void;
34
+ private connectWallet;
35
+ sendTransaction(address: Address, amount: bigint, payload?: Cell, stateInit?: StateInit): Promise<SendTransactionResponse>;
36
+ /**
37
+ * Send a TonConnect transaction with multiple messages bundled into a single
38
+ * sign request. Tonkeeper supports up to 4 messages per tx (TonConnect spec
39
+ * §sendTransaction). Used by --domain when both a `storage` and `site` DNS
40
+ * record are written in one user-prompt.
41
+ */
42
+ sendTransactionMulti(messages: Array<{
43
+ address: Address;
44
+ amount: bigint;
45
+ payload?: Cell;
46
+ stateInit?: StateInit;
47
+ }>): Promise<SendTransactionResponse>;
48
+ }
@@ -0,0 +1,12 @@
1
+ export declare const TONCONNECT_MANIFEST_URL = "https://raw.githubusercontent.com/Masashi-Ono0611/ton-mesh-harness/main/tonconnect/manifest.json";
2
+ export declare function getTonConnectStoragePath(): string;
3
+ /** Sign-request validity window: 5 minutes (chain-enforced cap). */
4
+ export declare const SIGN_WINDOW_SECONDS: number;
5
+ /**
6
+ * Build the `validUntil` Unix-epoch-second timestamp for a wallet sign
7
+ * request (TonConnect SDK + walletkit both use this convention).
8
+ * Used by `TonConnectProvider.sendTransactionMulti` and
9
+ * `agenticSignAndSend` so the same 5-minute window applies regardless
10
+ * of signing path.
11
+ */
12
+ export declare function signRequestValidUntilSeconds(): number;
@@ -0,0 +1,13 @@
1
+ export interface WalletUI {
2
+ choose<T>(message: string, options: T[], display: (t: T) => string): Promise<T>;
3
+ input(message: string): Promise<string>;
4
+ write(message: string): void;
5
+ setActionPrompt(message: string): void;
6
+ clearActionPrompt(): void;
7
+ }
8
+ export interface WalletUIOptions {
9
+ interactive: boolean;
10
+ defaultPick?: number;
11
+ preferByName?: string;
12
+ }
13
+ export declare function createWalletUI(opts: WalletUIOptions): WalletUI;
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "ton-mesh-harness",
3
+ "version": "0.13.0",
4
+ "description": "TON Mesh Harness — one-command CLI + MCP server to deploy a static site to .ton (TON Storage + .ton DNS + ADNL), self-host first, agent-callable. CLI, MCP server (4 tools), and a programmable SDK on one deploy contract.",
5
+ "main": "./dist/sdk.js",
6
+ "types": "./dist/sdk.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/sdk.d.ts",
10
+ "default": "./dist/sdk.js"
11
+ },
12
+ "./sdk": {
13
+ "types": "./dist/sdk.d.ts",
14
+ "default": "./dist/sdk.js"
15
+ },
16
+ "./package.json": "./package.json"
17
+ },
18
+ "bin": {
19
+ "ton-mesh-harness": "dist/cli.js",
20
+ "ton-mesh-harness-mcp": "dist/mcp.js"
21
+ },
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "os": [
26
+ "darwin",
27
+ "linux",
28
+ "win32"
29
+ ],
30
+ "scripts": {
31
+ "build": "bun run scripts/build.ts && bun run build:types",
32
+ "build:types": "tsc -p tsconfig.build.json",
33
+ "dev": "bun run scripts/build.ts --watch",
34
+ "test": "vitest run",
35
+ "test:watch": "vitest",
36
+ "lint": "eslint src/sdk",
37
+ "typecheck": "tsc --noEmit",
38
+ "smoke": "node scripts/cli-smoke.cjs && node scripts/mcp-smoke.cjs && node scripts/mcp-http-smoke.cjs && node scripts/sdk-smoke.cjs",
39
+ "smoke:full": "bun run smoke && node scripts/tarball-smoke.cjs",
40
+ "verify": "bun run lint && bun run typecheck && bun run test && bun run build && bun run smoke",
41
+ "pack:dry": "npm pack --dry-run"
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "templates",
46
+ "skills"
47
+ ],
48
+ "keywords": [
49
+ "ton",
50
+ "ton-storage",
51
+ "ton-dns",
52
+ "dot-ton",
53
+ "adnl",
54
+ "blockchain",
55
+ "deploy",
56
+ "static-site",
57
+ "website",
58
+ "storage",
59
+ "decentralized-web",
60
+ "censorship-resistant",
61
+ "mcp",
62
+ "mcp-server",
63
+ "agent-skill",
64
+ "claude-skill",
65
+ "tonconnect",
66
+ "agentic-wallet"
67
+ ],
68
+ "license": "MIT",
69
+ "dependencies": {
70
+ "@modelcontextprotocol/sdk": "^1.29.0",
71
+ "@ton/ton": "^15.4.0",
72
+ "@ton/walletkit": "^0.0.12-alpha.3",
73
+ "@tonconnect/sdk": "^3.4.1",
74
+ "chalk": "^4.1.2",
75
+ "chokidar": "^4.0.3",
76
+ "commander": "^12.1.0",
77
+ "ora": "^5.4.1",
78
+ "qrcode-terminal": "^0.12.0",
79
+ "zod": "^3.25.76"
80
+ },
81
+ "overrides": {
82
+ "axios": ">=1.16.0",
83
+ "form-data": ">=4.0.6",
84
+ "hono": ">=4.12.25",
85
+ "ws": ">=8.21.0"
86
+ },
87
+ "peerDependencies": {
88
+ "@ton/mcp": "^0.1.15-alpha.15"
89
+ },
90
+ "peerDependenciesMeta": {
91
+ "@ton/mcp": {
92
+ "optional": true
93
+ }
94
+ },
95
+ "devDependencies": {
96
+ "@ton/mcp": "^0.1.15-alpha.15",
97
+ "@types/node": "^25.5.0",
98
+ "@types/qrcode-terminal": "^0.12.2",
99
+ "eslint": "^9.39.4",
100
+ "typescript": "^5.9.3",
101
+ "typescript-eslint": "^8.59.2",
102
+ "vitest": "^2.1.9",
103
+ "zod-to-json-schema": "^3.25.2"
104
+ }
105
+ }
@@ -0,0 +1,283 @@
1
+ ---
2
+ name: mesh-deploy
3
+ description: Deploy a static site to .ton (TON Storage + .ton DNS) with one tool call. Censorship-resistant, no server, no CDN, no domain registrar.
4
+ ---
5
+
6
+ # Mesh Deploy — TON Storage + .ton DNS in one tool call
7
+
8
+ ## When to use
9
+
10
+ Use this skill when the user wants to publish a static site (built `dist/`,
11
+ `build/`, `out/`, or `public/` directory) to TON's digital-resistance stack
12
+ so the site:
13
+
14
+ - Cannot be taken down by hosting providers / domain registrars
15
+ - Survives geo-blocks
16
+ - Resolves at `<name>.ton` via TON DNS
17
+ - Is content-addressed (a bag id; the URL is the hash)
18
+
19
+ Trigger phrases (verbatim or paraphrased):
20
+ - "deploy this to .ton"
21
+ - "publish censorship-resistant"
22
+ - "TON Storage deploy"
23
+ - "host my site on TON"
24
+ - "I want a .ton domain pointing at this"
25
+
26
+ Skip this skill when:
27
+ - The site is a server-rendered app — TON Sites serve static content only
28
+ - The user wants a `.eth` domain or IPFS-only — different stack
29
+ - The deploy target is a private network (corporate intranet) — overkill
30
+
31
+ ## Prerequisites
32
+
33
+ Run `mesh_check_env` BEFORE `mesh_deploy` to surface fixable
34
+ problems early. Required:
35
+
36
+ - **Node ≥ 18** (the kit declares `engines.node: ">=18"`)
37
+ - **A built directory** (`dist/`, `build/`, `out/`, or `public/`)
38
+ - **UDP port 17555 free** (the tonutils-storage daemon binds here; TON
39
+ Browser.app conflicts — quit it before deploying)
40
+ - **TONAPI mainnet reachable** (the kit verifies the bag via TONAPI;
41
+ blocked behind a corporate proxy → tell the user to whitelist
42
+ `tonapi.io`)
43
+ - **Disk free ≥ 100 MB** for the daemon binary cache at `~/.ton-mesh/bin/`
44
+ - **One of two signing paths** (see "Signing modes" below)
45
+
46
+ If the user wants a `.ton` DNS record (most do — that's the human-readable
47
+ URL), they additionally need:
48
+ - **The `.ton` domain owned** by their TonConnect wallet (≈ 1 TON one-time
49
+ to mint)
50
+ - **≈ 0.02 TON** for the DNS write transaction gas
51
+
52
+ ## Signing modes
53
+
54
+ The kit supports two orthogonal signing paths via the `wallet` input:
55
+
56
+ ### Path 1 — TonConnect (human-signed, default)
57
+ ```json
58
+ { "wallet": { "kind": "tonconnect", "connector": "Tonkeeper" } }
59
+ ```
60
+ - The agent surfaces a `signing_url` via the `awaiting_signature` progress
61
+ event. The HUMAN opens it in their wallet app and approves.
62
+ - Use this when there's a human in the loop.
63
+ - Connector substring matches the TonConnect manifest name —
64
+ `"Tonkeeper"`, `"MyTonWallet"`, etc.
65
+
66
+ ### Path 2 — Agentic (autonomous, no human)
67
+ ```json
68
+ { "wallet": { "kind": "agentic" } }
69
+ ```
70
+ - The kit reads `~/.config/ton/config.json` (or `$TON_CONFIG_PATH`) — the
71
+ same file `@ton/mcp` writes via `agentic_start_root_wallet_setup`.
72
+ - Signing is fully autonomous — no human approval prompt.
73
+ - Use this when the agent operates without a user (CI, autonomous
74
+ agents, scheduled deploys).
75
+ - Set up the wallet once via:
76
+ ```bash
77
+ npx -y @ton/mcp@alpha agentic_start_root_wallet_setup
78
+ ```
79
+ Or load `@ton/mcp` as a peer MCP server and call its agentic
80
+ wallet management tools.
81
+
82
+ The signing modes are filesystem-level compose with `@ton/mcp`; there is
83
+ no inter-MCP RPC handoff.
84
+
85
+ ## Steps
86
+
87
+ ### 1. Pre-flight check
88
+ ```jsonc
89
+ // MCP call
90
+ {
91
+ "name": "mesh_check_env",
92
+ "arguments": { "source_dir": "./dist" }
93
+ }
94
+ ```
95
+ Returns a `CheckEnvResult`. If `ready: false`, the `blocking` array has
96
+ items with `code`, `message`, and `fix_hint`. Surface each `fix_hint` to
97
+ the user; don't proceed to deploy until `ready: true`.
98
+
99
+ ### 2. Deploy
100
+
101
+ TonConnect path (human-signed):
102
+
103
+ ```jsonc
104
+ // MCP call (rc5+)
105
+ {
106
+ "name": "mesh_deploy",
107
+ "arguments": {
108
+ "source_dir": "./dist",
109
+ "domain": "myprotocol.ton",
110
+ "wallet": { "kind": "tonconnect", "connector": "Tonkeeper" }
111
+ }
112
+ }
113
+ ```
114
+
115
+ Agentic path (autonomous — reads `~/.config/ton/config.json`):
116
+
117
+ ```jsonc
118
+ {
119
+ "name": "mesh_deploy",
120
+ "arguments": {
121
+ "source_dir": "./dist",
122
+ "domain": "myprotocol.ton",
123
+ "wallet": { "kind": "agentic", "wallet_label": "main-mainnet" }
124
+ }
125
+ }
126
+ ```
127
+
128
+ #### What rc5 MCP does end-to-end
129
+
130
+ From rc3+ the MCP server completes the **entire flow** — bag upload
131
+ AND .ton DNS write — for both wallet paths. `notifications/progress`
132
+ events fire in this order:
133
+
134
+ 1. `env_check` — preparing tonutils-storage
135
+ 2. `daemon_starting` — spawning the storage daemon
136
+ 3. `bag_creating` — uploading the build dir
137
+ 4. `bag_uploaded` — bag is on disk in the daemon
138
+ 5. `awaiting_signature` — TonConnect: `data.signing_url` is a tonkeeper://
139
+ deeplink, surface to the user. Agentic: `signing_url: null`, signing
140
+ proceeds locally and instantly.
141
+ 6. `dns_signing` — broadcast accepted by Toncenter (TonConnect: signed
142
+ message BOC in `data`; agentic: normalized message hash in `data`)
143
+ 7. `dns_confirmed` — DNS record propagated via TONAPI
144
+ 8. `verifying` — informational; TONAPI propagation IS the verification
145
+
146
+ Then the terminal `done` event with `DeployResult.dns_tx_hash` carrying
147
+ the **real on-chain tx hash** resolved via Toncenter v3
148
+ `transactionsByMessage` (rc4+), or `null` with a `next_actions` fallback
149
+ hint if Toncenter's index hadn't caught up by the 3s grace deadline.
150
+
151
+ ### 3. After deploy
152
+ - Tell the user the bag id (it's the content hash). Do NOT hand them
153
+ `https://ton.run/<bag_id>` — public gateways serve `.ton` domains, not raw
154
+ bag ids, so that URL 404s. A browser URL only exists once a `.ton` domain
155
+ points at the bag and a reachable node seeds it.
156
+ - If `dns_tx_hash` is non-null, surface a tonviewer link:
157
+ `https://tonviewer.com/transaction/<hash without 0x>`.
158
+ - If they passed `domain`, tell them `<domain>.ton` will resolve within
159
+ a few minutes after the DNS tx confirms (the `dns_confirmed` event
160
+ already implies TONAPI propagation succeeded).
161
+ - Suggest `--watch` mode (CLI) or a follow-up call if they expect the
162
+ build dir to change. **MCP rejects `keep_alive: true`** — use the CLI
163
+ if you need long-running watch.
164
+
165
+ ## Common mistakes
166
+
167
+ - **UDP port 17555 collision with TON Browser.app.** Quit the app before
168
+ deploying. `mesh_check_env` flags this as a blocker.
169
+ - **TONAPI unreachable in corporate networks.** Bag verification fails.
170
+ Whitelist `tonapi.io` or skip verification with `skip_verify: true`.
171
+ - **Forgetting that mainnet provider economy is dormant.** Do NOT suggest
172
+ `--provider` — the kit disabled it in v0.6 and v0.9 reserve will revisit.
173
+ - **Treating `--watch` as 24-hour hosting.** The daemon must keep running
174
+ for the bag to stay seedable. Suggest the user either keep their machine
175
+ on or contract a tunnel-rental (v0.9 reserve).
176
+ - **Empty `.ton` domain resolution.** The bag is created instantly but
177
+ TONAPI lags ~minutes; tell the user to wait if `.ton` returns nothing
178
+ immediately.
179
+
180
+ ## Examples
181
+
182
+ ### Minimal deploy (no DNS — just upload the bag)
183
+ ```jsonc
184
+ {
185
+ "name": "mesh_deploy",
186
+ "arguments": { "source_dir": "./dist" }
187
+ }
188
+ ```
189
+
190
+ ### Deploy with custom domain (default TonConnect)
191
+ ```jsonc
192
+ {
193
+ "name": "mesh_deploy",
194
+ "arguments": {
195
+ "source_dir": "./dist",
196
+ "domain": "myprotocol.ton",
197
+ "description": "MyProtocol v1.2.0 release build"
198
+ }
199
+ }
200
+ ```
201
+
202
+ ### Agentic deploy (no human)
203
+ ```jsonc
204
+ {
205
+ "name": "mesh_deploy",
206
+ "arguments": {
207
+ "source_dir": "./dist",
208
+ "domain": "ci-bot.ton",
209
+ "wallet": { "kind": "agentic", "wallet_label": "ci" }
210
+ }
211
+ }
212
+ ```
213
+
214
+ ### With tunnel client (NAT traversal, v0.9 reserve)
215
+ ```jsonc
216
+ {
217
+ "name": "mesh_deploy",
218
+ "arguments": {
219
+ "source_dir": "./dist",
220
+ "domain": "from-behind-nat.ton",
221
+ "tunnel_config": "/Users/me/.ton-tunnel/nodes-pool.json"
222
+ }
223
+ }
224
+ ```
225
+
226
+ ## Tool surface
227
+
228
+ - `mesh_check_env({ source_dir? })` → `CheckEnvResult`
229
+ - `mesh_deploy({ source_dir, domain?, wallet?, ... })` → `DeployResult`
230
+ - `mesh_status({ bag_id, domain?, testnet? })` → `StatusResult` (one-shot propagation snapshot)
231
+ - `mesh_site_record({ domain, site_adnl, testnet? })` → `SiteRecordResult` (Tonkeeper deeplink that sets only the `site` record; never broadcasts)
232
+
233
+ Full input/output schemas: see the `tools/list` response or
234
+ [`docs/v0.8/mcp-core-requirements.md`](https://github.com/Masashi-Ono0611/ton-mesh-harness/blob/main/docs/v0.8/mcp-core-requirements.md)
235
+ §F2.
236
+
237
+ ## Install
238
+
239
+ ```bash
240
+ # Per-call (recommended for agents)
241
+ npx -y --package ton-mesh-harness ton-mesh-harness-mcp
242
+
243
+ # Or pin globally
244
+ npm install -g ton-mesh-harness
245
+ ```
246
+
247
+ Add to your MCP client config:
248
+ ```jsonc
249
+ {
250
+ "mcpServers": {
251
+ "ton-mesh-harness": {
252
+ "command": "npx",
253
+ "args": ["-y", "--package", "ton-mesh-harness", "ton-mesh-harness-mcp"]
254
+ }
255
+ }
256
+ }
257
+ ```
258
+
259
+ For agentic-wallet flows, also load `@ton/mcp@alpha` so the kit can share
260
+ the wallet config:
261
+ ```jsonc
262
+ {
263
+ "mcpServers": {
264
+ "ton-mesh-harness": {
265
+ "command": "npx",
266
+ "args": ["-y", "--package", "ton-mesh-harness", "ton-mesh-harness-mcp"]
267
+ },
268
+ "ton": {
269
+ "command": "npx",
270
+ "args": ["-y", "@ton/mcp@alpha"]
271
+ }
272
+ }
273
+ }
274
+ ```
275
+
276
+ ## Source
277
+
278
+ - GitHub: https://github.com/Masashi-Ono0611/ton-mesh-harness
279
+ - License: MIT
280
+ - v0.8.0-rc1 first published 2026-05-10
281
+ - Status: rc5 — full end-to-end (bag upload + .ton DNS write via either
282
+ TonConnect or agentic signing path). v0.8.0 GA pending V3 (E2E
283
+ acceptance) + V4 (red-team) per the open Epic.
@@ -0,0 +1,44 @@
1
+ {
2
+ "_note_schema": "This is an experimental shape — there is no published JSON Schema at https://modelcontextprotocol.io/.well-known/ at the time of writing. Treat the file as a kit-specific self-description until/unless a standard MCP well-known schema lands. If a standard does land, add a $schema reference and update consumers.",
3
+ "_note_template": "This file is a TEMPLATE. Users who self-host the kit's dashboard at <domain>.ton can copy it into their build dir's .well-known/ so an agent visiting their site can discover the kit that published it (the 'View Source + Redeploy' axis from concept update 2026-05-10 Codex C proposal). The kit does NOT auto-write this file — copying is opt-in.",
4
+ "name": "ton-mesh-harness-mcp",
5
+ "version": "0.13.0",
6
+ "description": "Deploy a static site to .ton (TON Storage + .ton DNS, end-to-end). Censorship-resistant, no server, no CDN, no domain registrar. Agent-callable via MCP. Supports human-signed (TonConnect) and autonomous (agentic, reads ~/.config/ton/config.json shared with @ton/mcp) signing modes. Real on-chain dns_tx_hash via Toncenter v3 lookup.",
7
+ "homepage": "https://github.com/Masashi-Ono0611/ton-mesh-harness",
8
+ "install": {
9
+ "command": "npx",
10
+ "args": ["-y", "--package", "ton-mesh-harness", "ton-mesh-harness-mcp"]
11
+ },
12
+ "tools": [
13
+ {
14
+ "name": "mesh_check_env",
15
+ "summary": "Pre-flight readiness probe — call BEFORE mesh_deploy."
16
+ },
17
+ {
18
+ "name": "mesh_deploy",
19
+ "summary": "Deploy a static site to .ton (bag upload + DNS write, end-to-end) via TonConnect or agentic signing."
20
+ },
21
+ {
22
+ "name": "mesh_status",
23
+ "summary": "One-shot bag propagation + DNS resolution snapshot for a deployed site."
24
+ },
25
+ {
26
+ "name": "mesh_site_record",
27
+ "summary": "Build a Tonkeeper deeplink that sets only the site (ADNL) DNS record."
28
+ }
29
+ ],
30
+ "compose": {
31
+ "peer_mcp_servers": [
32
+ {
33
+ "name": "@ton/mcp",
34
+ "purpose": "agentic wallet management (autonomous signing). The kit reads ~/.config/ton/config.json — the same file @ton/mcp manages.",
35
+ "install": {
36
+ "command": "npx",
37
+ "args": ["-y", "@ton/mcp@alpha"]
38
+ }
39
+ }
40
+ ]
41
+ },
42
+ "skill_md": "https://github.com/Masashi-Ono0611/ton-mesh-harness/blob/main/skills/mesh-deploy.md",
43
+ "license": "MIT"
44
+ }