호출 방법
연결하면 에이전트에 보이는 것은 세 개의 도구입니다. 지역과 데이터셋은 수백 개의 도구가 아니라 execute_tool의 tool_id 인자입니다——지역을 추가해도 컨텍스트가 늘지 않습니다.
discover_tools원하는 데이터를 자연어로 설명하면 맞는 tool_id를 돌려줍니다.inspect_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 캡처
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
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)
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/가 돌려주는 것은 이 세 개뿐입니다. 지역이나 데이터셋마다 어느 것을 쓸지는 discover_tools가 판단하고, inspect_tool이 해당 도구의 완전한 JSON Schema와 과금을 알려줍니다.
인증
- Bearer 토큰 — 헤더
Authorization: Bearer sk-.... Twinkle Hub 발행 가상 키, 사용자당 1 개. /dashboard에서 받으세요. - OAuth 플로우 없음 — PKCE / 리프레시 토큰 불필요; 장기 bearer 하나.
- 레이트 제한 — 플랜별 롤링 방식 credits 한도로 관리되며, USD 예산이나 키당 RPM/TPM 이 아닙니다. 플랜별 수치는 요금 페이지를 참고하세요.
요금
무료 한도, 레이트 제한, 플랜별 차이는 요금 페이지에 정리되어 있습니다. 한도를 다 쓰면 gateway가 회복될 때까지 호출을 막고, 회복되면 자동으로 다시 열립니다. 따로 설정할 것은 없습니다.