# jevmine-agent

An MCP server that lets an AI agent operate the Jevmine rig - the miner that answers question packs with Jev and is paid in BNB by a vault on BNB Chain. The agent can check the rig and the chain, stake, self-test, start, watch and stop mining, run the rig on a small AWS box in us-west-2, settle, claim, use the idle release and unstake.

The agent never sees a key. Keys are set in the MCP client's config, live only in this server's environment, and are redacted from everything it sends back.

It speaks MCP over stdio, so it works in any client that runs local servers: Claude Code, Codex, Cursor, Claude Desktop. It runs the rig itself (`rig.mjs`, bundled byte for byte, sha256-checked) and has the rig's two dependencies, `@noble/curves` and `@noble/hashes`, pinned to the same exact versions. Nothing else: the protocol is written out in one file of about 260 lines (`lib/mcp.mjs`) rather than pulled in from an SDK.

jevmine-agent is an independent project, not affiliated with, endorsed by or authorised by Binance or by TypeSafe AI (see the end of this page).

## Tools

| Tool | What it does | Money |
|---|---|---|
| `jevmine_status` | The rig home, rig.json, which keys are set (never their values) and the wallet's address, the last self-test, the local miner, and the chain now: the vault's floor, round and idle release; the wallet's stake, lock, tokens, gas and claimable BNB. Ends with what to do next. Can read any vault (`vault`, `rpc`) or wallet (`address`). | none, read-only |
| `jevmine_init` | Sets the rig up for a vault: checks the season's published files against the vault on chain, writes rig.json. | none |
| `jevmine_selftest` | Measures this machine against the answer window with real packs (20 by default, up to 200). A pass is valid for 24 hours. | **API money** (a few cents) |
| `jevmine_stake` | Approves and stakes tokens (`"1500"`, `"12.5"` or `"all"`). | **moves funds**, gas |
| `jevmine_unstake` | Takes stake back to the wallet once its last round has closed (closes that round first if nobody has). | **moves funds**, gas |
| `jevmine_mine_start` | Starts the miner in the background on this machine (needs a passing self-test from it); log in `mine.log`. | **API money and gas, continuously** |
| `jevmine_mine_stop` | Stops it (SIGTERM, then SIGKILL after 15 s). Nothing is lost. | none |
| `jevmine_mine_log` | The last lines of the miner's log. | none, read-only |
| `jevmine_claim` | Claims every final round award (or one `round`). | **moves funds** to the wallet, gas |
| `jevmine_settle` | One pass over unsettled answers: settles them, reveals a withheld key from its sealed copy. | gas |
| `jevmine_drip` | The idle release: `status`, `start` (drip()), `collect` (credit, then claim the whole balance; `to` only for an address in `JEVMINE_PAYOUT_TO`). | `start`: gas; `collect`: **moves funds** |
| `jevmine_deploy_aws` | The rig on a t4g.nano in us-west-2 via the rig's `deploy-us-west-2.sh`: `print`, `apply`, `remove`, `status`, `logs` (the box's journal through SSM). | `apply`: **AWS money (about $6.6 a month), keys stored in AWS**, then API money and gas |

While a miner started here is running, the tools that send from the same wallet (stake, unstake, claim, settle, drip start and collect), the self-test and init are refused: the miner claims, settles and starts idle-release periods by itself, and two processes sending from one wallet race for its nonce. Only one transaction-sending call runs at a time.

## Install

