Skip to main content
Glama
anaisbetts

stonex-mcp

by anaisbetts
README.md
# stonex-mcp

Typed TypeScript client for the StoneX Client (`torchapi`) REST API, plus an MCP server that exposes those endpoints as tools.

Auth is **not** automated (no Okta/MFA in this project). You log into StoneX Client in a browser, export a `cookies.txt` file, and pass the **path** to that file on the CLI.

## Requirements

- [Bun](https://bun.sh) 1.1+ (for local development / `prepare` build)
- Node.js 18+ (to run the published `bin` bundle)

## Install

```bash
bun install
```

## Auth: cookies.txt

1. Install a browser extension that exports Netscape `cookies.txt` (e.g. [**Get cookies.txt LOCALLY**](https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc?hl=en)).
2. Log into [https://client.stonex.com/client/](https://client.stonex.com/client/).
3. Export cookies for `client.stonex.com` to a file (e.g. `client.stonex.com_cookies.txt`).
4. Pass that path to the server:

```bash
stonex-mcp --cookies /path/to/client.stonex.com_cookies.txt
```

The server reads session cookies from that file and calls `GET https://client.stonex.com/client/token` only when it needs a Bearer JWT.

### Token cache

Derived access tokens are cached on disk so repeated MCP tool calls do not mint a new token every time:

| OS | Path |
|----|------|
| Windows | `%LOCALAPPDATA%\stonex-mcp\access-token.json` |
| macOS | `~/Library/Caches/stonex-mcp/access-token.json` |
| Linux | `${XDG_CACHE_HOME:-~/.cache}/stonex-mcp/access-token.json` |

When the cached JWT is missing or near expiry, a new token is requested using the cookies file and written back to the cache. If refresh starts failing with `401`, re-export cookies after logging into StoneX Client again.

Treat the cookies file and cached token like passwords. Do not commit them.

## Run the MCP server

```bash
bun start -- --cookies /path/to/client.stonex.com_cookies.txt
# or after build:
node dist/stonex-mcp.js --cookies /path/to/client.stonex.com_cookies.txt
```

### Cursor / Claude Desktop config

```json
{
  "mcpServers": {
    "stonex": {
      "command": "npx",
      "args": [
        "-y",
        "stonex-mcp",
        "--cookies",
        "C:/Users/YOU/Downloads/client.stonex.com_cookies.txt"
      ]
    }
  }
}
```

`npx` runs the built Node bundle (`dist/stonex-mcp.js`, produced by `bun run build` / `prepare`). Local equivalent: `"command": "bun", "args": ["run", "/path/to/stonex-mcp/src/cli.ts", "--cookies", "/path/to/cookies.txt"]`.

## Typed client

```ts
import { StoneXClient } from "./src/client/index.ts";
import { sessionCookieFromCookiesTxtFile } from "./src/auth/cookiesTxt.ts";
import { resolveAuth } from "./src/auth/resolveAuth.ts";
import { writeTokenCache } from "./src/auth/tokenCache.ts";

const { accessToken, sessionCookie } = await resolveAuth(
  "/path/to/client.stonex.com_cookies.txt",
);

const client = new StoneXClient({
  accessToken,
  sessionCookie,
  onAccessToken: (token) => writeTokenCache(token),
});

const accounts = await client.getAccounts();
const summary = await client.getAccountSummary({
  accountNumber: accounts[0]!.acctNo,
});
```

Or build a cookie header yourself with `sessionCookieFromCookiesTxtFile(...)`.

Endpoints mirror the StoneX Client SPA (`https://vulcan.stonex.com/torchapi`): accounts, balances, summary, positions, activity, performance, projected income, documents, and related user/account metadata.