Connector
Choose an integration method
A connector is WorkBuddy's capability extension interface. After a user installs a connector, they can call third-party services with natural language. WorkBuddy supports two integration methods:
| Approach | When to use | Description |
|---|---|---|
| MCP + Skill (recommended) | You already have an API service, or you can build an MCP Server | Expose tools over the MCP protocol; for remote services, prefer HTTPS SSE or streamableHttp |
| CLI + Skill | You already have a mature command-line tool | WorkBuddy installs and schedules the CLI; the CLI manages its own login state and credentials |
If the service can expose capabilities over a network API, prefer MCP + Skill. Choose CLI + Skill only when you already have a stable, cross-platform CLI. A connector can use only one approach; the two cannot be mixed.
If the service requires the user to fill in a long-lived credential such as an Access Token or API Key, rather than OAuth, use the user-supplied token mode of the MCP approach. See User-supplied token mode below.
MCP + Skill integration
Basic structure
your-connector/
├── connector-meta.json # 连接器元信息(必须)
├── mcp.json # MCP Server 连接配置(必须)
├── icon.svg # 市场图标(必须)
└── skills/ # AI 使用说明(可选)
└── {skill-name}/
└── SKILL.md
MCP Server requirements
- Follow a stable MCP protocol version;
- Remote services must use HTTPS and support SSE or streamableHttp; local processes may use stdio;
- Tool names, descriptions, parameters, and return values should be clear and stable so the AI can choose and call them correctly;
- Return readable error messages and set a reasonable timeout; a single request should respond within 30 seconds;
- Keep the service stably reachable; availability of at least 99.9% is recommended;
- Authentication is required when user data is involved, and you must follow least privilege;
- Configure only one MCP Server per connector.
Developer resources:
- MCP protocol specification: https://modelcontextprotocol.io/
- Python SDK: https://github.com/modelcontextprotocol/python-sdk
- TypeScript SDK: https://github.com/modelcontextprotocol/typescript-sdk
mcp.json
Remote MCP example:
{
"mcpServers": {
"your-service": {
"type": "streamableHttp",
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer ${SERVICE_TOKEN}"
},
"timeout": 30000
}
}
}
stdio MCP example:
{
"mcpServers": {
"your-service": {
"type": "stdio",
"command": "npx",
"args": ["your-mcp-package"],
"runtime": {
"type": "node",
"version": "20"
},
"npmRegistry": "https://registry.npmmirror.com"
}
}
}
Common fields:
| Field | Required when | Minimum version | Description |
|---|---|---|---|
| mcpServers | Required | Base | Top-level config; configure only one Server |
| type | Required for remote services | Base | sse, streamableHttp, or stdio; stdio can be inferred from command |
| url | Required for SSE/streamableHttp | Base | Production must use HTTPS |
| command | Required for stdio | Base | Startup command, such as npx, uvx, or node |
| args | Optional | Base | Startup argument array |
| headers / env | Optional | Base | ${VAR_NAME} variable references; do not write real credentials |
| timeout | Optional | Base | Connection timeout; default 30000 ms |
| cwd | Optional | 4.22.15 | Working directory of the stdio child process |
| disabledTools | Optional | 4.22.15 | Tools that should not be exposed to the AI |
| runtime | Optional | 5.0.0 | stdio runtime declaration; currently only { "type": "node", "version"?: string } is supported |
| npmRegistry / npmRegistries | Optional | 5.0.0 | npm registry; takes effect only when runtime.type: "node" is declared; array form falls back in order |
| staticEnv / staticHeaders | Optional | 5.0.0 | Fixed environment variables and request headers; not shown to the user and not editable |
| preAuth | Optional | 5.0.0 | Top-level field; only "cli" is supported. Before connecting, run the auth flow from cli.json in the same directory |
Minimum version indicates the WorkBuddy version from which the field takes effect. Base means long-term support. When you use a versioned field, declare the corresponding minWorkbuddyVersion in connector-meta.json.
CLI + Skill integration
Basic structure
your-cli-connector/
├── connector-meta.json # 连接器元信息(必须,type 为 cli)
├── cli.json # CLI 安装与认证配置(必须)
├── icon.svg # 市场图标(必须)
└── skills/
└── {skill-name}/
└── SKILL.md # CLI 使用说明(强烈推荐)
CLI tools have no standard tool-description protocol. The AI depends on a Skill to learn available commands and arguments, so this approach strongly recommends providing a Skill file.
CLI development requirements
- Support at least macOS and Linux; Windows is also recommended;
- Provide a non-interactive install path, plus explicit auth, status, and unAuth commands;
- After a successful auth, the CLI persists login state itself; status only checks state and has no side effects; unAuth revokes or clears login state;
- Commands should return a clear exit code and readable error messages; prefer JSON for business results;
- Do not depend on Node.js, Python, or global packages preinstalled on the user’s machine; if a runtime is required, declare it in cli.json;
- Keep credentials separate from the CLI install directory; never write secrets into the package, Skill, or sample config.
cli.json
{
"runtime": {
"type": "node",
"version": "20"
},
"init": {
"darwin": "npm install -g your-cli",
"linux": "npm install -g your-cli",
"win32": "npm install -g your-cli"
},
"auth": {
"darwin": "your-cli auth login",
"linux": "your-cli auth login",
"win32": "your-cli.cmd auth login"
},
"unAuth": {
"darwin": "your-cli auth logout",
"linux": "your-cli auth logout",
"win32": "your-cli.cmd auth logout"
},
"status": {
"darwin": "your-cli auth status",
"linux": "your-cli auth status",
"win32": "your-cli.cmd auth status"
},
"statusMatch": "Logged in",
"authUrlDomain": "example.com"
}
Common fields:
| Field | Required | Minimum version | Description |
|---|---|---|---|
| init.{platform} | Yes | Base | Install command per platform; platform names are darwin, linux, and win32 |
| auth | As needed | Base | Login command; a single step is a per-platform command object, multiple steps are an array |
| unAuth.{platform} | Required when auth is used | Base | Logout or authorization-cleanup command |
| status.{platform} | Required when auth is used | Base | Side-effect-free auth status check command |
| statusMatch / statusMatchJson | One of the two | Base / 4.24.0 | Text regex or JSON condition that identifies a logged-in state; the latter takes precedence |
| authUrlDomain | Recommended for browser auth | Base | Restricts the auth domains WorkBuddy may extract and open |
| env | Optional | 4.22.0 | Injects fixed environment variables into commands; may use $HOME or ${HOME} |
| runtime | Recommended when a runtime is required | 4.22.0 / 5.0.0 | Declares a Node.js or Python runtime and version; Python is supported from 5.0.0 |
| npmRegistry / npmRegistries | Optional | 4.22.0 / 4.24.0 | npm registry; array form falls back in order |
| versionCheck | Optional | 4.24.0 | Checks the CLI minimum version and re-runs install if it is too low |
| authWaitForExit | Optional | 4.22.0 | After extracting the auth URL, do not kill the child process; wait for the CLI to exit on its own |
| authQrModal | Optional | 4.22.0 | Show the auth link in an embedded modal; mutually exclusive with authDeviceFlow |
| authSuppressBrowser | Optional | 4.22.8 | Do not let WorkBuddy open the browser; leave it to the CLI |
| authDeviceFlow | Optional | 5.0.0 | OAuth 2.0 Device Flow (RFC 8628) config; mutually exclusive with authQrModal |
Runtime hosting and install location
For a CLI that depends on Node.js or Python, declare runtime in cli.json. WorkBuddy prepares the corresponding runtime and injects it into the command environment, so the user does not need to install it in advance. npm and pip install locations and caches are isolated under WorkBuddy-managed directories and will not pollute the user’s system environment.
| Declaration | WorkBuddy behavior | Developer notes |
|---|---|---|
runtime.type: "node" | Hosts Node.js, points the npm global install directory and cache to WorkBuddy-managed directories, and adds the bin directory to PATH | npm install -g <package> can be used directly, but do not assume it writes to the user’s system global directory, and do not depend on the user’s ~/.npmrc |
runtime.type: "python" | Hosts Python, activates a WorkBuddy-managed virtualenv, and isolates pip and caches from the user’s system | Prefer python -m pip install <package>; do not use pip install --user, and do not depend on the user’s system Python |
| runtime not declared | Reuses the user’s system environment and PATH | Use only when the CLI does not depend on Node/Python; you must ensure dependencies are available yourself |
Install paths are managed by WorkBuddy; developers should not hard-code absolute paths in commands. Credential and authorization files are fully managed by the CLI: WorkBuddy only schedules auth, status, and unAuth, and will not migrate or clean up the CLI’s credential files. Therefore credentials should be stored separately from the runtime install directory.
Auth flow and key constraints
After the user clicks Connect, WorkBuddy runs the following in order: check installation (run init if not installed), then run status to determine login state. If the user is not logged in, it runs auth, extracts the auth URL from command output and opens the browser, then polls status every 3 seconds for up to 5 minutes.
Key constraint: WorkBuddy terminates the auth child process as soon as it extracts the auth URL, so the auth child process itself cannot be the OAuth callback receiver. Choose one of the following:
| Approach | Complexity | When to use |
|---|---|---|
| Background daemon receives callback | Medium | The CLI already has a resident process; the daemon continues receiving the callback after auth exits and persists the token |
| Device Code Flow (recommended) | Low | The auth server supports RFC 8628; no local callback is needed. Also configure authDeviceFlow |
| Server-side token storage | Medium | You run your own auth service; the grant is stored on the server and status pulls it down locally |
auth command output requirements:
- Print a complete
https://auth URL on stdout or stderr, within 10 seconds; - The URL must be separated by whitespace on both sides and must not be wrapped in quotes or angle brackets, or it will be truncated;
- Do not wait for interactive input (the execution environment has no TTY), and do not open the browser yourself without printing the URL.
Timeout and evaluation rules per command:
| Command | Timeout | Evaluation and requirements |
|---|---|---|
| init | 5 minutes | Install may involve a large download; must support non-interactive execution |
| auth | 10 seconds | Only needs to print the auth URL; does not need to wait for the user to finish authorization |
| status | 10 seconds | Exit code 0 and output matching statusMatch means logged in; must be idempotent, side-effect-free, and read persisted state |
| unAuth | 30 seconds | Clears local credentials and the remote session; should also return successfully when the user is not logged in |
| Auth poll | 5 minutes | Runs status every 3 seconds; times out as a connection failure |
After a WorkBuddy restart, status is run automatically to restore the connection, but auth is not re-run. Therefore the CLI login state must survive process restarts.
Connector metadata
connector-meta.json registers the connector and supplies the name, description, and usage examples shown in the marketplace.
{
"name": "任务管理",
"name_zh": "任务管理",
"name_en": "Task Manager",
"description": "Create and manage tasks in WorkBuddy.",
"description_zh": "通过自然语言创建、查询和更新任务。",
"description_en": "Create, query, and update tasks with natural language.",
"source": "task-manager",
"type": "mcp",
"version": "1.0.0",
"examples_zh": ["创建一个明天下午到期的评审任务", "列出本周尚未完成的任务"],
"examples_en": [
"Create a review task due tomorrow afternoon",
"List unfinished tasks for this week"
]
}
| Field | Required | Minimum version | Description |
|---|---|---|---|
| name / name_en | Yes | Base | Default name and English name; you may also add name_zh |
| description / description_zh / description_en | Yes | Base | Briefly describe the core capability and when to use it; 20–100 characters recommended |
| source | Yes | Base | Globally unique identifier; lowercase letters, digits, and hyphens only |
| type | Optional | Base | mcp (default), cli, or skill-only; CLI integrations must set cli |
| version | Recommended | Base | Semantic version; increment on every update |
| examples_zh / examples_en | Yes | 4.24.0 | Chinese and English usage examples; 2–5 of each is recommended |
| auth_mode | As needed for MCP | Base | Omit, or use server-side, gateway, or token |
| minWorkbuddyVersion | Required when using new fields | 4.22.12 | Minimum WorkBuddy version required by the connector |
| maxWorkbuddyVersion | Optional | 4.22.12 | Maximum supported version; used for emergency disablement |
| name_map / description_map | Optional | 5.2.0 | Override name and description by environment or account type |
Names should be concise and recognizable. Descriptions should say what the user can accomplish. Examples should use natural language that users would actually say.
Display priority: for the name, name_map (when the environment matches) > name_zh > name_en > name. Description falls back the same way to description_zh, description_en, then description.
Version compatibility
Different WorkBuddy clients support different config fields. When you use newer fields you must declare minWorkbuddyVersion; otherwise older clients may fetch an incompatible config. If you use several new features at once, declare the highest version among them.
| Field or capability | Minimum version |
|---|---|
| type: skill-only; auth_mode: server-side; cli.json unAuth / statusMatch / authUrlDomain | Base |
| cli.json runtime / npmRegistry / env, authWaitForExit / authQrModal; auth_mode: gateway | 4.22.0 |
| cli.json authSuppressBrowser | 4.22.8 |
| minWorkbuddyVersion / maxWorkbuddyVersion | 4.22.12 |
| mcp.json cwd / disabledTools | 4.22.15 |
| auth_mode: token and token-schema.json | 4.23.0 |
| name_zh / name_en, examples_zh / examples_en, statusMatchJson / versionCheck / npmRegistries, multi-step auth array | 4.24.0 |
| cli.json authDeviceFlow and Python runtime; mcp.json preAuth / runtime / staticEnv / staticHeaders | 5.0.0 |
| name_map / description_map | 5.2.0 |
Clients below the declared version: the connector is hidden if the user has never enabled it; if it is already enabled or was connected before, it is grayed out and the user is prompted to upgrade.
Skill file
A Skill guides the AI to use the connector correctly. It is optional when MCP already provides standard tool descriptions, and strongly recommended for the CLI approach.
See Development — Skill on this site for the Skill directory and SKILL.md format. When there are many capabilities, split them into multiple Skills, each in its own subdirectory; WorkBuddy loads all of them. When writing a Skill, focus on:
- The purpose of each MCP Tool or CLI command;
- Parameter names, types, whether they are required, and default values;
- Typical call examples and return formats;
- Auth prerequisites, error scenarios, and how to recover;
- Confirmation rules required for high-risk operations.
Authentication and credentials
| Scenario | Integration method | Opens the browser |
|---|---|---|
| The MCP Server has built-in OAuth or needs no auth | Omit auth_mode and connect through the standard MCP flow | Opens when authorization is required |
| WorkBuddy cloud-hosted OAuth | Use server-side or gateway; confirm with the WorkBuddy team before integrating | Opens when authorization is required |
| The user fills in an Access Token / API Key | Use auth_mode: "token" and provide token-schema.json to describe the form | Does not open |
| CLI login | Manage through auth, status, and unAuth in cli.json; the CLI stores credentials securely itself | Depends on the CLI auth method |
Security requirements:
- Do not hard-code real tokens or secrets in connector-meta.json, mcp.json, cli.json, Skills, or examples;
- Request only the minimum permissions needed for the business;
- Use HTTPS for remote MCP;
- Sensitive credential fields should use a password type; never print full credentials in logs or error messages;
- When authorization expires, return a recognizable error and guide the user to reconnect.
MCP OAuth flow
When the MCP Server needs access to the user’s private data and uses OAuth, WorkBuddy’s built-in OAuth manager completes the client-side flow automatically. It uses OAuth 2.1 + PKCE and connects as a public client (it does not hold a client_secret). Developers only need to implement the server endpoints.
Overall flow: the first request without a token returns 401 → discover metadata → dynamic client registration → open the browser for authorization → verify state and exchange the token → call normally with a Bearer token.
| Endpoint | Method | Description |
|---|---|---|
| /.well-known/oauth-protected-resource | GET | Returns the resource URL and the authorization_servers list |
| /.well-known/oauth-authorization-server | GET | Returns the issuer, endpoint URLs, and supported scopes |
| /oauth/register | POST | Dynamic client registration (RFC 7591); must accept a public client and echo redirect_uris |
| /oauth/authorize | GET | Authorization endpoint; must support code_challenge_method: S256 |
| /oauth/token | POST | Verifies code_verifier and issues access_token and refresh_token; must support the refresh_token grant |
Server behavior requirements:
- PKCE (
S256) is required; authorization codes are single-use and valid for about 10 minutes; - redirect_uri must match as an exact string. Prefer the WorkBuddy private-scheme callback
workbuddy://workbuddy/mcp/connector%3A<source>/oauth/callback; - If the platform only allows HTTP/HTTPS callbacks, allow the loopback address
http://127.0.0.1:{dynamicPort}/oauth/callback. WorkBuddy will automatically fall back once if the private scheme is rejected; - The dynamic registration response must echo redirect_uris in addition to client_id; otherwise the rest of the flow cannot continue;
- access_token lifetime of 1 hour is recommended; refresh_token of at least 30 days is recommended. After expiry, WorkBuddy guides the user to re-authorize;
- All OAuth server endpoints must use HTTPS and follow the OAuth 2.1 standard error format.
When access_token expires, WorkBuddy automatically renews it with refresh_token and retries the original request. This is transparent to the user.
User-supplied token mode
When the third-party service does not provide OAuth and only offers a Personal Access Token or API Key, or when the user must specify a private-deployment URL, use auth_mode: "token". WorkBuddy shows a form to collect credentials. Credentials are stored only on the user’s machine and injected at connect time; they never go through the cloud, and the browser is not opened. This mode requires minWorkbuddyVersion of at least 4.23.0.
This mode also requires token-schema.json to describe the form fields, and ${VAR} placeholders in mcp.json. Placeholder names must match the form field keys exactly (case-sensitive):
| MCP transport | Where credentials are injected | Typical syntax |
|---|---|---|
| stdio | env (environment variables) | "env": { "API_KEY": "${API_KEY}" } |
| sse / streamableHttp | headers or url | "Authorization": "Bearer ${API_KEY}" |
token-schema.json example:
{
"title": "服务对接配置",
"title_en": "Service Configuration",
"description": "连接您的账号以调用服务。凭证仅存储在本机 ~/.workbuddy 目录下。",
"description_en": "Connect your account. Credentials are stored locally only.",
"docUrl": "https://example.com/docs/api-token",
"docLabel": "如何获取 Access Token?",
"fields": [
{
"key": "API_KEY",
"label": "Access Token",
"type": "password",
"required": true,
"placeholder": "在个人中心 → 开放平台 → API 中生成",
"description": "用于访问服务 OpenAPI 的个人访问令牌。"
},
{
"key": "API_BASE_URL",
"label": "API 基础地址",
"label_en": "API Base URL",
"type": "text",
"required": true,
"defaultValue": "https://api.example.com",
"description": "私有部署可改为内网地址。"
}
]
}
| Field | Required | Description |
|---|---|---|
| title | Yes | Form title |
| description | Yes | Form description; stating where credentials are stored is recommended to reduce user concern |
| docUrl / docLabel | Optional | Link to the credential-obtaining docs and its display label; rendered as a clickable link in the form |
| fields | Yes | Field list; at least one item |
| fields[].key | Yes | Field key; must match the ${VAR} name in mcp.json, case-sensitive |
| fields[].label | Yes | Input label |
| fields[].type | Yes | text or password; always use password for sensitive credentials |
| fields[].required | Yes | Whether the field is required; the form blocks submit when it is empty |
| fields[].placeholder | Optional | Placeholder hint; pointing to the credential path or an example value is recommended |
| fields[].defaultValue | Optional | Initial value the user can change; recommended for Base URL fields |
| fields[].description | Optional | Helper text below the field |
Multilingual copy is provided through parallel fields with an _en suffix, such as title_en and label_en. The original fields must remain strings and must not be changed into objects, or older clients will fail to render them.
If the same service needs to offer both OAuth and token methods, submit them as two independent connectors with different source values.
Icon requirements
| Item | Requirement |
|---|---|
| Format | SVG (recommended), PNG, or JPG |
| File name | icon.svg, icon.png, or icon.jpg |
| Size | 64×64 px recommended for PNG/JPG |
| Background | Transparent recommended |
| Style | Simple and clear; recognizable at small sizes |
Pre-submit checklist
- You have chosen MCP or CLI integration, and the directory structure follows the spec;
- source uses kebab-case and stays globally unique;
- Connector name, description, and Chinese/English examples are complete;
- MCP configures only one Server, and remote URLs use HTTPS;
- Or the CLI has been verified for install, auth, status check, logout, and cross-platform behavior;
- For the CLI approach, login state survives restart and unAuth correctly clears authorization;
- When OAuth is involved, metadata discovery, dynamic registration, and PKCE verification are implemented, and the agreed callback URLs are accepted;
- For user-supplied token mode,
${VAR}placeholders match form field keys one-to-one, and sensitive fields use the password type; - The Skill accurately guides the AI to call all core capabilities;
- No real credentials are written in any file;
- The icon is clear, and the version plus minimum WorkBuddy version are declared correctly;
- Common failures such as timeouts, expired authorization, and invalid parameters are covered.
When you are ready, package the connector directory and submit it to the WorkBuddy team for review. After approval, the connector will appear in the Connector Marketplace. Later updates only need to be resubmitted for review and typically take effect within 10–15 minutes.
