Twinkle HubTwinkle Hub

10 분 셋업

Twinkle Hub는 MCP endpoint입니다. 사용하는 도구를 고르고 순서대로 따라 하세요.

API 키 받기

로그인하면 여기에 key가 표시되고, 아래 설정에도 자동으로 채워집니다.

API 키 받기

호출 방법

연결하면 에이전트에 보이는 것은 세 개의 도구입니다. 지역과 데이터셋은 수백 개의 도구가 아니라 execute_tool의 tool_id 인자입니다——지역을 추가해도 컨텍스트가 늘지 않습니다.

  1. discover_tools원하는 데이터를 자연어로 설명하면 맞는 tool_id를 돌려줍니다.
  2. inspect_tool인자를 어떻게 넘길지 모를 때는 전체 정의와 과금을 먼저 봅니다.
  3. execute_tool실행합니다. 과금·권한·요청 제한은 기존과 같습니다.

바깥쪽은 항상 이 모양

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

바깥쪽 키는 tool_id와 arguments 둘뿐이고, 나머지는 모두 arguments 안에 넣습니다. 인자를 바깥쪽에 펼쳐 쓰는 것이 가장 흔한 실수입니다.

그 dataset_id는 어디서 오나요? 데이터 카탈로그의 각 지역 페이지에 실려 있습니다. 그쪽은 데이터의 정체를, 이쪽은 사용법을 담당합니다.

curl (streamable-http 트랜스포트)

단계 1: initialize 후 mcp-session-id 응답 헤더에서 session id 캡처

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"}}}'

단계 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}
        }}}'

응답은 SSE 스타일 프레이밍 — data:로 시작하는 마지막 줄을 찾아 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())

도구는 CallToolResult.content[0].text를 JSON 문자열로 반환. 라이선스, 인용, 기타 메타데이터는 _meta 필드로 투과.

도구 레퍼런스

도구인자반환 값 (간략)
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}

tools/list가 돌려주는 것은 이 세 개뿐입니다. 지역이나 데이터셋마다 어느 것을 쓸지는 discover_tools가 판단하고, inspect_tool이 해당 도구의 완전한 JSON Schema와 과금을 알려줍니다.

인증

  • Bearer 토큰 — 헤더 Authorization: Bearer sk-.... Twinkle Hub 발행 가상 키, 사용자당 1 개. /dashboard에서 받으세요.
  • OAuth 플로우 없음 — PKCE / 리프레시 토큰 불필요; 장기 bearer 하나.
  • 레이트 제한 — 플랜별 롤링 방식 credits 한도로 관리되며, USD 예산이나 키당 RPM/TPM 이 아닙니다. 플랜별 수치는 요금 페이지를 참고하세요.

요금

무료 한도, 레이트 제한, 플랜별 차이는 요금 페이지에 정리되어 있습니다. 한도를 다 쓰면 gateway가 회복될 때까지 호출을 막고, 회복되면 자동으로 다시 열립니다. 따로 설정할 것은 없습니다.