需要用户凭据的小工具有三条路径,按凭据类型选择。
结构化配置:finch.settings
manifest 声明字段,Finch 在工具箱详情页原生渲染,用户保存后自动重载小工具:
{
"settings": {
"fields": [
{ "key": "endpoint", "type": "string", "label": "Endpoint" },
{ "key": "maxItems", "type": "number", "label": "最大条数", "default": 10 },
{ "key": "region", "type": "select", "label": "区域",
"options": [{ "value": "us", "label": "US" }, { "value": "eu", "label": "EU" }] }
]
}
}
代码里 ctx.settings.get('endpoint') 只读取,不能写入。字段类型:string、number、boolean、select、list;string 可标 secret: true(密码框)或 multiline: true(多行)。
API Key / Token
用《标准化 UI》里的模态框表单收集,存入 ctx.secrets。manifest 需声明允许的密钥名:
{ "permissions": { "secrets": ["apiKey"] } }
入口放哪里:ComposerAction 菜单、容器设置菜单(见《Session 容器》)、或一个 setup_* 工具。优先前两者——它们不依赖模型主动调用工具。
OAuth 路径 A:小工具自己持有 provider
用于调用普通 HTTPS API(Google、GitHub 等)。manifest 声明 provider id:
{ "permissions": { "oauth": ["google"] } }
代码定义 provider 并发起流程:
const google: finch.OAuthProviderConfig = {
id: 'google',
name: 'Google',
icon: 'assets/google.png', // 包内 PNG,显示在授权弹窗
clientId: PUBLIC_CLIENT_ID, // 发布者预先注册的公开 Client ID
authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
tokenEndpoint: 'https://oauth2.googleapis.com/token',
scopes: ['https://www.googleapis.com/auth/gmail.readonly'],
resourceOrigins: ['https://gmail.googleapis.com'], // HTTPS 白名单
};
await ctx.oauth.connect(google);
const status = await ctx.oauth.getStatus(google);
const res = await ctx.oauth.request(
google,
'https://gmail.googleapis.com/gmail/v1/users/me/profile',
);
await ctx.oauth.disconnect(google);
Finch 负责浏览器交互、加密存储、刷新加锁、Authorization 头注入。
安全边界(必须理解):
- 只用 Authorization Code + PKCE 公开客户端,不要内嵌 client secret。
- Access / refresh token 不会跨进程进入小工具,只能通过
ctx.oauth.request()代理调用。 resourceOrigins是 HTTPS 白名单,不在名单内的地址会被拒绝。request()会剥离调用方自带的Authorization、Cookie、Host、Proxy-Authorization头。- 凭据按小工具隔离存储,互相不可见。
OAuthResponse.body是字符串,先判断 HTTP 状态再解析;不要记录可能含隐私的响应体。
Device Flow:GitHub 这类 Web Flow 需要 secret 的服务,设 flow: 'device_code' 并提供 deviceAuthorizationEndpoint,Finch 负责展示、复制用户码并轮询令牌端点。
OAuth 客户端由发布者注册和维护,公开 Client ID 随包分发,不要让终端用户自己去申请 OAuth 应用。icon 强烈建议配置,否则授权弹窗没有品牌标识。

OAuth 路径 B:OAuth 保护的 MCP server
远程 MCP 端点要求 OAuth 时,不要走路径 A。声明 contributes.mcpServers[].oauth,由 MCP Client 完成 discovery、动态客户端注册(DCR)、PKCE 和 token 生命周期——你无需注册任何 OAuth 客户端,也不需要 permissions.oauth。品牌图标通过 mcpServers[].oauth.providerIcon 提供。
判断法则:同一个服务同时声明了 permissions.oauth 和 mcpServers[].oauth,一定是选错了路径。
登录状态怎么呈现
推荐组合:容器设置菜单里放一行 disabled 的状态行 + 一行可点击的登录/退出行。后台登录状态变化时调 notifyUpdate() 让菜单立即刷新。详见《Session 容器》。