@arcnow/mcp 0.1.0 → 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/README.md +92 -83
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
> **This repository is a published mirror.** Every release of the arcnow.io MCP
|
|
2
|
-
> server lands here as one commit, tagged `vX.Y.Z`, with the `npm pack` tarball
|
|
3
|
-
> under [Releases](https://github.com/arcnow-io/arcnow-io-mcp/releases). Issues and pull requests are welcome
|
|
4
|
-
> here. The maintainers' tooling (the pin gate against the SDK's history, the
|
|
5
|
-
> fork proof against the contracts) is not part of the mirror, so `scripts/`
|
|
6
|
-
> referred to below is absent; `@arcnow/sdk` is a path dependency, so clone
|
|
7
|
-
> [arcnow-io/arcnow-io-sdk](https://github.com/arcnow-io/arcnow-io-sdk) as a
|
|
8
|
-
> sibling directory named `sdk` and build `sdk/typescript` first.
|
|
9
|
-
> Site: [www.arcnow.io](https://www.arcnow.io) - docs:
|
|
10
|
-
> [docs.arcnow.io](https://docs.arcnow.io).
|
|
11
|
-
|
|
12
1
|
# `@arcnow/mcp`
|
|
13
2
|
|
|
14
3
|
An [MCP](https://modelcontextprotocol.io) server that lets an AI assistant use
|
|
@@ -19,14 +8,42 @@ graduating, and, **only if the operator explicitly turns it on**, launch, buy,
|
|
|
19
8
|
sell and rescue a stranded migration.
|
|
20
9
|
|
|
21
10
|
Every chain interaction goes through
|
|
22
|
-
[`@arcnow/sdk`](https://
|
|
23
|
-
[`pins.json`](pins.json). Nothing here encodes a call or
|
|
11
|
+
[`@arcnow/sdk`](https://www.npmjs.com/package/@arcnow/sdk), pinned to an exact
|
|
12
|
+
published version in [`pins.json`](pins.json). Nothing here encodes a call or
|
|
13
|
+
computes a curve.
|
|
14
|
+
|
|
15
|
+
## Install and run
|
|
24
16
|
|
|
17
|
+
The server is on npm as [`@arcnow/mcp`](https://www.npmjs.com/package/@arcnow/mcp)
|
|
18
|
+
(Node 22.12 or newer). Run it straight from the registry:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
npx -y @arcnow/mcp # read-only. The default, and the useful part.
|
|
22
|
+
npx -y @arcnow/mcp --allow-writes # can spend, if ARCNOW_PRIVATE_KEY is in the environment.
|
|
25
23
|
```
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
|
|
25
|
+
Or tell an MCP client to. Claude Desktop, Cursor, Claude Code and the like all
|
|
26
|
+
take this shape in their MCP server configuration:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"mcpServers": {
|
|
31
|
+
"arcnow": {
|
|
32
|
+
"command": "npx",
|
|
33
|
+
"args": ["-y", "@arcnow/mcp"],
|
|
34
|
+
"env": { "ARCNOW_MCP_NETWORK": "arc-testnet" }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
28
38
|
```
|
|
29
39
|
|
|
40
|
+
A writes-enabled client adds `"--allow-writes"` to `args` and puts the key
|
|
41
|
+
**in a file**, never in the config: see [`examples/`](examples) for both shapes
|
|
42
|
+
and [Configuration](#configuration) for every variable. To run from source
|
|
43
|
+
instead, clone
|
|
44
|
+
[arcnow-io/arcnow-io-mcp](https://github.com/arcnow-io/arcnow-io-mcp), then
|
|
45
|
+
`npm ci && npm run build && node dist/index.js`; the SDK comes from npm.
|
|
46
|
+
|
|
30
47
|
---
|
|
31
48
|
|
|
32
49
|
## The two rules this server is built around
|
|
@@ -373,72 +390,62 @@ token. Gas is always native USDC, whatever a token's quote.
|
|
|
373
390
|
|
|
374
391
|
## The SDK, and how the pin works
|
|
375
392
|
|
|
376
|
-
`@arcnow/sdk`
|
|
377
|
-
|
|
378
|
-
|
|
393
|
+
`@arcnow/sdk` is published to npm from
|
|
394
|
+
[arcnow-io/arcnow-io-sdk](https://github.com/arcnow-io/arcnow-io-sdk), one tagged
|
|
395
|
+
release per version, and this server depends on it at an **exact version** —
|
|
396
|
+
`"@arcnow/sdk": "0.1.3"`, never `^0.1.3`. The tool descriptions promise what one
|
|
397
|
+
known SDK does; a range would let `npm install` move the code under them with no
|
|
398
|
+
commit here saying so. Moving the pin is a pull request.
|
|
379
399
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
400
|
+
[`pins.json`](pins.json) records it:
|
|
401
|
+
|
|
402
|
+
```json
|
|
403
|
+
"sdk": {
|
|
404
|
+
"package": "@arcnow/sdk",
|
|
405
|
+
"version": "0.1.3",
|
|
406
|
+
"integrity": "sha512-…",
|
|
407
|
+
"public_repo": "arcnow-io/arcnow-io-sdk",
|
|
408
|
+
"tag": "v0.1.3",
|
|
409
|
+
"why": ["what this server uses from that SDK, in prose"]
|
|
410
|
+
}
|
|
384
411
|
```
|
|
385
412
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
413
|
+
`integrity` is the sha512 of that version's tarball, as npm records it in
|
|
414
|
+
`package-lock.json` and serves it as `dist.integrity`. **The tarball is the
|
|
415
|
+
surface**: every module, the generated ABIs that encode every call, the
|
|
416
|
+
`networks.json` every address comes from — one hash. (Until the SDK was
|
|
417
|
+
published this file hashed its sources file by file and the gate recompiled its
|
|
418
|
+
`dist/`; the integrity replaces all of that.)
|
|
392
419
|
|
|
393
|
-
So the SDK is pinned the way `arcnow-io/sdk` pins `arcnow-io/contracts`, and
|
|
394
420
|
`scripts/check-pins.sh` (run straight after the install by `scripts/preflight.sh`)
|
|
395
|
-
enforces
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
**What is pinned is a rule, not a list:** `networks.json`,
|
|
424
|
-
`typescript/package.json`, and every file under `typescript/src` except
|
|
425
|
-
`typescript/src/errors/`. A module the SDK adds is surface the moment it exists.
|
|
426
|
-
The generated ABIs are inside the rule because they encode every call, and the
|
|
427
|
-
generated `networks.json` because it is the copy the SDK compiles its
|
|
428
|
-
**addresses** from. `errors/` is outside it: message prose behind a surface
|
|
429
|
-
`index.ts` already pins, where pinning would make every improved error message
|
|
430
|
-
a false alarm. `test/unit/check-pins.test.ts` builds real repositories and
|
|
431
|
-
breaks each link on purpose — a stale build, an unpinned module, an uncommitted
|
|
432
|
-
edit, a ref for a commit, a commit off the branch.
|
|
433
|
-
|
|
434
|
-
Moving the pin is a commit of its own: check the SDK out at the commit and build
|
|
435
|
-
it, run `scripts/check-pins.sh --record` — which records `sdk.commit` and every
|
|
436
|
-
surface hash from `HEAD`, and refuses an edit no commit carries — update
|
|
437
|
-
`sdk.why`, run preflight, and say what changed in the SDK surface and what it
|
|
438
|
-
meant for the tools. A tool description that still promises what an older SDK
|
|
439
|
-
did is a model quoting a wrong price.
|
|
440
|
-
|
|
441
|
-
Point the gate at a checkout somewhere else with `ARCNOW_SDK_DIR`.
|
|
421
|
+
enforces four things:
|
|
422
|
+
|
|
423
|
+
1. `package.json` depends on the SDK at **exactly** `sdk.version`. A range, a
|
|
424
|
+
`file:` path or another number fails, by name.
|
|
425
|
+
2. `package-lock.json`'s entry for it carries that version, resolves to the npm
|
|
426
|
+
registry, and its `integrity` **is** `sdk.integrity` — the link between the
|
|
427
|
+
version and the bytes; npm refuses to install a tarball that does not hash to
|
|
428
|
+
it.
|
|
429
|
+
3. `node_modules/@arcnow/sdk/package.json` is that version — what the server
|
|
430
|
+
actually compiles against and imports.
|
|
431
|
+
4. The registry has that version and serves it with that `dist.integrity`, so
|
|
432
|
+
the pinned bytes are the published bytes. This needs the network: unreachable
|
|
433
|
+
is a **warning** (a laptop on a train is not a broken pin) unless
|
|
434
|
+
`ARCNOW_REQUIRE_REGISTRY=1`, which CI sets; a 404 is always a failure.
|
|
435
|
+
|
|
436
|
+
Together: the manifest asks for one version, the lockfile binds it to one
|
|
437
|
+
tarball, `node_modules` holds it, and the registry says those are the bytes it
|
|
438
|
+
serves under that number. `test/unit/check-pins.test.ts` builds real roots with
|
|
439
|
+
a fake `npm` on `PATH` and breaks each link on purpose — a range, a path, a
|
|
440
|
+
foreign tarball, a stale install, a version the registry never had, a registry
|
|
441
|
+
that cannot be reached.
|
|
442
|
+
|
|
443
|
+
Moving the pin is a commit of its own: `npm install @arcnow/sdk@X.Y.Z
|
|
444
|
+
--save-exact`, `npm ci`, `scripts/check-pins.sh --record` — which records the
|
|
445
|
+
version, the lockfile's integrity and the tag, and refuses a range or a version
|
|
446
|
+
the registry does not have — update `sdk.why`, run preflight, and say what
|
|
447
|
+
changed in the SDK surface and what it meant for the tools. A tool description
|
|
448
|
+
that still promises what an older SDK did is a model quoting a wrong price.
|
|
442
449
|
|
|
443
450
|
---
|
|
444
451
|
|
|
@@ -458,16 +465,18 @@ repository in this org has made. **`scripts/preflight.sh` is the gate**; the
|
|
|
458
465
|
workflow is a transcription of it, kept because a clean-checkout run is the one
|
|
459
466
|
thing a local run cannot prove.
|
|
460
467
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
`
|
|
468
|
+
Everything but the fork proof needs nothing beyond `npm ci`: the SDK comes from
|
|
469
|
+
npm. The fork proof is the maintainers' **private infrastructure**: it starts one
|
|
470
|
+
container, an anvil fork of Arc testnet from the Foundry image `pins.json` pins,
|
|
471
|
+
labelled `io.arcnow.mcp.test`, and deploys arcnow.io's 3.x multi-quote contracts
|
|
472
|
+
onto it with the private `arcnow-io/sdk` checkout's `scripts/fork-deploy-stack.sh`
|
|
473
|
+
(`ARCNOW_SDK_DIR`, default `../sdk`). Arc testnet now runs a 3.x stack of its own,
|
|
465
474
|
deployed on 2026-09-15, but the fork is taken at a pinned, already-cached block
|
|
466
475
|
from before that, where the live contracts are the 2.x ones the SDK refuses — and
|
|
467
476
|
a proof that deploys its own stack does not depend on what happens to be live
|
|
468
|
-
anyway. That needs `ARCNOW_CONTRACTS_DIR`, a checkout
|
|
469
|
-
of arcnow-io/contracts at the commit
|
|
470
|
-
the release it names. Its harness —
|
|
477
|
+
anyway. That also needs `ARCNOW_CONTRACTS_DIR`, a checkout
|
|
478
|
+
of arcnow-io/contracts at the commit that SDK checkout's `pins.json` names, and
|
|
479
|
+
forge at the release it names. Its harness —
|
|
471
480
|
copied from `arcnow-io/sdk`'s, not imported, because that repository's tests are
|
|
472
481
|
not part of the pinned surface — removes it on every exit path, sweeps only its
|
|
473
482
|
own label, and touches nothing else on a shared daemon.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcnow/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "An MCP server for arcnow.io on Arc: read the curves, quote a trade, and — only when the operator opts in — launch, buy and sell.",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"start": "node dist/index.js"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@arcnow/sdk": "
|
|
33
|
+
"@arcnow/sdk": "0.1.3",
|
|
34
34
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
35
35
|
"viem": "^2.56.3",
|
|
36
36
|
"zod": "^4.6.2"
|