Skip to main content
Glama
NikkeTryHard

safetrade-mcp

by NikkeTryHard
README.md
# safetrade-mcp

Docs-driven Model Context Protocol server for the SafeTrade REST API.

This MCP is intentionally not a one-tool-per-endpoint wrapper. It gives agents a small generic client that reads SafeTrade's OpenAPI docs, validates requests against those docs by default, signs private calls internally, and keeps API secrets out of prompts and command lines.

## Tools

### `safetrade_openapi`

Inspect the SafeTrade OpenAPI spec cached by the MCP.

Arguments:

- `path` optional API path, such as `/trade/public/tickers` or `/trade/account/members/me`
- `method` optional HTTP method when `path` is supplied

Use this first to discover paths, methods, query parameters, body schemas, and response shapes.

### `safetrade_request`

Execute a generic SafeTrade REST request.

Arguments:

- `method`: `GET`, `POST`, `PUT`, `PATCH`, or `DELETE`; default `GET`
- `path`: relative SafeTrade API path starting with `/`
- `query`: object of query parameters
- `body`: JSON body for non-GET requests
- `auth`: `auto`, `none`, or `required`; default `auto`
- `validate`: validate method/path against OpenAPI before sending; default `true`
- `timeoutMs`: request timeout; default `15000`, max `60000`
- `confirmDangerous`: must be `ALLOW_WITHDRAW` for withdraw mutations when withdraws are enabled

## Safety model

- Credentials are read from environment variables or a local key file.
- Credentials are never returned in tool output.
- Key files must not be group/world readable. Mode `600` is required.
- Withdraw mutation endpoints are blocked by default.
- To allow withdraw mutations, both conditions are required:
  - environment variable `SAFETRADE_ALLOW_WITHDRAW=true`
  - request argument `confirmDangerous: "ALLOW_WITHDRAW"`

For normal agent use, create a SafeTrade API key without withdraw permission and IP-lock it at SafeTrade.

## Secrets

Preferred key file:

```json
{
  "apiKey": "...",
  "apiSecret": "..."
}
```

Default path:

```text
~/.config/opencode/keys/safetrade.json
```

Permissions:

```sh
chmod 600 ~/.config/opencode/keys/safetrade.json
```

Environment variables are also supported:

```sh
SAFETRADE_API_KEY=...
SAFETRADE_API_SECRET=...
```

## Install

```sh
bun install
```

## Run

```sh
bun run index.ts
```

Self-test:

```sh
bun run index.ts --self-test
```

The self-test checks:

- OpenAPI lookup works
- live public `/trade/public/tickers` request returns HTTP 200
- withdraw mutation guard blocks before request

If credentials are configured, MCP clients can also call private endpoints such as `/trade/account/members/me` through `safetrade_request`.

## OMP MCP config example

```json
{
  "mcpServers": {
    "safetrade": {
      "type": "stdio",
      "command": "/home/cachybtw/.bun/bin/bun",
      "args": [
        "run",
        "/home/cachybtw/.config/opencode/mcp/safetrade-mcp/index.ts"
      ],
      "env": {
        "PATH": "/home/cachybtw/.local/bin:/home/cachybtw/.bun/bin:/usr/local/bin:/usr/bin:/bin",
        "SAFETRADE_KEYS_FILE": "/home/cachybtw/.config/opencode/keys/safetrade.json"
      },
      "enabled": true
    }
  }
}
```

## Auth details

The signing implementation follows SafeTrade's official example client:

- header `X-Auth-Apikey`: API key
- header `X-Auth-Nonce`: millisecond timestamp
- header `X-Auth-Signature`: `HMAC_SHA256(apiSecret, nonce + apiKey)` as lowercase hex

## License

MIT