curl (streamable-http transport)
Step 1: initialize and capture session id from the mcp-session-id response header
curl -i -X POST https://api.twinkleai.tw/mcp/ \ -H "Authorization: Bearer sk-..." \ -H "Accept: application/json, text/event-stream" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'
Step 2: tools/call
curl -X POST https://api.twinkleai.tw/mcp/ \ -H "Authorization: Bearer sk-..." \ -H "Accept: application/json, text/event-stream" \ -H "Content-Type: application/json" \ -H "mcp-session-id: <from-step-1>" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"tw_list_domains","arguments":{}}}'
Response uses SSE-style framing — find the last line starting with data: and parse the JSON.
Python (fastmcp)
import asyncio from fastmcp.client import Client from fastmcp.client.auth import BearerAuth async def main(): async with Client( "https://api.twinkleai.tw/mcp/", auth=BearerAuth("sk-..."), ) as client: tools = await client.list_tools() print([t.name for t in tools]) r = await client.call_tool( "tw_search_datasets", {"query": "AQI", "domain": "environment", "limit": 5}, ) # response 在 r.content[0].text — JSON string import json print(json.loads(r.content[0].text)) asyncio.run(main())
Tools return CallToolResult.content[0].text as a JSON string. License, citation and other metadata pass through in the _meta field.
Tools reference
| Tool | Arguments | Returns (brief) |
|---|---|---|
| tw_list_domains | — | [{key, name_zh, scope, typical_questions}] |
| tw_search_datasets | {query, domain?, limit?} | [{dataset_id, title, score, license}] |
| tw_get_dataset | {dataset_id} | {schema, columns, license, source_url} |
| tw_query_rows | {dataset_id, where?, limit?} | [row, ...] |
| tw_materialize_dataset | {dataset_id, format?} | 全表 CSV / JSON |
Full schemas via tools/list — auto-generated as JSON Schema.
Authentication
- Bearer token — header
Authorization: Bearer sk-.... A Twinkle-Hub-issued virtual key, one per user. Get yours from /dashboard. - No OAuth flow — no PKCE / refresh tokens needed; just a long-lived bearer.
- Rate limit — the Free tier is gated by a rolling credit allowance (50 per rolling 5 hours, refilling gradually, plus a 200-credit weekly cap), not a USD budget or per-key RPM/TPM.
Pricing
Coming soon
Core tools are currently free — 50 credits per rolling 5 hours, refilling gradually (plus a 200-credit weekly cap). On the Free tier, query_rows returns up to 10 rows per call. Advanced semantic search and full-document retrieval are reserved for the upcoming Pro tier; we'll announce Pro pricing before billing starts.
Free tier: 50 credits per rolling 5 hours, refilling gradually (plus a 200-credit weekly cap); query_rows returns up to 10 rows per call; advanced semantic search and full-document retrieval are Pro-only. Quota enforcement is live now (with a small async lag).