movmint-fx-mcp
MCP server for the Movmint FX quoting and capture service. Exposes two tools (get_fx_quote, capture_fx_quote) that LLM clients can call to get live FX rates and execute trades.
---
Architecture
How it fits together
┌─────────────────────────────────────────────────────────────────┐
│ LLM Client (Claude Desktop / Open WebUI + Ollama) │
└───────────────────────┬─────────────────────────────────────────┘
│
┌─────────────▼──────────────┐
│ Transport layer │
│ │
│ Option A: stdio │ ← Claude Desktop spawns
│ (no port, no proxy) │ the process directly
│ │
│ Option B: HTTP via mcpo │ ← Open WebUI / Ollama
│ localhost:8008 │ connects as tool server
└─────────────┬──────────────┘
│
┌─────────────▼──────────────┐
│ MCP Server (Node.js) │
│ src/index.ts │
│ │
│ Tools: │
│ • get_fx_quote │
│ • capture_fx_quote │
└─────────────┬──────────────┘
│ OAuth2 client_credentials
│ Bearer token (cached, auto-refreshed)
┌─────────────▼──────────────┐
│ Movmint API │
│ api.nextgen.digitalfiat.app│
│ │
│ POST /fx/quote │
│ POST /fx/quote/capture/:id│
└────────────────────────────┘
MCP Server (src/index.ts)
Written in TypeScript using the @modelcontextprotocol/sdk. Key behaviours:
- Transport:
StdioServerTransport— communicates over stdin/stdout. Does not bind to a network port by itself. - Auth: OAuth2
client_credentialsflow. Tokens are cached in memory and refreshed 30 seconds before expiry. - Validation: Tool inputs are validated with
zodschemas before the API is called.
Tool: get_fx_quote
Calls POST /fx/quote on the Movmint API.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | from_currency | string | Yes | Source currency code (e.g. BSD, USD) | | to_currency | string | Yes | Target currency code (e.g. USDC, EUR) | | amount | number | Yes | Amount in from_currency | | funding_method | IMMEDIATE \| DEFERRED | No | Defaults to IMMEDIATE | | tx_configuration | object | Yes | Client reference ID + source/target payment config | | participants | array | No | KYC participants (ULTIMATE_ORIGINATOR, ULTIMATE_BENEFICIARY, etc.) |
Returns a quote_id valid for approximately 30 seconds.
Tool: capture_fx_quote
Calls POST /fx/quote/capture/{quote_id} on the Movmint API.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | quote_id | string | Yes | The quote_id returned from get_fx_quote |
Returns transaction details including the deposit address for funding.
Payment configuration schemas
tx_configuration accepts source_configuration and target_configuration, each with a source_type and an account_configuration that is one of:
| Type | Fields | |------|--------| | BANK_ACCOUNT | account_number, routing_number, account_type (CHECKING/SAVINGS) | | DLT_WALLET | wallet_address, network (ethereum/solana/base/sanddollar) | | CARD | card_number, expiry_date, cvv, cardholder_name, card_type (CreditCard/DebitCard) |
---
Environment variables
| Variable | Default | Required | |----------|---------|----------| | CLIENT_ID | — | Yes | | CLIENT_SECRET | — | Yes | | MOVMINT_BASE_URL | https://api.nextgen.digitalfiat.app | No | | MOVMINT_TOKEN_URL | https://api.nextgen.digitalfiat.app/oauth2/token | No | | MOVMINT_TOKEN_AUDIENCE | fx-service | No |
Store these in a .env file at the project root (never commit it — it is gitignored).
CLIENT_ID=your-client-id
CLIENT_SECRET=your-client-secret
MOVMINT_BASE_URL=https://api.nextgen.digitalfiat.app
MOVMINT_TOKEN_URL=https://api.nextgen.digitalfiat.app/oauth2/token
MOVMINT_TOKEN_AUDIENCE=fx-service
---
Bootstrap: running locally
Prerequisites
- Node.js 20+
uvx(ships withuv) — for runningmcpowithout a permanent install
1. Install dependencies and build
cd /path/to/movmint-fx-mcp
npm install
npm run build # compiles src/ → dist/
2. Option A — Claude Desktop (stdio, no proxy needed)
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"movmint-fx": {
"command": "node",
"args": ["/absolute/path/to/movmint-fx-mcp/dist/index.js"],
"env": {
"CLIENT_ID": "your-client-id",
"CLIENT_SECRET": "your-client-secret"
}
}
}
}
Restart Claude Desktop. The tools appear automatically in the tool picker.
2. Option B — Open WebUI + Ollama (HTTP via mcpo)
mcpo is a proxy that wraps any stdio MCP server and exposes it as an OpenAI-compatible HTTP tool server. Open WebUI can then connect to it as a tool source for any hosted model including Ollama models.
Port map (confirmed on this machine)
| Service | Port | |---------|------| | Ollama | 11434 | | Open WebUI | 8080 | | mcpo (this server) | 8008 |
Step 1 — Create mcpo-config.json
Create mcpo-config.json at the project root (it is gitignored):
{
"mcpServers": {
"movmint-fx": {
"command": "node",
"args": ["/absolute/path/to/movmint-fx-mcp/dist/index.js"],
"env": {
"CLIENT_ID": "your-client-id",
"CLIENT_SECRET": "your-client-secret",
"MOVMINT_BASE_URL": "https://api.nextgen.digitalfiat.app",
"MOVMINT_TOKEN_URL": "https://api.nextgen.digitalfiat.app/oauth2/token",
"MOVMINT_TOKEN_AUDIENCE": "fx-service"
}
}
}
}
Step 2 — Start mcpo
uvx mcpo --port 8008 --config /absolute/path/to/movmint-fx-mcp/mcpo-config.json
Verify it is running:
curl http://localhost:8008/docs # OpenAPI/Swagger UI
curl http://localhost:8008/openapi.json
Step 3 — Connect Open WebUI
- Open WebUI → Admin Panel → Settings → Tools
- Add tool server URL:
http://localhost:8008 - Open WebUI discovers
get_fx_quoteandcapture_fx_quoteautomatically via the OpenAPI spec - Enable the tools when starting a chat with any Ollama model
3. Development mode (watch + rebuild)
npm run dev # tsc --watch, rebuilds dist/ on every save
Run mcpo in a separate terminal; it will pick up the rebuilt dist/index.js on the next tool invocation (the Node process is spawned fresh per mcpo request).
---
Project structure
movmint-fx-mcp/
├── src/
│ └── index.ts # MCP server — tools, auth, API client
├── dist/ # Compiled output (gitignored)
├── interactions/
│ └── SD-CAD_SD-USD Collection.postman_collection.json
├── mcpo-config.json # mcpo proxy config with credentials (gitignored)
├── package.json
├── tsconfig.json
├── .env # Local credentials (gitignored)
└── .gitignore
---
Security notes
mcpo-config.jsonand.envboth contain credentials and are gitignored. Do not commit either file.- The MCP server logs the token request URL and body to
stderrfor debugging. Avoid piping stderr to shared log aggregators in production. - The
quote_idreturned byget_fx_quoteexpires in ~30 seconds. Do not store or reuse stale quote IDs.






