Server version: v4.21
Endpoint: https://toolweave.dev/mcp
Transport: Streamable HTTP (MCP spec 2024-11-05)
This document is the operational reference for LLM agents (Claude, GPT, Gemini, etc.) connecting to toolweave as an MCP client. Load it as system prompt or context when bootstrapping an agent.
For human users see USER_GUIDE.md.
A multi-tenant MCP gateway exposing 60+ tools across six categories: - AI generation (text, image, video, audio, music) - Web tools (Firecrawl scrape/search/crawl) - DevOps (GitHub, Railway, Vercel) - Financial data (Alpha Vantage, Finnhub, Twelve Data, SEC EDGAR) - Crypto exchange (Kraken: market data, account, trading) - Custom Connectors (v4.21): user-defined REST APIs discovered via AI
A single bearer token gives access to whatever providers the user's package enables. Per-call key resolution is driven by the user's package configuration on the server — agents don't see or manage provider API keys directly; they just call tools.
https://toolweave.dev/mcp
Streamable HTTP. Standard MCP 2024-11-05 protocol.
Bearer token in Authorization header:
Authorization: Bearer tw_<token>
Two ways to obtain tw_<token>:
/dashboard/tokens (preferred for headless)After authenticating, standard MCP discovery:
POST /mcp
{"jsonrpc":"2.0","id":1,"method":"tools/list"}
| Tool | Purpose |
|---|---|
list_providers |
Returns array of provider names with configured: bool. Call first. |
get_usage_stats |
Returns current-month tokens used and budget remaining. |
list_video_jobs |
Returns recent async video generation jobs (own user only). |
upload_media |
Upload an image/video by URL or base64; returns signed media_id. Max 50 MB. |
| Tool | Provider |
|---|---|
anthropic_chat |
Anthropic (opus-4.1, sonnet-4.6) |
openai_chat |
OpenAI |
gemini_text |
| Tool | Provider | Notes |
|---|---|---|
openai_image |
OpenAI | DALL-E 3 |
gemini_image |
Imagen-4 | |
fal_image |
fal.ai | Flux models |
All video tools follow: _start → _status → _wait.
| Tool | Provider |
|---|---|
openai_video_* |
OpenAI Sora-2 |
gemini_video_* |
Google Veo 3.1 (requires Vertex AI) |
fal_image_to_video_* |
fal.ai Kling/Seedance/Wan |
fal_lipsync_* |
fal.ai sync.so v2 |
Rate limit: 5 video generations per hour per process.
| Tool | Provider |
|---|---|
openai_tts / openai_transcribe |
OpenAI |
gemini_tts / gemini_music |
Google (Lyria-2 needs Vertex) |
suno_music_* |
Suno V5 |
| Tool | Notes |
|---|---|
firecrawl_scrape |
Single-URL scrape to markdown |
firecrawl_search |
Web search with optional inline scrape |
firecrawl_crawl_start/status |
Multi-page crawl with depth control |
| Tool | Notes |
|---|---|
github_get_repo, github_get_file, github_list_files |
Read-only |
github_commit_file |
Refuses commits to main/master/production/prod unless allow_main=True. |
github_create_branch, github_create_pr, github_list_prs, github_get_pr |
PR workflow |
github_list_commits, github_list_workflow_runs, github_get_workflow_logs |
History/CI |
Default workflow: for code changes, create a branch, commit there,
open a PR. Direct main commits are reserved for docs/non-code changes
and require explicit opt-in.
| Tool | Notes |
|---|---|
railway_list_projects |
Returns [] on personal accounts — use known project_id directly |
railway_get_project, railway_list_deployments, railway_get_deployment |
Read |
railway_get_deployment_logs, railway_get_service_logs |
Build/runtime logs |
railway_trigger_deploy, railway_restart_service |
Deploy management |
railway_get_variables, railway_set_variables |
Env vars |
railway_create_project, railway_create_service_from_repo |
Project bootstrap |
railway_generate_domain, railway_add_custom_domain, railway_check_domain_status |
Domains |
railway_create_volume |
Currently broken — use Railway UI |
railway_list_environments, railway_list_domains |
Read-only listings |
| Tool | Notes |
|---|---|
vercel_list_projects, vercel_get_project |
Project info |
vercel_list_deployments, vercel_get_deployment, vercel_get_deployment_logs |
Deploys |
vercel_get_env_vars (masked), vercel_set_env_vars |
Env vars |
vercel_list_domains, vercel_check_domain_status, vercel_add_domain |
Domains |
vercel_list_dns_records, vercel_create_dns_record, vercel_delete_dns_record |
DNS |
vercel_check_domain_availability |
Pre-purchase |
vercel_register_domain |
Costs real money. Requires confirm_price=True + max_price_usd>0. Rate-limited 3/24h |
vercel_create_project, vercel_link_git_repo |
Bootstrap |
vercel_trigger_deploy, vercel_promote_deployment |
Deploy |
| Tool | Provider |
|---|---|
av_quote, av_time_series_daily, av_time_series_intraday, av_symbol_search, av_indicator_rsi |
Alpha Vantage |
fh_quote, fh_company_profile, fh_basic_financials, fh_company_news, fh_earnings_calendar, fh_recommendation_trends |
Finnhub |
td_quote, td_time_series, td_exchange_rate, td_market_state, td_statistics |
Twelve Data |
sec_ticker_lookup, sec_company_submissions, sec_company_facts, sec_company_concept, sec_financial_summary, sec_recent_filings |
SEC EDGAR |
Public (no auth):
- kraken_system_status — check before trading
- kraken_ticker, kraken_ohlc, kraken_depth, kraken_recent_trades, kraken_spread
- kraken_assets, kraken_asset_pairs — CRITICAL: check ordermin, tick_size before orders
Private read (auth):
- kraken_balance, kraken_open_orders, kraken_closed_orders, kraken_query_orders
- kraken_trades_history, kraken_trade_volume
Trading (real money):
- kraken_add_order — requires confirm=True. Use validate_only=True for dry-run
- kraken_cancel_order, kraken_cancel_all_orders (confirm=True), kraken_edit_order
Trading rate limit: 30 mutations/hour per user.
Auth: Kraken uses two providers (kraken_key + kraken_secret). Secret is
base64-encoded. HMAC-SHA512 signing happens server-side.
User-defined REST API integrations. Each connector has a unique
connector_id and exposes its own set of endpoints under three
generic MCP tools:
| Tool | Purpose |
|---|---|
connector_list |
Returns list of user's active connectors with their endpoint summaries. Always call first to see what's available. |
connector_describe |
Returns full schema (base_url, auth, endpoints, params) for one connector by connector_id. |
connector_call |
Invokes a specific endpoint on a connector. Args: connector_id, endpoint_name, params (dict). Returns response body. |
Workflow:
1. connector_list — discover what connectors the user created
2. connector_describe(connector_id="nbu") — get schema
3. connector_call(connector_id="nbu", endpoint_name="get_exchange_rates",
params={"date": "20260603"}) — execute
Security limits:
- SSRF protection blocks RFC 1918, localhost, 169.254/16 destinations
- Max 30 endpoints per connector schema
- Max 15 params per endpoint
- Max 200KB response body (truncated if larger)
- Response always returned with truncated: bool flag
Discovery (admin/user creates connectors via dashboard, not MCP):
- User initiates via /dashboard/connectors/new
- Two-phase opus pipeline finds API structure from docs
- Lifetime discovery quota: 10 per user (admin can raise)
- Agents do not initiate connector creation — only use existing ones
| Error | Meaning | Agent response |
|---|---|---|
Provider 'X' is not included in your package 'Y' |
Package doesn't grant access. | Tell user to ask admin to extend package. Do not retry. |
Provider 'X' is disabled in your package 'Y' |
In package but disabled. | Tell user to ask admin to enable. Do not retry. |
No personal 'X' key set |
User-specific key required, none configured. | Tell user to visit /dashboard/keys. Do not retry. |
Admin 'X' key not found |
Package mode = admin_key but env var missing. |
Tell user to contact admin@toolweave.dev. Do not retry. |
Your monthly token budget is exhausted |
Hit user's monthly_token_budget. |
Tell user to ask admin to raise budget. Do not retry. |
Rate limit exceeded for 'X': max N per Ms |
Server-side rate limit. | Wait indicated cooldown, retry once. |
kraken_add_order requires confirm=True |
Safety guard. | Re-issue with confirm=True only if user explicitly asked to trade. |
Connector 'X' not found |
User has no such custom connector. | Call connector_list to see what's available. Suggest user create it via /dashboard/connectors/new. |
Connector 'X' is not active |
Connector exists but in draft/disabled state. | Tell user to activate it in dashboard. |
Connector endpoint 'Y' does not exist |
Wrong endpoint_name. | Call connector_describe to get valid endpoint names. |
Custom connector key missing |
Connector requires auth but no key set. | Tell user to add API key in /dashboard/connectors/{id}. |
Discovery limit reached |
User exhausted 10 lifetime discoveries. | Tell user to contact admin. |
EAPI:Invalid signature (Kraken) |
Wrong kraken_secret. | Tell user to re-paste kraken_secret. Do not retry. |
EAPI:Invalid nonce (Kraken) |
Clock skew or key conflict. | Wait 60s, retry once. |
EOrder:Insufficient funds (Kraken) |
Balance too low. | Surface verbatim. Suggest kraken_balance. |
invalid_token (HTTP 401) |
Bearer token revoked/expired. | Re-authenticate via OAuth or new manual token. |
| Tool-specific provider errors | Pass-through. | Surface verbatim, suggest fix if obvious. |
_start calls with cost-exceeded — params need change.kraken_add_order safety-guard failures.When a user request maps to multiple possible tools, prefer:
fh_company_news > openai_chat for "what news about AAPL". kraken_ticker > openai_chat for "current BTC price". connector_call > generic search when user has a connector for the relevant API.Image and video generation can cost real money on the user's account:
Kraken trading operations spend real money on the user's exchange account. Before placing orders:
kraken_system_status — order rejected if not online.kraken_asset_pairs for ordermin and tick_size.kraken_balance to confirm available funds.validate_only=True to dry-run.confirm=True.When user requests batch operations, confirm before starting.
Image generation:
1. list_providers → confirm image provider configured
2. openai_image / gemini_image / fal_image → returns URL or media_id
Video generation (async):
1. list_providers
2. openai_video_start (returns job_id)
3. openai_video_wait (blocks until done or timeout)
4. Result includes media_id with signed URL
Code change in repo:
1. github_get_file to read current content
2. github_create_branch (e.g. "feat/foo")
3. github_commit_file on the new branch
4. github_create_pr from branch to main
Docs/README change:
1. github_commit_file with allow_main=True (single commit, no PR)
Crypto trade (Kraken):
1. kraken_system_status → ensure online
2. kraken_asset_pairs(pair="XBTUSD") → check ordermin, tick_size
3. kraken_balance → confirm available funds
4. kraken_ticker(pair="XBTUSD") → current price reference
5. CONFIRM with user: side, volume, price, total cost
6. kraken_add_order(..., validate_only=True, confirm=True) → dry-run
7. If validation OK, kraken_add_order(..., confirm=True) → actual order
Custom Connector use:
1. connector_list → see what connectors user has
2. connector_describe(connector_id) → get schema (endpoints, params)
3. connector_call(connector_id, endpoint_name, params={...}) → execute
4. If 401/403 → tell user to check API key in connector detail page
5. If 404 endpoint → check connector_describe again, suggest matching name
Infrastructure deploy:
1. github_commit_file or github_create_pr (code change)
2. (Railway auto-deploys on push to main)
3. railway_get_deployment_logs to confirm SUCCESS
4. railway_get_service_logs if issues
railway_list_projects returns [] on personal accounts — use known project_id directly.railway_create_volume is currently broken — fall back to Railway UI.vercel_create_dns_record only works for domains using Vercel nameservers.gemini_video_* and gemini_music require VERTEX_ENABLED=1. Fallback to fal.ai or Sora.kraken_recent_trades since is in nanoseconds, but kraken_ohlc since is in seconds.XXBT=Bitcoin, XETH=Ethereum, ZUSD=USD, ZEUR=EUR.truncated flag in response.auth.type can be "none" for public APIs — no key required.The server knows which user made the call (via Bearer token → user_id
ContextVar). Tools never need a user_id parameter — it's implicit.
Personal data returned (usage stats, video jobs, Kraken balance,
connectors, etc.) is scoped to the calling user only.
| URL | Method | Purpose |
|---|---|---|
/ |
GET | Landing page (HTML, UA/EN) |
/info |
GET | JSON with version + capabilities |
/health |
GET | JSON {"status":"ok"} |
/mcp |
POST | MCP endpoint (requires Bearer auth) |
/docs/terms |
GET | Terms of Service |
/docs/privacy |
GET | Privacy Policy |
/docs/ai-guide.md |
GET | This document (raw markdown) |
| URL | Method | Purpose |
|---|---|---|
/.well-known/oauth-authorization-server |
GET | Metadata |
/.well-known/oauth-protected-resource |
GET | Resource metadata |
/register |
POST | Dynamic client registration |
/authorize |
GET | Authorization endpoint |
/token |
POST | Token exchange |
| URL | Method | Purpose |
|---|---|---|
/login |
GET/POST | Magic link login |
/auth/magic/{token} |
GET | Magic link consumer |
/dashboard |
GET | User overview |
/dashboard/keys |
GET/POST | Per-user provider keys (3-zone with test) |
/dashboard/tokens |
GET/POST | MCP token CRUD |
/dashboard/analytics |
GET | Usage analytics dashboard |
/dashboard/connectors |
GET | Custom Connectors list |
/dashboard/connectors/new |
GET/POST | Create new connector |
/me |
GET | JSON user info |
| Limit | Value |
|---|---|
| Max upload size | 50 MB |
| Video generation | 5/hour |
| Project creation | 10/hour |
| Mutations (env vars, configs) | 30/hour |
| Code commits | 30/hour |
| DNS records | 60/hour |
| Domain registration | 3/24h |
| Kraken trading | 30/hour per user |
| Custom Connector discovery | 10 lifetime per user (admin can raise) |
| Custom Connector call | Subject to user's token budget |
| OAuth authorization codes | Single-use, 10-min TTL |
| Magic link tokens | Single-use, 24-hour TTL |
| Signed media URLs | 1-hour TTL (configurable) |
| Per-user monthly token budget | Admin-configured per package |
Server-side enforcement; agent should respect by not spamming.
Since v4.19, toolweave uses tokens as unified billing currency. Each action costs a fixed number of tokens:
User has a monthly token budget. When exhausted, calls return
"Your monthly token budget is exhausted". Agent should NOT retry —
direct user to ask admin for raise.
Server version exposed at https://toolweave.dev/info as {"version": "..."}.
Compatibility:
- v4.x family is stable. Tool signatures don't break across minor versions.
- New tools added in minor versions. Agents should call tools/list after connection rather than hardcoding tool names.
- Mode-based key resolution introduced in v4.17 — older clients work but won't see package-aware error messages.
- Kraken integration added in v4.18.
- Token-based billing replaced USD-based in v4.19.
- Custom Connectors added in v4.21.
1. Get tw_<token> from user (manual token or OAuth flow).
2. POST /mcp tools/list — discover what's actually available.
3. Call list_providers — confirm which providers user has configured.
4. Call connector_list — see what custom connectors user created.
5. Plan workflow with cheapest viable tools, preferring Custom Connectors
when user explicitly built one for the target API.
6. Confirm cost estimate with user for batch / video / trading operations.
7. Execute. Surface errors verbatim; use error categories above to
decide retry vs user action.
8. If user requests something requiring a disabled provider, tell
them to email admin@toolweave.dev — don't try to work around it.
This document is for v4.21 of toolweave. Always check
https://toolweave.dev/info for current server version. For human
users: USER_GUIDE.md. Legal: TERMS.md, PRIVACY.md.