Blink MCP Server
Official# Blink MCP Server
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that provides AI assistants with access to the [Blink](https://blink.sv) Bitcoin and Lightning Network API.
## Features
- **Lightning Network**: Create and pay invoices, send to Lightning addresses
- **On-Chain Bitcoin**: Generate addresses, send transactions, estimate fees
- **Stablesats (USD)**: Full support for USD-denominated wallets
- **Intraledger Transfers**: Free instant transfers between Blink users
- **Webhooks**: Register callbacks for payment notifications
- **Real-time Subscriptions**: Monitor invoice status and account updates
- **Price Data**: Get real-time and historical Bitcoin prices
- **L402 Consumer**: Discover, pay for, and cache tokens for L402-gated APIs
- **L402 Producer**: Create Lightning paywalls and verify payment tokens
- **L402 Discovery**: Search l402.directory and 402index.io for paid APIs
## Prerequisites
- Node.js 18+
- A Blink wallet account ([dashboard.blink.sv](https://dashboard.blink.sv))
- A Blink API key
## Installation
### From Source
```bash
git clone https://github.com/yourusername/blink-mcp.git
cd blink-mcp
npm install
npm run build
```
### Getting an API Key
1. Log in to your Blink wallet at [dashboard.blink.sv](https://dashboard.blink.sv)
2. Go to **Settings** > **API Keys**
3. Click **Create API Key**
4. Select the permissions you need:
- **Read**: View balances, transactions, and account info
- **Receive**: Create invoices and addresses to receive payments
- **Write**: Send payments and modify account settings
5. Copy the generated API key
## Configuration
Set the following environment variables:
```bash
# Required: Your Blink API key
export BLINK_API_KEY=blink_xxxxxxxxxxxxx
# Optional: Network to use (default: mainnet)
export BLINK_NETWORK=mainnet # or 'staging' for testnet
```
## Usage with Claude Desktop
Add to your Claude Desktop configuration (`~/.config/claude/claude_desktop_config.json` on Linux/Mac or `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
```json
{
"mcpServers": {
"blink": {
"command": "node",
"args": ["/path/to/blink-mcp/dist/index.js"],
"env": {
"BLINK_API_KEY": "your_api_key_here"
}
}
}
}
```
Or if installed globally via npm:
```json
{
"mcpServers": {
"blink": {
"command": "blink-mcp",
"env": {
"BLINK_API_KEY": "your_api_key_here"
}
}
}
}
```
## Usage with Other MCP Clients
The server uses stdio transport. Run it with:
```bash
BLINK_API_KEY=your_key node dist/index.js
```
## Available Tools
### Wallet & Account (17 tools)
| Tool | Description |
| -------------------------- | ------------------------------------ |
| `get_account_info` | Get current user account information |
| `get_wallets` | List all wallets with balances |
| `get_wallet_balance` | Get balance of a specific wallet |
| `get_transactions` | Get transaction history (paginated) |
| `get_transaction_by_id` | Get specific transaction details |
| `get_account_limits` | View withdrawal and transfer limits |
| `set_default_wallet` | Set default wallet (BTC or USD) |
| `set_display_currency` | Set display currency preference |
| `get_realtime_price` | Get current Bitcoin price |
| `get_price_history` | Get historical price data |
| `convert_currency` | Convert between fiat and Bitcoin |
| `get_supported_currencies` | List supported currencies |
| `lookup_user_wallet` | Find wallet by Blink username |
| `check_username_available` | Check username availability |
| `set_username` | Set/update your username |
| `get_authorization_scopes` | View API key permissions |
| `get_network_info` | Get Lightning node info |
### Lightning Network (12 tools)
| Tool | Description |
| ---------------------------------- | -------------------------------- |
| `create_invoice` | Create BTC Lightning invoice |
| `create_invoice_usd` | Create USD-denominated invoice |
| `create_invoice_no_amount` | Create open (any amount) invoice |
| `cancel_invoice` | Cancel unpaid invoice |
| `get_invoice_status` | Check invoice status by hash |
| `get_invoice_status_by_request` | Check status by bolt11 |
| `pay_invoice` | Pay a Lightning invoice |
| `pay_invoice_with_amount` | Pay open invoice with amount |
| `pay_lightning_address` | Send to Lightning address |
| `pay_lnurl` | Pay via LNURL |
| `estimate_lightning_fee` | Estimate payment fee |
| `estimate_lightning_fee_no_amount` | Estimate fee for open invoice |
### On-Chain Bitcoin (7 tools)
| Tool | Description |
| ----------------------------- | ------------------------------ |
| `create_onchain_address` | Generate new receiving address |
| `get_current_onchain_address` | Get current address |
| `send_onchain` | Send BTC on-chain |
| `send_onchain_all` | Sweep entire balance |
| `send_onchain_usd` | Send from USD wallet on-chain |
| `estimate_onchain_fee` | Estimate BTC transaction fee |
| `estimate_onchain_fee_usd` | Estimate USD wallet fee |
### Intraledger (Blink-to-Blink) (3 tools)
| Tool | Description |
| -------------------- | ------------------------------------- |
| `send_to_wallet` | Send BTC to wallet ID (free, instant) |
| `send_to_wallet_usd` | Send USD to wallet ID |
| `send_to_username` | Send to Blink username |
### Webhooks & Subscriptions (9 tools)
| Tool | Description |
| ---------------------------------- | ------------------------------- |
| `list_webhooks` | List registered webhooks |
| `add_webhook` | Register webhook endpoint |
| `remove_webhook` | Remove webhook |
| `subscribe_invoice_status` | Subscribe to invoice updates |
| `subscribe_invoice_status_by_hash` | Subscribe by payment hash |
| `subscribe_account_updates` | Subscribe to all account events |
| `subscribe_price_updates` | Subscribe to price changes |
| `list_subscriptions` | List active subscriptions |
| `cancel_subscription` | Cancel a subscription |
| `cancel_all_subscriptions` | Cancel all subscriptions |
### L402 Protocol (6 tools)
| Tool | Description |
| ------------------------ | ------------------------------------------------------------------ |
| `l402_discover` | Probe a URL for L402 payment requirements (no payment) |
| `l402_pay` | Access an L402-protected URL, paying automatically via Blink |
| `l402_store` | Manage the L402 token cache (~/.blink/l402-tokens.json) |
| `l402_challenge_create` | Create an L402 payment challenge (invoice + signed macaroon) |
| `l402_payment_verify` | Verify an L402 payment token (preimage + HMAC signature + caveats) |
| `l402_search` | Search L402 service directories (l402.directory or 402index.io) |
## Example Conversations
### Check Balance
```
User: What's my Bitcoin balance?
Assistant: [Uses get_wallets tool]
Your BTC wallet has 50,000 sats and your USD wallet has $12.50.
```
### Create Invoice
```
User: Create an invoice for 10,000 sats
Assistant: [Uses create_invoice tool]
Here's your Lightning invoice for 10,000 sats:
lnbc100u1p...
```
### Send Payment
```
User: Send 1000 sats to user@blink.sv
Assistant: [Uses pay_lightning_address tool]
Payment of 1,000 sats sent successfully to user@blink.sv!
```
### Monitor Invoice
```
User: Let me know when invoice lnbc... is paid
Assistant: [Uses subscribe_invoice_status tool]
I'm now monitoring the invoice. I'll notify you when it's paid.
```
## Development
```bash
# Install dependencies
npm install
# Build TypeScript
npm run build
# Run in development mode
npm run dev
# Type checking
npm run typecheck
# Linting
npm run lint
```
## Architecture
```
src/
├── index.ts # MCP server entry point
├── client.ts # Blink GraphQL client
├── types.ts # TypeScript type definitions
├── graphql/
│ └── operations.ts # GraphQL queries, mutations, subscriptions
└── tools/
├── wallet.ts # Wallet and account tools
├── lightning.ts # Lightning Network tools
├── onchain.ts # On-chain Bitcoin tools
├── intraledger.ts # Blink-to-Blink transfer tools
├── webhooks.ts # Webhook and subscription tools
└── l402.ts # L402 consumer, producer, and discovery tools
```
## API Reference
This MCP server wraps the [Blink GraphQL API](https://dev.blink.sv/). For detailed API documentation, visit:
- [Blink Agent Playbook](https://dev.blink.sv/api/agent-playbook): Canonical AI agent API reference — order of operations, safety constraints, and verification checklist.
- [Blink Developer Docs](https://dev.blink.sv/)
- [Blink API Playground](https://api.blink.sv/)
- [llms.txt](https://dev.blink.sv/llms.txt): Machine-readable discovery metadata for AI agents.
## Security Considerations
- **API Key Security**: Never commit your API key to version control
- **Permission Scoping**: Use the minimum required permissions for your use case
- **Write Operations**: Be cautious with write permissions as they allow sending funds
- **Environment Variables**: Store API keys in environment variables, not in config files
### Spend Guard
Because this server holds a Blink API key and exposes tools that move funds, an
agent processing untrusted content (a web page, email, invoice memo, etc.) could
be steered into making a payment via indirect prompt injection. To mitigate
this, every money-moving tool passes through a central **spend guard** before it
executes, enforcing (in order): recipient allowlist → per-transaction cap →
rolling 24h budget → **human confirmation**.
The guard is **safe-by-default**: with no configuration, all spend tools require
explicit confirmation before running.
| Variable | Default | Effect |
| -------- | ------- | ------ |
| `BLINK_REQUIRE_CONFIRMATION` | `true` | Require confirmation before any spend |
| `BLINK_APPROVAL_MODE` | `fail-closed` | Fallback when the client can't do elicitation: `fail-closed` or `stderr-code` |
| `BLINK_MAX_PAYMENT_SATS` | _(none)_ | Per-transaction cap in sats (authoritative for all spends, incl. `l402_pay`) |
| `BLINK_DAILY_BUDGET_SATS` | _(none)_ | Rolling 24h spend cap in sats (durable across restarts) |
| `BLINK_RECIPIENT_ALLOWLIST` | _(none)_ | Allowed recipients (ln addr / username / btc addr / wallet id) |
| `BLINK_WEBHOOK_ALLOWLIST` | _(none)_ | Allowed webhook callback hostnames |
| `BLINK_L402_MAX_SATS` | `1000` | Mandatory default cap for `l402_pay` |
| `BLINK_L402_HOST_ALLOWLIST` | _(none)_ | **Required** for L402 network access; fail-closed when unset |
**Confirmation flow.** When the MCP client supports
[elicitation](https://modelcontextprotocol.io/), the guard prompts inline and
blocks until the user accepts — this is the preferred, injection-safe path.
For clients **without** elicitation support, a token returned through the tool
channel is *not* a human boundary (a prompt-injected loop could simply echo it
back), so there is no such token. Instead `BLINK_APPROVAL_MODE` controls the
fallback:
- **`fail-closed`** (default): the spend is refused.
- **`stderr-code`**: the server prints a one-time approval code to its **console
(stderr)** — which the model cannot read — and the human operator re-issues
the tool call with `approval_code="<code>"`. The code never enters model
context, so injection alone cannot obtain it.
**Amount enforcement.** `BLINK_MAX_PAYMENT_SATS` and `BLINK_DAILY_BUDGET_SATS`
are enforced for every spend tool. Fixed-amount Lightning invoices are decoded
from the bolt11 before payment so `pay_invoice` is subject to the same caps and
budget as amount-carrying tools. For `l402_pay`, whose amount is only known
after fetching the invoice, the caps are re-checked *after decoding* and before
payment. The 24h budget is debited only on a **successful** payment (failed
attempts never burn budget) and is persisted to a `0600` ledger at
`~/.blink/spend-ledger.json` so it survives restarts.
**Sweeps and undecodable amounts.** When a per-transaction cap or daily budget
is configured, `send_onchain_all` (full-balance sweep) and any `pay_invoice`
whose bolt11 amount cannot be decoded are **refused** — the amount cannot be
verified against the cap, so the guard fails closed rather than bypassing it.
With no caps configured, these still require confirmation.
**L402 hardening.** `l402_pay` enforces a mandatory spend cap
(`max_amount_sats` or `BLINK_L402_MAX_SATS`) plus the global caps above, and
refuses invoices whose amount cannot be decoded. Server-side L402 fetches
**require `BLINK_L402_HOST_ALLOWLIST`** (fail-closed when unset), are HTTPS-only,
reject private/loopback/link-local addresses, and re-validate every redirect
hop — mitigating DNS-rebinding SSRF without socket pinning. Cached L402 tokens
are stored `0600`, and `l402_store get` masks payment secrets unless called
with `reveal: true`.
**Webhooks.** `add_webhook` requires an HTTPS URL and, when
`BLINK_WEBHOOK_ALLOWLIST` is set, a listed hostname.
## Troubleshooting
### "BLINK_API_KEY environment variable is required"
Make sure you've set the `BLINK_API_KEY` environment variable with your API key.
### "GraphQL Error: Not authorized"
Your API key may not have the required permissions. Check your key's scopes in the Blink wallet settings.
### WebSocket connection issues
Real-time subscriptions require a stable connection. Check your network and firewall settings.
## License
MIT
## Contributing
Contributions are welcome! Please open an issue or submit a pull request.
## Links
- [Blink Wallet](https://blink.sv)
- [Blink Developer Docs](https://dev.blink.sv/)
- [Blink Agent Playbook](https://dev.blink.sv/api/agent-playbook)
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [MCP SDK](https://github.com/modelcontextprotocol/sdk)
TDQS
Scored across 55 tools
Tools are mostly distinct by resource and action, with clear descriptions for similar operations like invoice creation and payment. Some pairs (get_account_info vs get_wallets, send_to_wallet vs send_to_username) overlap slightly, but their descriptions specify exact use cases, minimizing misselection. Overall, an agent can reliably pick the correct tool.
The tool names consistently use snake_case with a verb_noun pattern (get_, create_, pay_, send_, estimate_, subscribe_, cancel_). Minor inconsistencies include list_webhooks vs get_wallets for retrieval, and check_username_available/lookup_user_wallet using non-get verbs. These are understandable but break the pattern slightly.
With 55 tools, the server has an extremely large surface area. While the domain (Lightning wallet, invoices, onchain, L402, subscriptions) is broad, 55 tools exceed the 'too many' threshold and can overwhelm agents. Many tools are variants (e.g., create_invoice, create_invoice_usd, create_invoice_no_amount), making the set feel bloated.
The server provides comprehensive coverage of the wallet domain: account management, invoice lifecycle, payment methods, on-chain operations, intraledger transfers, fee estimation, webhooks, real-time subscriptions, and L402 paywalled access. There are no obvious gaps or dead-end operations; all critical workflows are supported.