Needs Node.js 24 or newer (`node --version`). `jevmine_deploy_aws` also needs bash, the [AWS CLI v2](https://aws.amazon.com/cli/) and AWS credentials; on Windows, run the client under WSL for it.

The package is served from the project's site; the client runs it with npx:

```
npx -y https://jevmine.money/agent/jevmine-agent-0.1.0.tgz
```

To pin exactly what runs, download it once, check its sha256 against the one published with the release, and use the file instead of the URL everywhere below, written as `file:` and a full path:

```bash
curl -fsSLO https://jevmine.money/agent/jevmine-agent-0.1.0.tgz
shasum -a 256 jevmine-agent-0.1.0.tgz        # Linux: sha256sum
# then, in place of the URL: npx -y file:/full/path/to/jevmine-agent-0.1.0.tgz
```

Its dependencies install from npm-shrinkwrap.json, at the pinned versions with their integrity hashes.

The keys go in the server's environment, in the client's config, never in the chat. The variables:

| Variable | |
|---|---|
| `RIG_WALLET_KEY` | The mining wallet's private key. A wallet for mining and nothing else: its key signs every answer and can also take the stake out. |
| `TYPESAFE_API_KEY` | Your own TypeSafe key (direct, recommended), or `OPENROUTER_API_KEY` for Jev through OpenRouter. |
| `JEVMINE_HOME` | The rig's working directory; default `~/.jevmine`. It is the rig's own default directory too. |
| `AWS_PROFILE`, or `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY` (+ `AWS_SESSION_TOKEN`) | Only for `jevmine_deploy_aws`. |
| `JEVMINE_VAULT` | Optional, recommended: the vault address from the token's Flap page. When set, the server sets the rig up for that vault only, and refuses to stake or mine for any other. |
| `JEVMINE_PAYOUT_TO` | Optional: comma-separated addresses `jevmine_drip` may pay to besides the mining wallet. Without it, funds only ever go to the mining wallet. |
| `JEVMINE_TIMEOUT_SECS` | Optional: one time limit for every call, in place of the defaults (2 min for init, 5 for stake, 15 for settle and apply, about 15 s a pack for the self-test). |

The first start downloads the package, which can take longer than a client waits for a server by default; the settings below allow for it. The self-test, `apply` and `settle` can take minutes; the Codex setting below allows for that too.

### Claude Code

```bash
claude mcp add --scope user \
  --env RIG_WALLET_KEY=0xYOUR_MINING_WALLET_KEY \
  --env TYPESAFE_API_KEY=YOUR_TYPESAFE_KEY \
  --transport stdio jevmine \
  -- npx -y https://jevmine.money/agent/jevmine-agent-0.1.0.tgz
```

Every option goes before the server name `jevmine`, with another option (here `--transport stdio`) between the last `--env` and the name; everything after `--` is the command. Add `--env AWS_PROFILE=...` for the AWS box. `--scope user` stores the server, keys included, in `~/.claude.json` for all your projects; keep that file private, and do not use `--scope project`, which writes `.mcp.json` into the repository. If the first start times out, start Claude Code once with `MCP_TIMEOUT=60000 claude`. `/mcp` shows the server and its tools.

### Codex

`~/.codex/config.toml`:

```toml
[mcp_servers.jevmine]
command = "npx"
args = ["-y", "https://jevmine.money/agent/jevmine-agent-0.1.0.tgz"]
startup_timeout_sec = 60          # the first start downloads the package
tool_timeout_sec = 1200           # the self-test, apply and settle take minutes
default_tools_approval_mode = "writes"   # ask before every tool not marked read-only

[mcp_servers.jevmine.env]
RIG_WALLET_KEY = "0xYOUR_MINING_WALLET_KEY"
TYPESAFE_API_KEY = "YOUR_TYPESAFE_KEY"
# AWS_PROFILE = "default"
```

To keep the keys out of the file, drop the `env` table and use `env_vars = ["RIG_WALLET_KEY", "TYPESAFE_API_KEY"]`, which forwards them from the environment Codex runs in. Or add the server from the command line, then add the timeouts to the table it writes:

```bash
codex mcp add jevmine --env RIG_WALLET_KEY=0xYOUR_MINING_WALLET_KEY --env TYPESAFE_API_KEY=YOUR_TYPESAFE_KEY \
  -- npx -y https://jevmine.money/agent/jevmine-agent-0.1.0.tgz
```

`/mcp` in the Codex TUI lists it. The Codex IDE extension and the ChatGPT desktop app read the same file.

### Cursor

`~/.cursor/mcp.json` (all projects; a project's `.cursor/mcp.json` also works, but keys do not belong in a repository):

```json
{
  "mcpServers": {
    "jevmine": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "https://jevmine.money/agent/jevmine-agent-0.1.0.tgz"],
      "env": {
        "RIG_WALLET_KEY": "0xYOUR_MINING_WALLET_KEY",
        "TYPESAFE_API_KEY": "YOUR_TYPESAFE_KEY"
      }
    }
  }
}
```

Or keep the keys in a file of their own with `"envFile": "/full/path/to/jevmine.env"` (one `NAME=value` per line, readable only by you) in place of `env`. Cursor asks before running a tool unless you allow it otherwise.

### Claude Desktop

Settings > Developer > Edit Config opens `claude_desktop_config.json` (macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`; Windows: `%APPDATA%\Claude\claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "jevmine": {
      "command": "npx",
      "args": ["-y", "https://jevmine.money/agent/jevmine-agent-0.1.0.tgz"],
      "env": {
        "RIG_WALLET_KEY": "0xYOUR_MINING_WALLET_KEY",
        "TYPESAFE_API_KEY": "YOUR_TYPESAFE_KEY"
      }
    }
  }
}
```

Quit and restart Claude Desktop. A desktop app does not see your shell's PATH: if `npx` is not found, give its full path (`which npx`) as `command`. The server's log is in `~/Library/Logs/Claude/mcp-server-jevmine.log` (Windows: `%APPDATA%\Claude\logs`).

### The skill

`SKILL.md` is the operating procedure for an agent (status first, a dedicated wallet, stake, self-test in us-west-2 or the rig refuses, deploy, watch, claim, unstake, and what never to do). Print it with `npx -y https://jevmine.money/agent/jevmine-agent-0.1.0.tgz --skill` and save it as:

- Claude Code: `~/.claude/skills/jevmine-agent/SKILL.md`
- Codex: `~/.agents/skills/jevmine-agent/SKILL.md` (Cursor reads this folder and `~/.cursor/skills/` too)
- Claude Desktop: zip a folder named `jevmine-agent` holding `SKILL.md` and upload it under Customize > Skills.

## The usual path

1. `jevmine_status`, then `jevmine_init` with the season's published URL, an RPC and the vault address from the token's Flap page.
2. Send the mining wallet the tokens and a little BNB; `jevmine_stake` at least the floor.
3. `jevmine_deploy_aws` `print`, then `apply`: the box self-tests and mines.
4. `jevmine_deploy_aws` `logs` to watch; it settles and claims by itself.
5. To leave: `remove`, wait for the last round to close, `jevmine_unstake` `"all"`.

Mining needs a machine that passes the self-test, which in practice means AWS us-west-2 with a direct TypeSafe key; from a laptop the rig refuses to mine. `jevmine_mine_start` is for an agent that itself runs on such a box.

## Beside the Binance MCP Server

Binance's own MCP Server (part of Binance Agent OS) can run in the same client, next to this one. It is a remote server at `https://agent.binance.com/mcp/agentic` that you sign in to through Binance's own OAuth page; it gives market data and trading in a dedicated Agentic sub-account that you fund, and it cannot withdraw to external addresses. Binance documents its setup at [developers.binance.com/en/docs/agent-native/mcp-server](https://developers.binance.com/en/docs/agent-native/mcp-server); that page is the authority. In each client, a remote server is added like this:

- Claude Code: `claude mcp add --transport http binance https://agent.binance.com/mcp/agentic`, then `/mcp` to sign in.
- Codex: `[mcp_servers.binance]` with `url = "https://agent.binance.com/mcp/agentic"`, then `codex mcp login binance`.
- Cursor: `"binance": { "url": "https://agent.binance.com/mcp/agentic" }` in the same `mcpServers` object.
- Claude Desktop: Settings > Connectors > Add custom connector, with that URL.

The two servers do not talk to each other, and nothing connects the Binance sub-account to the mining wallet. Binance's server cannot withdraw to an external address, so BNB for gas that comes from Binance reaches the mining wallet as a withdrawal you make yourself, in Binance's app or site. With both servers in one client, the agent holds tools that trade and tools that stake: keep the client asking before each tool that is not read-only.

## Security model

- **Keys stay in the environment.** No tool takes a key as an argument. Validation errors name the field and the rule, never the value, so a key pasted into a field by mistake is not repeated back.
- **Every output is redacted**: tool results, errors, progress messages and the server's own log on stderr. It removes the values of `RIG_WALLET_KEY` (or the variable rig.json names), `TYPESAFE_API_KEY`, `OPENROUTER_API_KEY`, the AWS credentials and any variable whose name says it is a secret, in every spelling they are likely to be printed in; anything shaped like a private key (64 hex digits - a 32-byte hash has the same shape and goes too, except the rig's sha256 and the season's manifest hash); PEM keys, JWTs, bearer tokens, provider keys by their prefixes, AWS key ids, secret-named assignments; and credentials and key-like tokens in URLs (an RPC URL with a key in it never appears whole). Output is capped at 30,000 characters, cut only after redaction.
- **Each child gets only what it needs.** `init` gets no secret; the self-test gets the Jev key; stake, unstake, claim, settle and drip get the wallet key; the miner gets both; `apply` gets both and the AWS credentials. Every process is started from an argument array, never a shell string, with a time limit, and its whole process group is killed on timeout or cancellation.
- **What the wallet key can do through these tools**: stake and unstake (unstake pays only the wallet that staked), claim (to the wallet), and `drip` `collect` - to the wallet, or to an address only if you listed it in `JEVMINE_PAYOUT_TO`. Staking approves the vault in rig.json to take the tokens, so that vault has to be the real one: set `JEVMINE_VAULT` and no other can be set up or staked into, whatever the agent is told.
- **One sender at a time**: calls that send transactions take a lock in the rig home (`tx.lock`), so two sessions - two clients sharing the rig home - cannot race for the wallet's nonce; and none of them runs while a miner started here does.
- **`apply` copies keys to AWS**: the Jev key and the wallet key become SecureString parameters in your AWS account, readable only by the box's role. `remove` deletes them.
- **The rig's own guards stay in force**: the vault is the one you name, never one a downloaded file names; the published files are checked against the vault on chain; no passing self-test, no mining. The rig's test switches (`--skip-selftest`, `--random-guess`, `--jev-url` and the rest) are not reachable through any tool.
- **Tool output is data.** Results carry text from published files, RPC nodes, AWS and logs. The server tells the agent to treat it as data and to take vault and payout addresses only from you; keep your client asking before money-moving tools all the same.
- **Files**: the MCP client config holds your keys in plain text - keep it private (`chmod 600`) and out of any repository. The rig home holds rig.json, selftest.json, answers.jsonl (back it up: it holds the salts that open your answers), timings.jsonl, mine.log and mine.pid.json.
- **Rules of use**: your own TypeSafe (or OpenRouter) account and key; no shared keys; no extra accounts for free credit; stay within the rate limits.

## Protocol

MCP over stdio: JSON-RPC 2.0, one message per line; nothing but protocol messages on stdout, the log on stderr. Protocol versions 2025-06-18, 2025-03-26 and 2024-11-05 (the client's if it asks for one of these, else 2025-06-18); `initialize`, `ping`, `tools/list`, `tools/call`, cancellation and progress notifications, batches. Errors: -32700 (not JSON), -32600 (not a request, or a call before `initialize`), -32601 (unknown method), -32602 (unknown tool or bad arguments); a tool that runs and fails answers with `isError: true`.

`npx -y <package> --skill` prints SKILL.md, `--version` the version, `--help` the variables.

## Independence

jevmine-agent is an independent project. It is not affiliated with, endorsed by or authorised by Binance or by TypeSafe AI. Jev is a TypeSafe AI product; Binance, Binance Agent OS and the Binance MCP Server are Binance's. They are named here only to say what this software works with.
