Docs
MCP

Set up MCP

Expose Convoy tasks and project context to MCP-aware AI clients.

Convoy ships an MCP (Model Context Protocol) server, so AI clients like Claude Code, Codex, and OpenCode can read and write your tasks directly from the editor — project-scoped task lookup and search, comments, artifacts, and task creation/updates. The full catalog is in the MCP tools reference.

MCP does not require convoy connect — it is independent of live thread execution. You only need a saved profile and an API key.

Connect with OAuth (Claude Code)

The fastest path for clients with OAuth support — no API key handling at all:

claude mcp add --transport http convoy \
  "https://<DEPLOYMENT>.convex.site/api/mcp?project=<ORG_SLUG>/<PROJECT_ALIAS>"

Then run /mcp in Claude Code and follow the browser flow: sign in to Convoy, click Approve, done. The client receives its own API key automatically (visible under your account's API keys as MCP (Claude Code)); when it expires, /mcp re-authenticates with one click.

Clients without OAuth support (e.g. Codex) use the header-based configuration below.

Prerequisites

Generate the config

From the repository or workspace you want the client to operate on:

convoy init mcp                # both targets
convoy init mcp --cli claude   # writes .mcp.json
convoy init mcp --cli codex    # writes .codex/config.toml
convoy init mcp --cli opencode # writes opencode.json

Useful flags:

  • --output-dir <path> — write config somewhere other than the current directory
  • --force — overwrite existing config without prompting (otherwise Convoy asks first)

Verify

  1. Restart the client so it picks up the new config.
  2. Open the repo that now contains the config.
  3. Ask the client to list or search tasks — a working setup returns project-scoped results.

If nothing shows up, check that the generated config file exists at the expected path, the profile points at the correct project, and the API key is valid. See MCP troubleshooting for the longer symptom list.

Manual OpenCode configuration

To configure OpenCode by hand instead of using init, add the server to opencode.json in the project folder (replace the URL with your deployment's and the token with your API key):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "convoy": {
      "type": "remote",
      "url": "https://your-deployment.convex.site/api/mcp?project=acme/WEB",
      "headers": { "Authorization": "Bearer sk_user_..." },
      "oauth": false
    }
  }
}

opencode.json contains your API key — add it to .gitignore.

Manual Codex configuration

To configure Codex by hand instead of using init, create .codex/config.toml in the project folder. Replace the URL with your Convex backend URL and project scope, and the bearer token with an API key from Convoy user settings:

[mcp_servers.convoy]
url = "https://<DEPLOYMENT>.convex.site/api/mcp?project=<ORG_SLUG>/<PROJECT_ALIAS>"

[mcp_servers.convoy.http_headers]
Authorization = "Bearer <YOUR_API_KEY>"

The API key popup in Convoy fills in the backend URL at runtime; opened from a project route, it also scopes the URL with ?project=<ORG>/<ALIAS>.

You can also open the project header gear menu and choose Configure MCP to copy project-scoped .mcp.json and .codex/config.toml snippets for the current project.

Optional per-tool approvals

Add approval_mode = "approve" blocks only for the Convoy tools you want Codex to run without asking each time:

[mcp_servers.convoy.tools.list_projects]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_task_types]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_task_lists]
approval_mode = "approve"

[mcp_servers.convoy.tools.create_task_list]
approval_mode = "approve"

[mcp_servers.convoy.tools.update_task_list]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_task_labels]
approval_mode = "approve"

[mcp_servers.convoy.tools.create_task_label]
approval_mode = "approve"

[mcp_servers.convoy.tools.update_task_label]
approval_mode = "approve"

[mcp_servers.convoy.tools.delete_task_label]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_project_agents]
approval_mode = "approve"

[mcp_servers.convoy.tools.create_project_agent]
approval_mode = "approve"

[mcp_servers.convoy.tools.update_project_agent]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_prompts]
approval_mode = "approve"

[mcp_servers.convoy.tools.create_prompt]
approval_mode = "approve"

[mcp_servers.convoy.tools.update_prompt]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_skills]
approval_mode = "approve"

[mcp_servers.convoy.tools.get_skill]
approval_mode = "approve"

[mcp_servers.convoy.tools.create_skill]
approval_mode = "approve"

[mcp_servers.convoy.tools.update_skill]
approval_mode = "approve"

[mcp_servers.convoy.tools.delete_skill]
approval_mode = "approve"

[mcp_servers.convoy.tools.load_skill]
approval_mode = "approve"

[mcp_servers.convoy.tools.read_skill_file]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_tasks]
approval_mode = "approve"

[mcp_servers.convoy.tools.search_tasks]
approval_mode = "approve"

[mcp_servers.convoy.tools.get_task]
approval_mode = "approve"

[mcp_servers.convoy.tools.get_tasks]
approval_mode = "approve"

[mcp_servers.convoy.tools.create_task]
approval_mode = "approve"

[mcp_servers.convoy.tools.create_task_comment]
approval_mode = "approve"

[mcp_servers.convoy.tools.update_task]
approval_mode = "approve"

[mcp_servers.convoy.tools.update_task_link]
approval_mode = "approve"

[mcp_servers.convoy.tools.move_task]
approval_mode = "approve"

[mcp_servers.convoy.tools.move_tasks_to_list]
approval_mode = "approve"

[mcp_servers.convoy.tools.delete_task]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_task_artifacts]
approval_mode = "approve"

[mcp_servers.convoy.tools.get_task_artifact]
approval_mode = "approve"

[mcp_servers.convoy.tools.create_task_artifact]
approval_mode = "approve"

[mcp_servers.convoy.tools.update_task_artifact]
approval_mode = "approve"

[mcp_servers.convoy.tools.replace_in_task_artifact]
approval_mode = "approve"

[mcp_servers.convoy.tools.move_task_artifact]
approval_mode = "approve"

[mcp_servers.convoy.tools.delete_task_artifact]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_artifact_comments]
approval_mode = "approve"

[mcp_servers.convoy.tools.create_artifact_comment]
approval_mode = "approve"

[mcp_servers.convoy.tools.reply_to_artifact_comment]
approval_mode = "approve"

[mcp_servers.convoy.tools.set_artifact_comment_status]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_cli_profiles]
approval_mode = "approve"

[mcp_servers.convoy.tools.get_thread]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_threads]
approval_mode = "approve"

[mcp_servers.convoy.tools.list_thread_messages]
approval_mode = "approve"

[mcp_servers.convoy.tools.create_thread]
approval_mode = "approve"

[mcp_servers.convoy.tools.send_thread_message]
approval_mode = "approve"

Tool names must match the server catalog exactly — when tools are added or renamed, regenerate or update this list.

Codex executes MCP tools today, but Codex thread execution is not yet implemented — see the Roadmap.

Project vs. user scope

Think about config scope before writing files:

  • use project scope when the config should travel with the repo — preferred for shared team repos
  • use user scope when the config is machine-specific

Generated config embeds your API key. Before committing project-scoped config, verify the file is ignored by version control or strip the key — see the Security model.

Next steps

On this page