Twinkle HubTwinkle Hub

10-minute setup

Twinkle Hub is an MCP endpoint. Pick the tool you use and follow the steps.

Get an API key

Sign in and your key appears here, already filled into every snippet below.

Get an API key

curl (streamable-http transport)

Step 1: initialize and capture session id from the mcp-session-id response header

bash
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

bash
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)

python
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

ToolArgumentsReturns (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 — gated by a rolling credit allowance per plan, not a USD budget or per-key RPM/TPM. The numbers for each plan are on the pricing page.

Pricing

Free allowance, rate limits and how the plans differ are all on the pricing page. When the allowance runs out, the gateway rejects calls until it refills, then resumes on its own — nothing to reset.