关于 composio
composio 是供 Starchild Agent 使用的外部应用集成技能,通过网关搜索、查询并执行应用工具,也可管理连接和 Browserbase 会话。
主要功能
- 01搜索外部应用工具
- 02查询完整工具参数
- 03执行应用操作
- 04管理 OAuth 连接
- 05管理 Browserbase 会话
适用场景
- 01通过 Gmail 发送邮件
- 02查询 Google Calendar 事件
- 03管理外部应用连接
- 04创建并清理 Browserbase 会话
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ starchild-ai-agent/ official-skills --skill composio安装后在 Claude Code 中输入/composio确认已加载。
详细介绍
Composio — 通过网关集成外部应用
Composio 让用户能够将 1000 多个外部应用(Gmail、Slack、GitHub、Google Calendar、Notion 等)连接到他们的 Starchild Agent。所有操作都通过 Composio Gateway(composio-gateway.fly.dev)进行,由它处理身份验证和 API 密钥管理。
架构
Agent (Fly 6PN network)
↓ HTTP (auto-authenticated by IPv6)
Composio Gateway (composio-gateway.fly.dev)
↓ Composio SDK
Composio Cloud → Target API (Gmail, Slack, etc.)
- 你永远不会接触 COMPOSIO_API_KEY — 网关持有该密钥
- 你永远不会直接调用 Composio SDK — 使用网关 HTTP API
- 身份验证是自动的 — 你的 Fly 6PN IPv6 地址会通过计费数据库解析为 user_id
- 无需环境变量 — 任何 Agent 容器始终都能访问网关
网关基准 URL
GATEWAY = "http://composio-gateway.flycast"
所有请求都通过 Fly 内部网络(flycast)使用 纯 HTTP。无需 JWT。
重要 — 绝不要通过 sc-proxy 路由网关:
- 使用 curl(如下方示例所示),或使用不经过代理的普通
requests/http.client。 - 对此主机不要使用
proxied_get/proxied_post(即使 PROTOCOL 对外部 API 的说明是“始终经由代理”——flycast 是文档中注明的例外;core.http_client也会自动绕过*.flycast)。 - 不要设置指向网关的
HTTP_PROXY/HTTPS_PROXY,也不要使用curl -x。 - 代理会改写调用者身份,导致网关看到错误的用户,从而使连接/执行失败或访问其他用户的 locker。
API 参考
1. 搜索工具(精简)
查找适合某项任务的工具 slug。返回精简的工具信息——仅包含 slug、描述和参数名称。足以用于选择正确的工具。
curl -s -X POST $GATEWAY/internal/search \
-H "Content-Type: application/json" \
-d '{"query": "send email via gmail"}'
响应(精简):
{
"results": [{"primary_tool_slugs": ["GMAIL_SEND_EMAIL"], "use_case": "send email", ...}],
"tool_schemas": {
"GMAIL_SEND_EMAIL": {
"tool_slug": "GMAIL_SEND_EMAIL",
"toolkit": "gmail",
"description": "Send an email...",
"parameters": ["to", "subject", "body", "cc", "bcc"],
"required": ["to", "subject", "body"]
}
},
"toolkit_connection_statuses": [...]
}
2. 获取工具架构(完整)
获取特定工具的完整参数定义——类型、描述、枚举值和默认值。需要精确的参数格式时,在搜索后使用此接口。
curl -s -X POST $GATEWAY/internal/tool_schema \
-H "Content-Type: application/json" \
-d '{"tool": "GOOGLECALENDAR_EVENTS_LIST"}'
响应:
{
"data": {
"tool_slug": "GOOGLECALENDAR_EVENTS_LIST",
"description": "Returns events on the specified calendar.",
"input_parameters": {
"properties": {
"timeMin": {"type": "string", "description": "RFC3339 timestamp..."},
"timeMax": {"type": "string", "description": "RFC3339 timestamp..."},
"calendarId": {"type": "string", "default": "primary"}
},
"required": ["calendarId"]
}
},
"error": null
}
3. 执行工具
执行 Composio 工具。键名是 arguments,不是 params。
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GMAIL_SEND_EMAIL", "arguments": {"to": "[email protected]", "subject": "Hi", "body": "Hello!"}}'
成功时:
{"data": {"messages": [...]}, "error": null}
失败时——包含 tool_schema,便于你自行纠正:
{
"data": null,
"error": "Missing required parameter: calendarId",
"tool_schema": {
"tool_slug": "GOOGLECALENDAR_EVENTS_LIST",
"description": "...",
"input_parameters": {"properties": {...}, "required": [...]}
}
}
4. 列出用户的连接(并确认 OAuth 已完成)
# Optional toolkit filter: oauth_completed_active only turns true
# when that toolkit status is ACTIVE.
curl -s "$GATEWAY/internal/connections?toolkit=gmail"
响应包含:
connections:当前去重后的连接列表oauth_completed_active:布尔值,仅当观察到 OAuth 完成状态为ACTIVE时才为 true
只有在观察到 ACTIVE 后才会触发缓存失效,并且目标是用户的实例(fly-force-instance-id=<user_mapping 中的用户 container_id>),而不是 composio-gateway 自己的实例。
5. 发起新连接
curl -s -X POST $GATEWAY/api/connect \
-H "Content-Type: application/json" \
-d '{"toolkit": "gmail"}'
返回 connect_url,供用户完成 OAuth。
零摩擦连接(执行操作时必须遵循)
仅当用户希望在某个外部应用中执行操作(发送/读取邮件、创建日历事件、创建 GitHub issue、发布内容等),且该应用尚未连接时,才触发连接。
不要在纯问答/解释场景中触发(例如“Gmail 是什么?”、“Calendar 如何运作?”)。
- 不要描述连接检查、空列表或 OAuth 流程,也不要询问“要我帮你连接吗?”。
- 在 Web(活跃 SSE 会话)中:调用内置工具,连接唯一的主要工具包:
可选:frontend_action(action_type="composio_connect", toolkit="gmail")display_name="Gmail"、title=...、description=...。 使用正确的小写工具包 slug。不要粘贴connect_urlMarkdown 链接 — 前端会根据 action_request 显示连接卡片。 - 对用户可见的回复:用一行简短文字说明连接后你会做什么(不要使用 emoji 装饰,也不要提供授权 URL)。
- 停止并等待用户完成 OAuth 并点击 Done,然后继续原任务。
- 绝不要让用户先去 Connections 页面查找。
- 备用方案(没有 SSE / 非 Web 渠道,或
frontend_action失败):
然后以纯文本提供原始curl -s -X POST $GATEWAY/api/connect \ -H "Content-Type: application/json" \ -d '{"toolkit": "gmail"}'connect_url(仍无需匹配 Markdown 卡片)。 如果这也失败,用一行简短文字说明,并停止操作——不要编造其他设置流程。
6. 断开连接
curl -s -X DELETE $GATEWAY/api/connections/{connection_id}
Instagram 发布(重要的 slug 映射)
Composio 搜索可能会返回旧版 Instagram slug,这些 slug 在此环境中无法执行。 发布到 Instagram 时,请使用以下可用的 slug:
- 创建草稿容器:
INSTAGRAM_CREATE_MEDIA_CONTAINER- 必填:
ig_user_id - 照片的常用参数:
{"ig_user_id":"...","image_url":"https://...","content_type":"photo","caption":"..."}
- 发布草稿:
INSTAGRAM_CREATE_POST- 必填:
ig_user_id、creation_id
两步流程:
- 执行
INSTAGRAM_CREATE_MEDIA_CONTAINER→ 将data.data.id读取为creation_id - 使用该
creation_id执行INSTAGRAM_CREATE_POST
提示:如果 /internal/search 建议使用 INSTAGRAM_POST_IG_USER_MEDIA 或 INSTAGRAM_POST_IG_USER_MEDIA_PUBLISH,但执行时返回 "Tool ... not found",请改用上述两个 slug。
Browserbase — 混合工作流(会话管理 + Playwright CDP)
Composio 的 Browserbase 工具仅管理会话生命周期(打开/关闭/列出),不会控制网页。
要实际操作浏览器(导航、点击、填写表单、抓取数据),请使用 Playwright connect_over_cdp 连接到会话的 WebSocket URL。
第 1 步:通过 Composio 创建 Browserbase 会话
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "BROWSERBASE_TOOL_SESSIONS_CREATE", "arguments": {"projectId": "YOUR_PROJECT_ID"}}'
响应包含 id(session_id)、status 和时间戳。
第 2 步:构建 CDP WebSocket URL
import os
session_id = "<session_id from step 1>"
api_key = os.environ.get("BROWSERBASE_API_KEY") # stored in workspace/.env
cdp_url = f"wss://connect.browserbase.com?apiKey={api_key}&sessionId={session_id}"
第 3 步:使用 Playwright 控制浏览器
from playwright.async_api import async_playwright
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(cdp_url)
page = await browser.new_page()
await page.goto("https://example.com")
# Click, fill, screenshot — full Playwright API
await page.click("button.submit")
await page.fill("input[name='email']", "[email protected]")
await page.screenshot(path="result.png")
content = await page.content()
第 4 步:删除会话(重要 — 停止计费)
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "BROWSERBASE_TOOL_SESSIONS_DELETE", "arguments": {"id": "YOUR_SESSION_ID"}}'
关键概念
| 方面 | 详情 |
|---|---|
| Composio 的作用 | 仅管理会话生命周期 — 创建、列出、删除会话 |
| Playwright 的作用 | 控制页面 — 导航、点击、填写、抓取、截屏 |
| 内存开销 | 本地约 30-50MB(仅 Playwright 客户端);Chromium 在 Browserbase 服务器上运行 |
| 反检测 | Browserbase 在服务器端处理 — 指纹屏蔽、验证码求解、绕过 Cloudflare。Playwright 客户端不做任何特殊处理。 |
| 计费 | 按分钟计费(向上取整)。完成后务必删除会话。 |
完整示例脚本(创建 → 控制 → 删除)
#!/usr/bin/env python3
"""Browserbase: create session → control with Playwright → clean up."""
import asyncio, os, requests
from playwright.async_api import async_playwright
GATEWAY = "http://composio-gateway.flycast"
PROJECT_ID = os.environ.get("BROWSERBASE_PROJECT_ID")
async def main():
# 1. Create session via Composio
resp = requests.post(f"{GATEWAY}/internal/execute", json={
"tool": "BROWSERBASE_TOOL_SESSIONS_CREATE",
"arguments": {"projectId": PROJECT_ID}
}).json()
session_id = resp["data"]["id"]
print(f"Session created: {session_id}")
try:
# 2. Connect via CDP
api_key = os.environ["BROWSERBASE_API_KEY"]
cdp_url = f"wss://connect.browserbase.com?apiKey={api_key}&sessionId={session_id}"
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(cdp_url)
page = await browser.new_page()
await page.goto("https://example.com")
title = await page.title()
print(f"Page title: {title}")
await browser.close()
finally:
# 3. Always delete session to stop billing
requests.post(f"{GATEWAY}/internal/execute", json={
"tool": "BROWSERBASE_TOOL_SESSIONS_DELETE",
"arguments": {"id": session_id}
})
print("Session deleted")
asyncio.run(main())
通过 Composio 提供的 Browserbase 工具
| 工具 Slug | 用途 | 关键参数 |
|---|---|---|
BROWSERBASE_TOOL_SESSIONS_CREATE | 创建浏览器会话 | projectId |
BROWSERBASE_TOOL_SESSIONS_DELETE | 删除会话 | id |
BROWSERBASE_TOOL_SESSIONS_GET | 获取会话信息 | id |
BROWSERBASE_TOOL_SESSIONS_LIST | 列出所有会话 | (无) |
BROWSERBASE_TOOL_SESSIONS_GET_DEBUG_INFO | 获取调试信息 | id |
BROWSERBASE_TOOL_SESSIONS_STOP | 停止会话 | id |
BROWSERBASE_TOOL_CONTEXTS_CREATE | 创建持久化上下文 | projectId |
BROWSERBASE_TOOL_CONTEXTS_DELETE | 删除上下文 | id |
BROWSERBASE_TOOL_CONTEXTS_GET | 获取上下文信息 | id |
BROWSERBASE_TOOL_CONTEXTS_LIST | 列出上下文 | (无) |
BROWSERBASE_TOOL_CONTEXTS_UPDATE | 更新上下文标签 | id、labels |
BROWSERBASE_TOOL_UPLOADS_CREATE | 将文件上传到会话 | projectId、文件数据 |
BROWSERBASE_TOOL_UPLOADS_GET | 获取上传信息 | id |
BROWSERBASE_TOOL_UPLOADS_LIST | 列出上传内容 | (无) |
BROWSERBASE_TOOL_UPLOADS_DELETE | 删除上传内容 | id |
BROWSERBASE_TOOL_DOWNLOADS_LIST | 列出下载内容 | sessionId |
BROWSERBASE_TOOL_DOWNLOADS_GET | 获取下载内容 | downloadId |
BROWSERBASE_TOOL_DOWNLOADS_GET_STREAM | 流式传输下载内容 | downloadId |
BROWSERBASE_TOOL_KB_GET_KNOWLEDGE | 获取知识库文章 | id |
Browserbase / Browser 工具故障排查
如果 Browserbase 已连接,但执行失败,请检查连接工具包与工具 slug之间的名称是否不匹配:
- 连接可能显示为工具包
browserbase_tool - 搜索可能返回类似
BROWSER_TOOL_CREATE_TASK的工具 slug - 执行时仍可能拒绝该 slug(
Tool ... not found),并且只识别工具包browserbase下的旧版 slug
快速诊断:
# 1) Health + active connections
curl -s $GATEWAY/health
curl -s $GATEWAY/internal/connections
# 2) Search browser tool slugs
curl -s -X POST $GATEWAY/internal/search \
-H "Content-Type: application/json" \
-d '{"query":"browserbase create task"}'
# 3) Try execute and inspect exact error
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool":"BROWSER_TOOL_CREATE_TASK","arguments":{"task":"open https://example.com"}}'
如果错误提示 No active connection found for toolkit 'browserbase',网关应在服务端规范化 Browserbase 别名(browser/browserbase/browserbase_tool),并规范化执行 slug 变体(BROWSERBASE_TOOL_* ↔ BROWSER_TOOL_*),以便新旧客户端都能使用处于活动状态的 browserbase_tool 连接。
最佳工作流(尽量减少工具调用)
已知工具 → 直接执行(1 次调用)
如果你已通过以往使用或下方的常用工具表知道工具 slug 和参数,请完全跳过搜索:
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GOOGLECALENDAR_EVENTS_LIST", "arguments": {"calendarId": "primary", "timeMin": "2026-04-02T00:00:00+08:00", "timeMax": "2026-04-09T00:00:00+08:00", "singleEvents": true, "timeZone": "Asia/Hong_Kong"}}'
未知工具 → 搜索 + 模式 + 执行(2–3 次调用)
- 搜索(精简)→ 选择合适的工具 slug
- 获取模式(参数详情不明确时)→ 确认准确的参数格式
- 执行 → 使用正确的参数
如果执行失败,错误响应会包含完整模式,因此你可以立即重试,无需额外调用模式查询。
将其封装成脚本以便重复使用
对于重复查询,可编写一次性 Python 脚本:
#!/usr/bin/env python3
import sys, json, requests
from datetime import datetime, timedelta, timezone
GATEWAY = "http://composio-gateway.flycast"
days = int(sys.argv[1]) if len(sys.argv) > 1 else 7
tz_name = sys.argv[2] if len(sys.argv) > 2 else "UTC"
# ... build timeMin/timeMax ...
resp = requests.post(f"{GATEWAY}/internal/execute", json={
"tool": "GOOGLECALENDAR_EVENTS_LIST",
"arguments": {"calendarId": "primary", "timeMin": t_min, "timeMax": t_max,
"singleEvents": True, "timeZone": tz_name}
}).json()
# ... format and print ...
之后的调用只需:bash("python3 scripts/calendar_events.py 7 Asia/Hong_Kong") — 1 次工具调用。
常用工具速查(这些工具可跳过搜索)
📧 Gmail
| 工具 Slug | 用途 | 关键参数 |
|---|---|---|
GMAIL_SEND_EMAIL | 发送邮件 | to、subject、body、cc、bcc |
GMAIL_FETCH_EMAILS | 获取邮件 | max_results(int)、label_ids(list)、q(Gmail 搜索语法) |
GMAIL_CREATE_EMAIL_DRAFT | 创建草稿 | to、subject、body |
Gmail 使用示例:
# Send email
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GMAIL_SEND_EMAIL", "arguments": {"to": "[email protected]", "subject": "Hello", "body": "Hi there!"}}'
# Fetch last 5 emails
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GMAIL_FETCH_EMAILS", "arguments": {"max_results": 5}}'
# Search specific emails (using Gmail search syntax)
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GMAIL_FETCH_EMAILS", "arguments": {"max_results": 10, "q": "from:github.com after:2026/03/01"}}'
Gmail 响应解析: 邮件数据位于 data.data.messages[],每封邮件都包含 id、snippet、payload.headers[](From/Subject/Date 位于 headers 中,可按名称查找)。
| 工具 Slug | 用途 | 关键参数 |
|---|---|---|
TWITTER_CREATION_OF_A_POST | 创建帖子 | text(必填)、media_media_ids、reply_in_reply_to_tweet_id |
TWITTER_POST_DELETE_BY_POST_ID | 删除帖子 | id |
TWITTER_POST_LOOKUP_BY_POST_ID | 获取单条推文 | id、tweet_fields |
TWITTER_RECENT_SEARCH | 搜索最近 7 天的内容 | query、max_results(最小值为 10) |
TWITTER_USER_LOOKUP_ME | 获取自己的个人资料 | (无参数) |
TWITTER_USER_LOOKUP_BY_USERNAME | 获取用户个人资料 | username |
Twitter 使用示例:
# Post tweet
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "TWITTER_CREATION_OF_A_POST", "arguments": {"text": "Hello from Composio!"}}'
# Delete tweet
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "TWITTER_POST_DELETE_BY_POST_ID", "arguments": {"id": "2039756730192601584"}}'
Twitter 响应结构: 创建帖子时返回 data.data.data(3 层嵌套),包含 id、text、edit_history_tweet_ids。
Twitter — 带图片发帖(FileUploadable 流程)
关键限制: 网关的 /internal/execute 是 Composio v2 actions/{slug}/execute 的薄封装——它不支持固定 version 或合成 FileUploadable。Twitter 媒体上传工具(TWITTER_UPLOAD_MEDIA、TWITTER_UPLOAD_LARGE_MEDIA)两者都需要,因此必须直接通过 composio_client Python SDK 调用,不能通过网关调用。
网关有意保持通用——像这样的工具专属流程应保留在此技能中。
3 步流程(已验证可用):
import hashlib, httpx, json
from pathlib import Path
from composio_client import Composio
# COMPOSIO_API_KEY: read from /data/workspace/composio-gateway/.env
# (gateway owns the key; for skill scripts, source it the same way)
client = Composio(api_key=COMPOSIO_API_KEY)
USER_ID = f"starchild-{user_id}" # NOTE: hyphen, not underscore
img = Path("output/images/foo.jpg")
# 1. Get presigned S3 upload URL
md5 = hashlib.md5(img.read_bytes()).hexdigest()
presigned = client.files.create_presigned_url(
filename=img.name, md5=md5, mimetype="image/jpeg",
tool_slug="TWITTER_UPLOAD_MEDIA", toolkit_slug="twitter",
)
# presigned.type == "new" → file is new, must PUT
# presigned.type == "existing" → cached, skip PUT
if presigned.type == "new":
httpx.put(presigned.new_presigned_url, content=img.read_bytes(),
headers={"Content-Type": "image/jpeg"}, timeout=60).raise_for_status()
# 2. Execute upload tool — MUST pass version="20260501_00" (or current latest)
# media is a FileUploadable dict, NOT base64
upload_resp = client.tools.execute(
tool_slug="TWITTER_UPLOAD_MEDIA",
user_id=USER_ID,
version="20260501_00",
arguments={
"media": {"name": img.name, "mimetype": "image/jpeg", "s3key": presigned.key},
"media_type": "image/jpeg",
"media_category": "tweet_image", # or "dm_image", "subtitles"
},
)
result = upload_resp.model_dump()
assert result["successful"], result["error"]
# Response nesting: data.data.id (NOT data.id, NOT data.media_id_string)
media_id = result["data"]["data"]["id"]
# 3. Create tweet with media_media_ids — this one is fine via gateway too
tweet_resp = client.tools.execute(
tool_slug="TWITTER_CREATION_OF_A_POST",
user_id=USER_ID,
arguments={"text": "your tweet text", "media_media_ids": [str(media_id)]},
)
tweet_id = tweet_resp.model_dump()["data"]["data"]["id"]
url = f"https://x.com/i/web/status/{tweet_id}"
此方法为何有效(调试记录——请保留):
- 如果不指定版本,
GET /api/v3/tools/TWITTER_UPLOAD_MEDIA会返回 404,因为该工具位于工具包版本20260501_00+中,而非默认版本00000000_00。 client.tools.execute(version=...)会通过/api/v3/tools/execute/{slug}路由,该路由支持版本识别。- 网关使用 v2
/api/v2/actions/{slug}/execute执行工具——v2 不支持版本路由,因此无法调用带版本的工具。不要尝试为此“修复”网关——添加版本和 FileUploadable 会让它变得臃肿。保持轻量。 media参数需要{name, mimetype, s3key}(FileUploadable 架构),而不是 base64。传入 base64 会返回:“Input should be a valid dictionary or instance of FileUploadable on parametermedia”。TWITTER_UPLOAD_MEDIA的文件大小限制约为 5 MB。对于更大的文件、视频或 GIF,请使用TWITTER_UPLOAD_LARGE_MEDIA(分块上传,流程相同,但需额外的分段参数)。
⚠️ Twitter 的限制与备用方案:
TWITTER_RECENT_SEARCH仅覆盖最近 7 天,更早的推文不会显示TWITTER_FULL_ARCHIVE_SEARCH需要 Twitter API Pro 访问权限,普通 OAuth App 无法使用- 获取用户推文历史时,优先使用平台原生工具
twitter_user_tweets,而非仅覆盖最近 7 天的工具
📅 Google Calendar
| 工具 Slug | 用途 | 关键参数 |
|---|---|---|
GOOGLECALENDAR_EVENTS_LIST | 列出事件 | calendarId(默认值:"primary")、timeMin、timeMax(RFC3339+时区)、singleEvents(true)、timeZone |
GOOGLECALENDAR_CREATE_EVENT | 创建事件 | calendarId、summary、start、end、description、attendees |
GOOGLECALENDAR_DELETE_EVENT | 删除事件 | calendarId、eventId |
🐙 GitHub
| 工具 Slug | 用途 | 关键参数 |
|---|---|---|
GITHUB_CREATE_AN_ISSUE | 创建议题 | owner、repo、title、body、labels、assignees |
GITHUB_LIST_REPOSITORY_ISSUES | 列出议题 | owner、repo、sort、state(open/closed/all)、page、per_page |
GITHUB_GET_AN_ISSUE | 获取议题详情 | owner、repo、issue_number |
GITHUB_CREATE_A_PULL_REQUEST | 创建 PR | owner、repo、title、head、base、body、draft |
GITHUB_LIST_PULL_REQUESTS | 列出 PR | owner、repo、state、sort、head、base |
GITHUB_MERGE_A_PULL_REQUEST | 合并 PR | owner、repo、pull_number、commit_title、sha |
GITHUB_GET_A_REPOSITORY | 获取仓库信息 | owner、repo |
GITHUB_SEARCH_CODE | 搜索代码 | q(GitHub 搜索语法)、sort、order、per_page |
GITHUB_GET_REPOSITORY_CONTENT | 获取文件内容 | owner、repo、path、ref |
# Create issue
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GITHUB_CREATE_AN_ISSUE", "arguments": {"owner": "myorg", "repo": "myrepo", "title": "Bug: login fails", "body": "Steps to reproduce..."}}'
# List open issues
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GITHUB_LIST_REPOSITORY_ISSUES", "arguments": {"owner": "myorg", "repo": "myrepo", "state": "open", "per_page": 10}}'
📝 Notion
| 工具标识 | 用途 | 关键参数 |
|---|---|---|
NOTION_CREATE_NOTION_PAGE | 创建页面 | parent_id、title、markdown、icon、cover |
NOTION_SEARCH_NOTION_PAGE | 搜索页面/数据库 | query、filter_value(页面/数据库)、page_size |
NOTION_QUERY_DATABASE_WITH_FILTER | 查询数据库行 | database_id、filter、sorts、page_size |
NOTION_INSERT_ROW_DATABASE | 添加数据库行 | database_id、properties |
NOTION_UPDATE_ROW_DATABASE | 更新数据库行 | row_id、properties、icon、cover |
NOTION_FETCH_DATABASE | 获取数据库架构 | database_id |
NOTION_FETCH_BLOCK_CONTENTS | 获取页面内容 | block_id(= page_id) |
NOTION_ADD_MULTIPLE_PAGE_CONTENT | 添加内容块 | parent_block_id、content_blocks、after |
NOTION_UPDATE_PAGE | 更新页面属性 | page_id、properties、icon、cover、archived |
NOTION_DELETE_BLOCK | 删除/归档内容块 | block_id |
# Search pages
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "NOTION_SEARCH_NOTION_PAGE", "arguments": {"query": "Meeting Notes", "page_size": 5}}'
# Query database with filter
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "NOTION_QUERY_DATABASE_WITH_FILTER", "arguments": {"database_id": "abc123", "filter": {"property": "Status", "select": {"equals": "In Progress"}}, "page_size": 10}}'
📁 Google Drive
| 工具标识 | 用途 | 关键参数 |
|---|---|---|
GOOGLEDRIVE_CREATE_FILE_FROM_TEXT | 创建文件 | file_name、text_content、mime_type、parent_id |
GOOGLEDRIVE_FIND_FILE | 搜索文件 | q(Drive 搜索语法)、fields、spaces |
GOOGLEDRIVE_DOWNLOAD_FILE | 下载文件 | fileId、mime_type |
GOOGLEDRIVE_COPY_FILE | 复制文件 | fileId |
GOOGLEDRIVE_ADD_FILE_SHARING_PREFERENCE | 共享文件 | fileId、role、type、emailAddress |
# Search files by name
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GOOGLEDRIVE_FIND_FILE", "arguments": {"q": "name contains '\''report'\'' and mimeType != '\''application/vnd.google-apps.folder'\''"}}'
# Create text file
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GOOGLEDRIVE_CREATE_FILE_FROM_TEXT", "arguments": {"file_name": "notes.txt", "text_content": "Hello World"}}'
Google Drive 搜索语法(q 参数): name contains 'keyword'、mimeType = 'application/vnd.google-apps.folder'(文件夹)、'<folderId>' in parents(文件夹中的文件)、modifiedTime > '2026-01-01'。
📄 Google Docs
| 工具标识 | 用途 | 关键参数 |
|---|---|---|
GOOGLEDOCS_CREATE_DOCUMENT_MARKDOWN | 根据 Markdown 创建文档 | title、markdown_text |
GOOGLEDOCS_GET_DOCUMENT_PLAINTEXT | 以文本形式获取文档 | document_id、include_tables、include_headers |
GOOGLEDOCS_GET_DOCUMENT_BY_ID | 获取原始文档对象 | id |
# Create doc with markdown content
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GOOGLEDOCS_CREATE_DOCUMENT_MARKDOWN", "arguments": {"title": "Meeting Notes", "markdown_text": "# Q2 Planning\n\n- Item 1\n- Item 2"}}'
# Read doc as plain text
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GOOGLEDOCS_GET_DOCUMENT_PLAINTEXT", "arguments": {"document_id": "1abc...xyz"}}'
📊 Google Sheets
| 工具标识 | 用途 | 关键参数 |
|---|---|---|
GOOGLESHEETS_CREATE_GOOGLE_SHEET1 | 创建电子表格 | title |
GOOGLESHEETS_GET_SHEET_NAMES | 列出电子表格中的工作表 | spreadsheet_id、exclude_hidden |
GOOGLESHEETS_BATCH_GET | 读取单元格值 | spreadsheet_id、ranges(列表,A1 表示法)、majorDimension、valueRenderOption |
GOOGLESHEETS_UPDATE_VALUES_BATCH | 写入单元格值 | spreadsheet_id、data({range, values} 列表)、valueInputOption |
GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND | 追加行 | spreadsheetId、range、values、valueInputOption、insertDataOption |
GOOGLESHEETS_SPREADSHEETS_VALUES_BATCH_CLEAR | 清除区域 | spreadsheet_id、ranges |
GOOGLESHEETS_GET_SPREADSHEET_INFO | 获取完整的电子表格元数据 | spreadsheet_id |
GOOGLESHEETS_UPDATE_SHEET_PROPERTIES | 更新工作表属性 | spreadsheet_id、sheet_id、title、index |
# Read cells
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GOOGLESHEETS_BATCH_GET", "arguments": {"spreadsheet_id": "1abc...xyz", "ranges": ["Sheet1!A1:D10"]}}'
# Write cells
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GOOGLESHEETS_UPDATE_VALUES_BATCH", "arguments": {"spreadsheet_id": "1abc...xyz", "valueInputOption": "USER_ENTERED", "data": [{"range": "Sheet1!A1:B2", "values": [["Name", "Score"], ["Alice", 95]]}]}}'
# Append rows
curl -s -X POST $GATEWAY/internal/execute \
-H "Content-Type: application/json" \
-d '{"tool": "GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND", "arguments": {"spreadsheetId": "1abc...xyz", "range": "Sheet1!A:B", "valueInputOption": "USER_ENTERED", "values": [["Bob", 88], ["Charlie", 92]]}}'
⚠️ Google Sheets 注意事项:
valueInputOption:"USER_ENTERED"(解析公式/数字)或"RAW"(按原样作为文本处理)ranges使用 A1 表示法:"Sheet1!A1:D10"、"Sheet1!A:A"(整列)BATCH_GET返回data.data.valueRanges[].values(二维数组)spreadsheetId和spreadsheet_id:有些工具使用驼峰命名,有些使用蛇形命名;不确定时请查看架构
重要说明
- 工具 slug 为大写:
GMAIL_SEND_EMAIL - 工具包 slug 为小写:
gmail、github - 参数键:始终使用
"arguments",不要使用"params"——params会被静默忽略 - 时间参数:使用带时区偏移的 RFC3339 格式(
2026-04-08T00:00:00+08:00),除非确有需要,否则不要使用 UTC - OAuth 令牌由 Composio 管理——过期时会自动刷新
- 响应嵌套:Composio 执行响应通常为
data.data,但 Twitter 为data.data.data(3 层)。请递归访问 data 进行解析。 - 原生工具备用方案:当 Composio 工具有局限性时(例如,Twitter 搜索仅支持最近 7 天),优先使用平台内置的原生工具(例如,
twitter_user_tweets)
常见问题
Browserbase 连接名称不匹配
如果 /internal/connections 显示工具包 browserbase_tool 的状态为 ACTIVE,但执行 BROWSER_TOOL_* 时返回 "No active connection found for toolkit 'browser'",则说明网关侧的工具包别名不匹配(browserbase_tool 与 browser)。
处理方法:
- 对于会话管理工具(
SESSIONS_*、CONTEXTS_*、UPLOADS_*等),网关应在服务端规范化 Browserbase 别名。如果未能规范化,请尝试使用BROWSER_TOOL_*和BROWSERBASE_TOOL_*slug。 - 对于实际的浏览器控制(导航、点击、填写、抓取),不要使用 Composio execute——请按照上方 Browserbase 部分的说明,使用 Playwright
connect_over_cdp。Composio 工具只管理会话,不处理页面交互。
Gmail 嵌套 JSON 解析
Gmail 返回包含多层 HTML 内容的复杂 JSON 结构。不要尝试使用 json.loads 解析嵌套字符串。在 Python 中直接将其作为 dict 访问——网关已经返回了解析后的 JSON。