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

How calls work

Once connected, your agent sees three tools. Regions and datasets aren't hundreds of tools — they're the tool_id argument to execute_tool, so adding a region never grows your context.

  1. discover_toolsDescribe the data you want in plain language; it returns the tool_ids that fit.
  2. inspect_toolWhen you're unsure how to pass parameters, read the full definition and its pricing first.
  3. execute_toolRun it. Billing, permissions and rate limits behave exactly as before.

The outer call always has this shape

execute_tool
execute_tool({
  tool_id: "tw_query_dataset",
  arguments: {
    dataset_id: "pcc-tender",
    filters: [{ field: "agency", operator: "contains", value: "交通部" }],
    limit: 10
  }
})

The outer call takes exactly two keys, tool_id and arguments. Everything else goes inside arguments — flattening parameters into the outer call is the most common mistake.

Where does that dataset_id come from? Every region page in the data catalogue lists them. The split is simple: that side tells you what the data is, this side tells you how to call it.

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":"execute_tool",
        "arguments":{
          "tool_id":"tw_search_datasets",
          "arguments":{"query":"空氣品質","limit":5}
        }}}'

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

        # 外層一定是 execute_tool,tool_id 與 arguments 兩個鍵
        r = await client.call_tool(
            "execute_tool",
            {
                "tool_id": "tw_query_dataset",
                "arguments": {
                    "dataset_id": "pcc-tender",
                    "filters": [
                        {"field": "agency", "operator": "contains", "value": "交通部"}
                    ],
                    "limit": 10,
                },
            },
        )
        # 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)
discover_tools{query, country?, cursor?}[{tool_id, name, description, access}]
inspect_tool{tool_id}{input_schema, how_to_call, execution_policy}
execute_tool{tool_id, arguments}{tool_id, result, _meta.opendata.license}

These three are everything tools/list returns. Which one fits a given region or dataset is discover_tools' job; inspect_tool hands you that tool's full JSON Schema and its pricing.

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.