来源接入清单
按服务配置来源、完成授权,先用只读请求核对工具与资源范围,再接入日常工作。
挑来源
挑来源的顺序是固定的:先看服务有没有现成的 MCP 服务,没有再看它是否提供稳定的 HTTP 接口,最后才考虑把本机资料登记为本地目录。
工具越明确越好。服务提供 MCP 时优先用 MCP,因为工具语义清楚、出错时容易定位;只有 HTTP 接口时用接口来源,请求路径由你约束;资料就在本机时用本地目录,不引入网络调用。
同时接入的来源不宜太多。每多一个来源就多一组工具,工具过密会拖慢每轮响应,也会让模型更难判断该用哪一个。
- 可重复使用的集成才值得建来源,一次性的界面操作不必接进来。
- 同一份数据有两种接法时,选工具更明确的那一种。
- 先把一个来源跑通,再按任务需要逐步扩展。
常见来源接入清单
按服务选择下面的接法,完成配置和授权后,先用一条只读请求验证实际工具与资源范围。
示例 config.json 包含 id、slug、enabled、provider 和类型块。替换标明的客户端 ID、文件 ID、路径或设备环境变量;不要把 REPLACE_WITH 值当成有效凭据。每项还需 guide.md 记录资源范围。
| 主题 | 接入方式 | 首个检查 |
|---|---|---|
| Amplitude | API | 对应配置 + source_test |
| Brave Search | MCP | 对应配置 + source_test |
| Craft(第三方文档服务) | MCP | 对应配置 + source_test |
| 本地文件系统 | Local | 对应配置 + source_test |
| GitHub | MCP | 对应配置 + source_test |
| Google OAuth:七项服务的共同前提 | OAuth | 项目 / API / 客户端 / 回调 |
| Google Calendar | API | 对应配置 + source_test |
| Google Docs | API | 对应配置 + source_test |
| Google Drive | API | 对应配置 + source_test |
| Gmail | API | 对应配置 + source_test |
| Google Search Console | API | 对应配置 + source_test |
| Google Sheets | API | 对应配置 + source_test |
| YouTube | API | 对应配置 + source_test |
| Linear | MCP | 对应配置 + source_test |
| 记忆 MCP | MCP | 对应配置 + source_test |
| Microsoft Calendar | API | 对应配置 + source_test |
| Microsoft Outlook | API | 对应配置 + source_test |
| Microsoft SharePoint | API | 对应配置 + source_test |
| Microsoft Teams | API | 对应配置 + source_test |
| Slack | API | 对应配置 + source_test |
Amplitude
- 在 Amplitude 项目设置获取该项目的 API Key 和 Secret Key;Basic 的 username 对应 API Key,password 对应 Secret Key,不是账号登录密码。
- 请 Agent 调用
source_credential_prompt({"sourceSlug":"amplitude","mode":"basic","labels":{"username":"API Key","password":"Secret Key"}}),然后source_test({"sourceSlug":"amplitude"})。 - 先 GET
events/list看可见事件;查询区间平均会话时用 GETsessions/average?start=20261001&end=20261007,日期为YYYYMMDD,使用项目时区。
- EU 数据驻留项目改用 https://analytics.eu.amplitude.com/api/2/。
events/list返回当前周概况,不要假定给它 start/end 就能改成任意区间。401 先核对项目及 Key 对;限流按返回提示退避。
{
"id": "amplitude-docs-example",
"name": "Amplitude",
"slug": "amplitude",
"enabled": true,
"provider": "amplitude",
"type": "api",
"api": {
"baseUrl": "https://amplitude.com/api/2/",
"authType": "basic",
"testEndpoint": {
"method": "GET",
"path": "events/list"
}
}
}Brave Search
- 在 Brave Search API 控制台申请有搜索权限的 Key,在运行 Agent 的机器安装 Node/npx,并允许工作区本地 MCP。
BRAVE_API_KEY是本地进程环境变量,填在 mcp.env 时属于明文;也可删除 env 中该项,确保实际宿主进程已继承它。凭据库输入不会自动转成此变量。- 运行
source_test({"sourceSlug":"brave-search"}),确认出现 brave_web_search 等工具,再做一个限量的网页搜索;只有所选 Key 套餐支持时才使用新闻或其他搜索。
- 探索模式权限可精确允许 brave_.*search 工具族;核对工具实际名称和输入 schema,不放行无关写操作。本例使用 Brave 官方发布的 MCP 包。
{
"id": "brave-search-docs-example",
"name": "Brave Search",
"slug": "brave-search",
"enabled": true,
"provider": "brave",
"type": "mcp",
"mcp": {
"transport": "stdio",
"command": "npx",
"args": [
"-y",
"@brave/brave-search-mcp-server",
"--transport",
"stdio"
],
"env": {
"BRAVE_API_KEY": "REPLACE_WITH_BRAVE_API_KEY"
},
"authType": "none"
}
}Craft(第三方文档服务)
- 在第三方 Craft 的 Space 设置中创建 MCP Link,把生成的完整地址填入 mcp.url;一个链接对应所授权的 Space/文档范围。
authType为 none,因为访问能力已在链接里,而不是来源公开无权限。运行source_test({"sourceSlug":"craft"}),先列文件夹和文档,并核对 Space。- 写 collection 前先调用 collectionSchema_get,format 使用 json-schema-items;按返回的实际属性 key 构建 collectionItems_add。若 schema 中确有 year,条目形状是 {"title":"Example","properties":{"year":2026}},不能把 year 平铺到顶层。
- collectionSchema_update 替换整份 schema,必须保留仍需存在的字段及稳定 key。文档按 block ID 和层级读取;访问链接失效应在 Craft 重建授权。
{
"id": "craft-docs-example",
"name": "Craft",
"slug": "craft",
"enabled": true,
"provider": "craft",
"type": "mcp",
"mcp": {
"transport": "http",
"url": "https://mcp.craft.do/links/REPLACE_WITH_LINK_ID/mcp",
"authType": "none"
}
}本地文件系统
- 选择运行 Agent 的机器上已存在、可读的绝对目录,在 local.path 填实际路径;不需要启动 MCP 进程或填写令牌。
guide.md记录目录结构和使用约定,运行source_test({"sourceSlug":"reference-files"}),然后列出目录并读取一份已知文件。
- 来源是资料目录入口,不是操作系统沙箱。探索模式允许内置读取工具,写入仍按会话模式与路径权限处理。完整步骤见本地文件来源。
{
"id": "reference-files-docs-example",
"name": "参考资料",
"slug": "reference-files",
"enabled": true,
"provider": "filesystem",
"type": "local",
"local": {
"path": "/REPLACE_WITH_ABSOLUTE_DIRECTORY"
}
}GitHub
- 优先检查 gh --version 和 gh auth status;安装后运行 gh auth login,再用 gh repo view 或 gh pr list 即可,无需为了 CLI 再建来源。
- 需要结构化工具时安装并启动 Docker。创建只覆盖目标仓库及所需权限的 fine-grained PAT;不要把 classic 的 repo/read:org scope 当成 fine-grained 权限选项。
- 按示例把 PAT 注入
GITHUB_PERSONAL_ACCESS_TOKEN;mcp.env 是配置明文,也可继承正确的宿主变量。运行source_test({"sourceSlug":"github"}),再读取目标仓库。
- 远程官方 MCP 的 https://api.githubcopilot.com/mcp/ 可选择兼容的 PAT Bearer;不要假定第三方客户端能直接完成其 OAuth App 注册。自建 GitHub OAuth App 的 API 接法见通用 OAuth。
{
"id": "github-docs-example",
"name": "GitHub",
"slug": "github",
"enabled": true,
"provider": "github",
"type": "mcp",
"mcp": {
"transport": "stdio",
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "REPLACE_WITH_REPOSITORY_SCOPED_PAT"
},
"authType": "none"
}
}Google OAuth:七项服务的共同前提
以下 Google 示例使用 provider: google、api.authType: oauth,显式 googleService 选择服务;googleScopes 优先于默认服务范围,示例先用只读范围。授权完成后的令牌由来源统一注入。
403 分别检查 API 是否启用、OAuth scope 和账号资源权限;配置中的示例 ID 必须换成真实可读资源,测试失败不能直接归因于端点下线。
- 在 Google Cloud 创建或选择项目,为下列服务启用对应 API;配置 OAuth 同意界面,并在应用仍处测试状态时添加自己的测试用户。
- 为本机桌面创建支持 loopback 的 OAuth 客户端,例如 Google 的 Desktop app 类型,取得 Client ID 与 Secret。两者都要填写;授权回调由本机桌面监听。
- 在具体来源的 api.googleOAuthClientId 与 api.googleOAuthClientSecret 填入客户端信息;这些字段是配置明文。服务选择值分别为 calendar、docs、drive、gmail、searchconsole、sheets、youtube。
- 请 Agent 调用 source_google_oauth_trigger({"sourceSlug":"对应来源 slug"}),在本机浏览器确认账号、scope 和本次 redirect_uri。桌面监听从 localhost:6477/callback 起选空闲端口,授权后再
source_test和实际读取。 - 写入 Docs/Sheets、创建日程或发送 Gmail 前,换成业务需要的写入 scope 并重新授权;界面允许一次写操作不会替你扩展 Google token 的范围。
Google Calendar
- 启用 Google Calendar API,按上节完成 Google OAuth;测试先列可见日历并记录 calendarId。
- 按 Google OAuth 小节授权后,运行
source_test({"sourceSlug":"google-calendar"})。 - 查询日程用 calendars/{calendarId}/events,params 示例 {"timeMin":"2026-10-27T00:00:00+08:00","timeMax":"2026-10-28T00:00:00+08:00","singleEvents":true,"orderBy":"startTime","timeZone":"Asia/Shanghai","maxResults":10}。带时区边界,复发日程展开为单次实例,继续使用
nextPageToken。
{
"id": "google-calendar-docs-example",
"name": "Google Calendar",
"slug": "google-calendar",
"enabled": true,
"provider": "google",
"type": "api",
"api": {
"baseUrl": "https://www.googleapis.com/calendar/v3/",
"authType": "oauth",
"googleService": "calendar",
"googleScopes": [
"https://www.googleapis.com/auth/calendar.readonly"
],
"googleOAuthClientId": "REPLACE_WITH_CLIENT_ID.apps.googleusercontent.com",
"googleOAuthClientSecret": "REPLACE_WITH_CLIENT_SECRET",
"testEndpoint": {
"method": "GET",
"path": "users/me/calendarList?maxResults=1"
}
}
}Google Docs
- 启用 Google Docs API,准备账号可读的 documentId;Docs API 没有文档列表,发现文档 ID 可另接 Drive。
- 按 Google OAuth 小节授权后,运行
source_test({"sourceSlug":"google-docs"})。 - 先 GET documents/{documentId},按返回的段落/元素 startIndex、endIndex 读取。写入用 POST documents/{documentId}:batchUpdate,body 如 {"requests":[{"insertText":{"location":{"index":1},"text":"Example "}}]};索引为 UTF-16 单元,写前重新读取并确认目标 tab/正文范围,勿把字符数量当索引。
{
"id": "google-docs-docs-example",
"name": "Google Docs",
"slug": "google-docs",
"enabled": true,
"provider": "google",
"type": "api",
"api": {
"baseUrl": "https://docs.googleapis.com/v1/",
"authType": "oauth",
"googleService": "docs",
"googleScopes": [
"https://www.googleapis.com/auth/documents.readonly"
],
"googleOAuthClientId": "REPLACE_WITH_CLIENT_ID.apps.googleusercontent.com",
"googleOAuthClientSecret": "REPLACE_WITH_CLIENT_SECRET",
"testEndpoint": {
"method": "GET",
"path": "documents/REPLACE_WITH_DOCUMENT_ID"
}
}
}Google Drive
- 启用 Google Drive API,完成 drive 只读授权;确认目标是个人盘还是 shared drive。
- 按 Google OAuth 小节授权后,运行
source_test({"sourceSlug":"google-drive"})。 - GET files 的 params 用 {"q":"trashed = false and mimeType = 'application/pdf'","pageSize":10,"fields":"
nextPageToken,files(id,name,mimeType)"}。下载普通文件用 files/{id}?alt=media;Google 原生 Docs/Sheets 需要 export 并选 MIME,不能假定 alt=media 通用。共享盘另按文档提供 driveId 和支持参数。
{
"id": "google-drive-docs-example",
"name": "Google Drive",
"slug": "google-drive",
"enabled": true,
"provider": "google",
"type": "api",
"api": {
"baseUrl": "https://www.googleapis.com/drive/v3/",
"authType": "oauth",
"googleService": "drive",
"googleScopes": [
"https://www.googleapis.com/auth/drive.readonly"
],
"googleOAuthClientId": "REPLACE_WITH_CLIENT_ID.apps.googleusercontent.com",
"googleOAuthClientSecret": "REPLACE_WITH_CLIENT_SECRET",
"testEndpoint": {
"method": "GET",
"path": "files?pageSize=1&fields=files(id,name)"
}
}
}Gmail
- 启用 Gmail API,完成 gmail 只读授权。先用
users/me/profile核对邮箱身份;不是把 Gmail 接入消息网关。 - 按 Google OAuth 小节授权后,运行
source_test({"sourceSlug":"google-gmail"})。 - GET users/me/messages,params 用 {"q":"is:unread newer_than:7d","
maxResults":5};列表只有 id/threadId,正文另取 users/me/messages/{id}。草稿为 POST users/me/drafts,发送为 users/me/messages/send 或 users/me/drafts/send,raw 使用 RFC 2822 MIME 的 base64url;先审阅再明确发送,并重新授予 compose/send 所需范围。
{
"id": "google-gmail-docs-example",
"name": "Gmail",
"slug": "google-gmail",
"enabled": true,
"provider": "google",
"type": "api",
"api": {
"baseUrl": "https://gmail.googleapis.com/gmail/v1/",
"authType": "oauth",
"googleService": "gmail",
"googleScopes": [
"https://www.googleapis.com/auth/gmail.readonly"
],
"googleOAuthClientId": "REPLACE_WITH_CLIENT_ID.apps.googleusercontent.com",
"googleOAuthClientSecret": "REPLACE_WITH_CLIENT_SECRET",
"testEndpoint": {
"method": "GET",
"path": "users/me/profile"
}
}
}Google Search Console
- 启用 Google Search Console API,登录对目标 property 有访问权的账号;先 GET sites 取得实际 siteUrl。
- 按 Google OAuth 小节授权后,运行
source_test({"sourceSlug":"google-search-console"})。 - 把完整 property 编码成路径段:
sc-domain:example.com→sc-domain%3Aexample.com;URL-prefix https://example.com/ →https%3A%2F%2Fexample.com%2F。查询为 POSTsites/{编码值}/searchAnalytics/query,body 用 {"startDate":"2026-10-01","endDate":"2026-10-07","dimensions":["query"],"rowLimit":10};数据存在处理延迟,空结果不等于实时无访问。
{
"id": "google-search-console-docs-example",
"name": "Google Search Console",
"slug": "google-search-console",
"enabled": true,
"provider": "google",
"type": "api",
"api": {
"baseUrl": "https://www.googleapis.com/webmasters/v3/",
"authType": "oauth",
"googleService": "searchconsole",
"googleScopes": [
"https://www.googleapis.com/auth/webmasters.readonly"
],
"googleOAuthClientId": "REPLACE_WITH_CLIENT_ID.apps.googleusercontent.com",
"googleOAuthClientSecret": "REPLACE_WITH_CLIENT_SECRET",
"testEndpoint": {
"method": "GET",
"path": "sites"
}
}
}Google Sheets
- 启用 Google Sheets API,准备可访问的 spreadsheetId;先测试表格元数据,再读取一个小范围。
- 按 Google OAuth 小节授权后,运行
source_test({"sourceSlug":"google-sheets"})。 - 读取用 spreadsheets/{id}/values/{编码后的 A1 范围},例如 Summary!A1:B5;多个范围用 values:batchGet 和 ranges。写入使用 values:batchUpdate,body 如 {"valueInputOption":"RAW","data":[{"range":"Summary!A1:B2","values":[["Item","Count"],["Example",1]]}]}。RAW 保留字面值,USER_ENTERED 按表格输入解析;写入前扩展 scope 并确认范围。
{
"id": "google-sheets-docs-example",
"name": "Google Sheets",
"slug": "google-sheets",
"enabled": true,
"provider": "google",
"type": "api",
"api": {
"baseUrl": "https://sheets.googleapis.com/v4/",
"authType": "oauth",
"googleService": "sheets",
"googleScopes": [
"https://www.googleapis.com/auth/spreadsheets.readonly"
],
"googleOAuthClientId": "REPLACE_WITH_CLIENT_ID.apps.googleusercontent.com",
"googleOAuthClientSecret": "REPLACE_WITH_CLIENT_SECRET",
"testEndpoint": {
"method": "GET",
"path": "spreadsheets/REPLACE_WITH_SPREADSHEET_ID?fields=spreadsheetId,properties.title"
}
}
}YouTube
- 启用 YouTube Data API v3,完成 youtube 账号授权。使用 mine=true 前确认当前账号有对应频道。
- 按 Google OAuth 小节授权后,运行
source_test({"sourceSlug":"google-youtube"})。 - 先 GET
channels?part=snippet&mine=true&maxResults=1。其他读取按channels/videos/playlists/playlistItems选择路径,明确 part 与maxResults,用nextPageToken继续。search 较耗配额,先查已知 ID,查询配额控制台而不是假定固定额度。
{
"id": "google-youtube-docs-example",
"name": "YouTube",
"slug": "google-youtube",
"enabled": true,
"provider": "google",
"type": "api",
"api": {
"baseUrl": "https://www.googleapis.com/youtube/v3/",
"authType": "oauth",
"googleService": "youtube",
"googleScopes": [
"https://www.googleapis.com/auth/youtube.readonly"
],
"googleOAuthClientId": "REPLACE_WITH_CLIENT_ID.apps.googleusercontent.com",
"googleOAuthClientSecret": "REPLACE_WITH_CLIENT_SECRET",
"testEndpoint": {
"method": "GET",
"path": "channels?part=snippet&mine=true&maxResults=1"
}
}
}Linear
- 准备可访问目标团队的 Linear 账号;保存后调用
source_oauth_trigger({"sourceSlug":"linear"}),用桌面本机回调授权,再source_test。只读专用来源可用官方 /mcp/readonly 端点。 - 先列团队与项目,缓存实际 teamId、projectId、workflow state ID 到
guide.md;ENG-123 是议题标识,不能代替 teamId。查询大列表按返回 cursor 继续。 - 修改议题前先读取当前 state 与项目,按实际工具 schema 填写。若改走 GraphQL API,priority 使用 0=无、1=紧急、2=高、3=中、4=低,不能照 P0/P1 的显示名称推断整数。
- 发现工具为空时先查授权与团队可见性;OAuth metadata/回调错误不等于整个 Linear MCP 端点不可用。
{
"id": "linear-docs-example",
"name": "Linear",
"slug": "linear",
"enabled": true,
"provider": "linear",
"type": "mcp",
"mcp": {
"transport": "http",
"url": "https://mcp.linear.app/mcp",
"authType": "oauth",
"oauthRelay": false
}
}记忆 MCP
- 安装 Node/npx,选择一个持久、可写的绝对存储路径,建立父目录后填
MEMORY_FILE_PATH,避免依赖 npx 缓存包目录的默认文件。 - 运行
source_test({"sourceSlug":"memory"}) 后先调用read_graph、search_nodes或open_nodes;写入用实体/观察/关系工具,完整参数与权限见记忆来源。
- 此服务不需要网络 OAuth;不同工作区若指向同一文件,会共享记忆数据,来源标识隔离不能替代文件隔离。
{
"id": "memory-docs-example",
"name": "Memory",
"slug": "memory",
"enabled": true,
"provider": "memory",
"type": "mcp",
"mcp": {
"transport": "stdio",
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-memory"
],
"env": {
"MEMORY_FILE_PATH": "/REPLACE_WITH_ABSOLUTE_PATH/memory.jsonl"
},
"authType": "none"
}
}Microsoft Graph 的共同授权前提
四个 Graph 配方使用 provider: microsoft、api.authType: oauth,必须显式设置 microsoftService 或 microsoftScopes:通用 https://graph.microsoft.com/v1.0/ 无法推断具体服务。示例自定义只读范围覆盖默认的部分读写范围。
401 查登录和刷新,403 查委派范围、租户管理员同意和资源归属;列表按 @odata.nextLink 分页,但调用时仍转换为本来源下的相对路径和查询,不把任意外站 URL 交给工具。
- 运行时的原生 Microsoft 流程需要由启动环境提供已注册的 MICROSOFT_OAUTH_CLIENT_ID,支持公共客户端 PKCE 与本机回调,并满足租户同意策略;缺失时报 not configured,不能只填 service 就认为可登录。
- 条件具备后请 Agent 调用 source_microsoft_oauth_trigger({"sourceSlug":"对应来源 slug"}),核对租户、账号和范围,再
source_test。自定义范围会补 User.Read 与 offline_access。 - 自行注册应用且不能修改原生启动配置时,另建普通 provider(例如 microsoft-custom)的 API 来源,在 api.oauth 明填自己应用的 authorizationUrl、tokenUrl、clientId 和 Graph scopes,按通用 OAuth配置;不要发明 api.microsoftOAuthClientId 字段。
Microsoft Calendar
- 按 Graph 共同前提准备 OAuth,
microsoftService必须为 microsoft-calendar;运行 source_microsoft_oauth_trigger({"sourceSlug":"microsoft-calendar"})。 - 运行
source_test({"sourceSlug":"microsoft-calendar"}) 并核对可见账号资源。 - 先列日历,查询区间用 GET me/calendarView?startDateTime=2026-10-27T00%3A00%3A00%2B08%3A00&endDateTime=2026-10-28T00%3A00%3A00%2B08%3A00,区间带偏移以展开复发实例。创建 me/events 需 Calendars.ReadWrite,body 包含 subject、start/end 的 dateTime 和 timeZone。
{
"id": "microsoft-calendar-docs-example",
"name": "Microsoft Calendar",
"slug": "microsoft-calendar",
"enabled": true,
"provider": "microsoft",
"type": "api",
"api": {
"baseUrl": "https://graph.microsoft.com/v1.0/",
"authType": "oauth",
"microsoftService": "microsoft-calendar",
"microsoftScopes": [
"https://graph.microsoft.com/Calendars.Read"
],
"testEndpoint": {
"method": "GET",
"path": "me/calendars?$top=1"
}
}
}Microsoft Outlook
- 按 Graph 共同前提准备 OAuth,
microsoftService必须为 outlook;运行 source_microsoft_oauth_trigger({"sourceSlug":"outlook"})。 - 运行
source_test({"sourceSlug":"outlook"}) 并核对可见账号资源。 - GET
me/messages的 params 可用 {"$top":5,"$select":"id,subject,receivedDateTime","$search":""release""}。草稿用 POSTme/messages;发送用 POSTme/sendMail,body 是 {"message":{"subject":"Example","body":{"contentType":"Text","content":"Draft for review"},"toRecipients":[{"emailAddress":{"address":"recipient@example.com"}}]},"saveToSentItems":true}。草稿与发送是不同操作,需对应Mail.ReadWrite/Mail.Send及明确发送授权。
{
"id": "outlook-docs-example",
"name": "Microsoft Outlook",
"slug": "outlook",
"enabled": true,
"provider": "microsoft",
"type": "api",
"api": {
"baseUrl": "https://graph.microsoft.com/v1.0/",
"authType": "oauth",
"microsoftService": "outlook",
"microsoftScopes": [
"https://graph.microsoft.com/Mail.Read"
],
"testEndpoint": {
"method": "GET",
"path": "me/mailFolders?$top=1"
}
}
}Microsoft SharePoint
- 按 Graph 共同前提准备 OAuth,
microsoftService必须为 sharepoint;运行 source_microsoft_oauth_trigger({"sourceSlug":"sharepoint"})。 - 运行
source_test({"sourceSlug":"sharepoint"}) 并核对可见账号资源。 - 先 GET sites?search=关键词 确认 siteId,再 GET sites/{siteId}/drives 取得文档库 driveId,最后 GET drives/{driveId}/root/children 或 drives/{driveId}/items/{itemId}/children。名称不能代替 site/drive/item ID;下载 content 可能重定向到带临时权限的地址,勿记录或分享该地址。
{
"id": "sharepoint-docs-example",
"name": "Microsoft SharePoint",
"slug": "sharepoint",
"enabled": true,
"provider": "microsoft",
"type": "api",
"api": {
"baseUrl": "https://graph.microsoft.com/v1.0/",
"authType": "oauth",
"microsoftService": "sharepoint",
"microsoftScopes": [
"https://graph.microsoft.com/Sites.Read.All"
],
"testEndpoint": {
"method": "GET",
"path": "sites?search=*"
}
}
}Microsoft Teams
- 按 Graph 共同前提准备 OAuth,
microsoftService必须为 teams;运行 source_microsoft_oauth_trigger({"sourceSlug":"teams"})。 - 运行
source_test({"sourceSlug":"teams"}) 并核对可见账号资源。 - 先 GET me/chats 或 me/joinedTeams,使用实际 chatId/teamId;再 GET teams/{teamId}/channels,按 channelId 查询 messages。读取频道消息需要另授 ChannelMessage.Read.All 等对应范围;发送到 teams/{teamId}/channels/{channelId}/messages 的 JSON 为 {"body":{"contentType":"text","content":"Example"}},需 ChannelMessage.Send,不能因为能列 chats 就假定可写。
{
"id": "teams-docs-example",
"name": "Microsoft Teams",
"slug": "teams",
"enabled": true,
"provider": "microsoft",
"type": "api",
"api": {
"baseUrl": "https://graph.microsoft.com/v1.0/",
"authType": "oauth",
"microsoftService": "teams",
"microsoftScopes": [
"https://graph.microsoft.com/Chat.Read",
"https://graph.microsoft.com/Team.ReadBasic.All",
"https://graph.microsoft.com/Channel.ReadBasic.All"
],
"testEndpoint": {
"method": "GET",
"path": "me/chats?$top=1"
}
}
}Slack
- 在你自己的 Slack App 中申请所需 scopes 并安装到目标工作区,取得 bot 或 user token。这里使用普通 provider 标签 slack-token 表示手工 Bearer;原生 provider: slack 的托管 OAuth 当前不可用。
- 用
source_credential_prompt({"sourceSlug":"slack","mode":"bearer"}) 输入令牌,然后source_test。auth.test是 POST 且验证身份;api.test 不能代替它。还要检查 JSON 中 ok 是否为 true。 - 先 POST conversations.list 取得频道 ID,再 GET conversations.info?channel={id} 或 POST conversations.history 查询。权限至少与目标频道类型匹配(如 channels:read/history);私有频道还要成员关系。search.all 需要可用的 user token 与 search:read,不能假定 bot token 可搜索。
- 这些读取可能使用 POST;在来源
permissions.json只允许 POST 的 ^(?:auth\.test|conversations\.list|conversations\.history|users\.list)$,不要放行 chat.postMessage。写消息需 chat:write、目标 channel ID 及明确授权;429 遵循 Retry-After。 permissions.json的完整只读 POST 规则为 {"allowedApiEndpoints":[{"method":"POST","path":"^/?(?:auth\\.test|conversations\\.list|conversations\\.history|users\\.list)$"}]}。保留其他确有用途的规则;这不会授予 Slack token 新的 scope。
{
"id": "slack-docs-example",
"name": "Slack",
"slug": "slack",
"enabled": true,
"provider": "slack-token",
"type": "api",
"api": {
"baseUrl": "https://slack.com/api/",
"authType": "bearer",
"testEndpoint": {
"method": "POST",
"path": "auth.test"
}
}
}接入
接入前先把三件事说清楚:要这个来源做什么、范围到哪里、需要只读还是完整权限。范围和权限决定后面凭据该申请到哪一步。
接入动作本身很短:建来源、写配置、填凭据、保存。凭据只出现在专用字段里,不要写进配置文件的说明部分、对话正文或技能文件。
- 在
~/.zero-works/workspaces/{工作区目录名}/sources/{slug}/ 保存完整config.json,slug 与目录一致,id 唯一。 - 按配方填写 API 基地址或 MCP 完整端点;stdio 使用实际可执行命令、参数和进程环境。
- 按正确入口授权:MCP/通用 API 用
source_oauth_trigger;Google/Microsoft 用各自专用工具;静态 token 用source_credential_prompt。 - 保存
guide.md,列清资源 ID、常用查询、只读与写入边界,然后source_test并进行最小读取。
- 先只申请当前任务需要的权限,需要更多时再补。
- 本地 stdio 来源的启动命令必须存在于运行 Agent 的机器上,配置前先确认命令来源。
- 接口来源的基地址末尾保留斜杠,测试端点路径不要带开头的斜杠。
验证
保存配置不等于接入成功。凭据可能过期,权限可能不足,地址可能写错,都要靠实际请求才能确认。
验证顺序建议是:先跑连接校验,再做一次真实读取,最后才交给 Agent 自主调用。这样每一步都能明确知道问题出在哪一层。
- 执行连接校验,确认状态变为已连接,必要时能看到已发现的工具数量。
- 发起一次范围清楚的只读请求,核对返回内容是否与预期一致。
- 确认工具名称前缀正确,再进入对话让它按正常方式调用。
- MCP 来源:核对发现的工具名称和数量;为空时检查服务发布内容及工具筛选,有些服务另提供资源或提示模板。
- API 来源:核对认证测试的 HTTP 状态、业务错误及返回账号;公开健康检查通过只说明地址可达。
- 本地文件夹:校验确认路径存在且可读。
- 本地 stdio 来源:命令不存在或不在 PATH 时会直接启动失败。
注意事项
服务端点、套餐和权限可能调整,按各项官方参考更新配置。OAuth 需要匹配的客户端注册、回调和账号授权,授权后再核对实际可见资源。
Zapier、Composio、Make、Pipedream 可以作为 MCP 来源接入,聚合器一侧负责连接下游账号;下方提供真实 MCP 配方,而不只把它们统称为 HTTP 接口。
限流与配额由第三方服务决定。触发限流时按服务返回的提示等待或降低频率,不要靠反复重试硬闯。
- 凭据过期后需要回到同一个入口重新填写;OAuth 来源在有刷新令牌时会自动续期,静态令牌需要自己更换。
- 只读模式下的来源默认只放行读取类操作,需要更多时再补充权限规则。
- 真正写入外部系统的操作前,先用只读请求确认范围,再决定是否放开权限。
- 不要把真实令牌、内网地址或凭据截图贴进对话、技能文件或反馈材料。
Zapier MCP
- 在 Zapier MCP 控制台创建 MCP server,选 Other 或通用客户端;添加具体读取动作,连接下游账号并保存必填参数。
- 从 Connect 页复制完整服务器 URL 与认证说明,映射为 type:mcp、mcp.transport:http、mcp.url。若 URL 自带访问能力则
authType:none;若另给 token 则 bearer 并走凭据框;若标明 OAuth 则 oauth 并在桌面启动授权。 - 运行
source_test后核对只出现你添加的动作,再调用一项只读工具。无工具时回 Zapier 检查是否已保存动作,而非自动扩大权限。
Composio / Rube
- 个人连接可用 https://connect.composio.dev/mcp,按 Composio 登录并连接需要的应用;开发者单 toolkit 模式先创建 auth config、连接账号、创建 MCP config,再生成该 user 的 URL。
- 开发者 URL 必须使用生成返回值,不从 server ID 猜地址。需要 x-api-key 时在 mcp.headerNames 声明 ["x-api-key"],通过
source_credential_prompt的 multi-header 模式保存;authType:none 表示不再追加 Bearer,不代表没有 Key。 source_test后核对用户、下游账号和工具范围,再调用一项只读工具;连接地址只使用控制台或 generate 返回的完整值。
{
"id": "composio-docs-example",
"name": "Composio",
"slug": "composio",
"enabled": true,
"provider": "composio",
"type": "mcp",
"mcp": {
"transport": "http",
"url": "https://connect.composio.dev/mcp",
"authType": "oauth",
"oauthRelay": false
}
}Make MCP
- 在 Make 准备要暴露为工具的 on-demand/active scenarios,核对输入输出;账号需要访问对应组织和场景。
- OAuth 使用 https://mcp.make.com/v2;设置 oauth 后在桌面授权时选择组织和 scopes。API Key 接法在 Profile → API access 创建包含 mcp:use 的 Key,使用 https://{MAKE_ZONE}/mcp/v2 和 bearer 凭据框;MAKE_ZONE 如 eu2.make.com。
- 运行
source_test并核对场景工具;场景调用本身可能发送消息或写入外部系统,先选择不会产生外部写入的验证场景。
{
"id": "make-docs-example",
"name": "Make",
"slug": "make",
"enabled": true,
"provider": "make",
"type": "mcp",
"mcp": {
"transport": "http",
"url": "https://mcp.make.com/v2",
"authType": "oauth",
"oauthRelay": false
}
}Pipedream MCP
- 在 Pipedream MCP 登录并连接需要的下游应用,选择可用动作和账号;MCP 配置页当前给出的通用地址为 https://mcp.pipedream.net/v2。
- 保存下面的 http/oauth 来源,调用
source_oauth_trigger({"sourceSlug":"pipedream"}),完成 Pipedream 授权后运行source_test。 - 核对该连接实际可用的工具和下游账号,再调用一项只读动作。没有暴露工具的应用不能靠服务目录中的名称推断已接通。
{
"id": "pipedream-docs-example",
"name": "Pipedream",
"slug": "pipedream",
"enabled": true,
"provider": "pipedream",
"type": "mcp",
"mcp": {
"transport": "http",
"url": "https://mcp.pipedream.net/v2",
"authType": "oauth",
"oauthRelay": false
}
}