Skip to content

MCP Servers

Canopy ships two distinct MCP (Model Context Protocol) servers - one for Host, one for Cortex - each with its own tool set. There is also a third, unrelated concept (“hosted MCP servers”) that reuses the “MCP” name but is a marketplace feature, not a server you connect an MCP client to. This page covers all three, kept clearly separate.

Host’s MCP server

Package canopy-host-mcp (host/mcp/), built on mcp.server.fastmcp.FastMCP. Exposes read/write tools over the Canopy Host API for coding agents and MCP clients (Claude Desktop, Claude Code, etc.).

Connecting

  • Transport: stdio by default (CANOPY_HOST_MCP_TRANSPORT), or streamable-http/SSE.
  • CANOPY_HOST_API_URL (default https://api.canopy.pm) + CANOPY_HOST_API_KEY - the server calls the Host API on your behalf using this key.
  • Alternatively, connect with OAuth 2.1: Canopy self-hosts an authorization server at auth.canopy.pm (Ory Hydra). A client that supports OAuth/DCR (Claude Code, Claude.ai, ChatGPT, Codex) discovers it automatically and authorizes through your Canopy account - no API key to copy around. Either way you end up with a bearer token scoped to your own account; there’s no third, separate MCP-level credential.
  • Public URL: https://mcp.canopy.pm, health check at https://mcp.canopy.pm/mcp/health (always reachable, reports host_mcp_hosting_feature_enabled, tool_count, and the live tool list).

Example stdio client config:

{
"mcpServers": {
"canopy-host": {
"command": "canopy-host-mcp",
"env": { "CANOPY_HOST_API_KEY": "your-api-key" }
}
}
}

Feature-gated: the whole tool set is gated behind the host.mcp.hosting platform feature. If it resolves disabled, zero tools are registered (the server stays up, tools/list is just empty) - see Platform Features.

Tools

ToolParamsWhat it does
host_list_projectslimit?, cursor?List projects, paginated (25/page by default)
host_get_projectproject_idLook up one project
host_get_environmentenvironment_idFetch an environment
host_get_environment_variablesenvironment_idList its variables (values masked - a value_preview only)
host_reveal_environment_variableenvironment_id, nameReal plaintext value of ONE named variable (requires confirmation in clients that support it)
host_get_environment_domainsenvironment_idList its domains
host_get_environment_runtime_logsenvironment_id, lines?, process?Snapshot of the app’s own stdout/stderr (preview)
host_create_environmentproject_id, branch?, repository?, build_path?, build_command?, template_id?, parent_environment_id?, name?, migrate_command?, image?Create an environment (image creates one from an OCI image and starts its first deploy)
host_update_environmentenvironment_id, build_path?, build_command?, migrate_command?, health_mode?, backup_consistency?, predeploy_backup?Update build config, how the app is health-checked, how backups treat volumes, and whether a backup runs before an image change
host_list_buildsenvironment_id, page=1List builds
host_get_buildenvironment_id, build_idFetch one build
host_trigger_deployenvironment_id, no_cache?, no_reuse?, image?Trigger a deploy (image moves an image environment to a new reference)
host_rollbackenvironment_id, build_idRoll back to a build
host_cancel_buildenvironment_id, build_idCancel a running build
host_deploy_approvalenvironment_id, build_id, actionApprove/reject a gated deploy
host_deploy_unlockenvironment_id, force?Release a stuck Dokku deploy lock (Dokku-hosted only)
host_set_variablesenvironment_id, variablesBulk-set env vars
host_add_domainenvironment_id, domainAdd a custom domain
host_list_previewsenvironment_id, include_destroyed?List a source environment’s PR preview environments (read-only)
host_get_previewenvironment_id, preview_idOne preview with its workload phase and databases (read-only)
host_destroy_previewenvironment_id, preview_idTear a preview down (destructive, idempotent)
host_list_backupsenvironment_idList an environment’s database backups (read-only)
host_get_backupenvironment_id, backup_idOne backup’s status and metadata (read-only)
host_create_backupenvironment_idTake a manual backup (rate limited; restore is not a tool)
host_get_restore_statusenvironment_id, restore_idStatus of a backup restore (read-only)
host_get_environment_databaseenvironment_idThe environment’s primary database, no connection details (read-only)
host_list_environment_storageenvironment_idPersistent storage mounts (read-only)
host_list_volumesenvironment_idPersistent volumes of a Forest environment: mount path, size, status, retention (read-only)
host_create_volumeenvironment_id, name, mount_path, size_gb?, process?, retention_days?, apply?Create a persistent volume; redeploys the current artifact once unless apply is false
host_detach_volumeenvironment_id, volume_idDetach a volume and keep its data for the retention period (permanent deletion is CLI-only)
host_attach_volumeenvironment_id, volume_idMount a detached volume again
host_list_adoptable_volumesenvironment_idDetached volumes of the project this environment can mount (read-only)
host_adopt_volumeenvironment_id, volume_id, mount_path, name?, process?, apply?Mount a detached volume with its data intact
host_get_destroy_planenvironment_idWhat deleting an environment would affect and the retain/delete choices (read-only; deleting is CLI-only)
host_check_environmentenvironment_idCheck whether an environment can be deployed without deploying it: image, user, port, volumes, replicas, variables, domains, health (read-only)
host_get_environment_stateenvironment_idOne page of health: rollout, restarts and why, volumes, routes, last backup, failing crons, problems (read-only)
host_list_environment_jobsenvironment_id, kind?, limit?Scheduled commands with next run and recent runs, or recorded one-off and release-task runs (read-only)
host_get_environment_configenvironment_idThe .canopy.yml document the environment deploys with (read-only)
host_list_config_revisionsenvironment_idRecorded configuration revisions, newest first (read-only)
host_set_environment_configenvironment_id, content, apply?Record a new configuration revision and redeploy with it unless apply is false
host_get_environment_language_settingsenvironment_id, revision?PREVIEW: the languages detected in an environment’s source and the build settings they unlock (read-only)
host_set_environment_language_settingsenvironment_id, settingsPREVIEW: set language build settings (true/false, null resets); applies on the next build
host_analyze_environment_languagesenvironment_idPREVIEW: queue a fresh language analysis of the current source revision
host_list_team_rolesteam_idA team’s custom roles and their actions (read-only, preview API)
host_get_team_roleteam_id, role_idOne custom role (read-only)
host_list_alert_rulesteam_idA team’s alert rules, without webhook URLs (read-only)
host_list_alert_eventsteam_idA team’s recent alert events (read-only)
host_list_team_imagesteam_id, limit?Docker images a team pushed to the registry, with each tag’s digest-pinned ref (read-only)
host_list_api_keysThe caller’s API keys, never key material (read-only)
host_start_jobteam_id, purpose, image_ref, command, timeout_seconds?, memory_mb?, cpus?, egress?Start an ephemeral isolated job and return at once
host_get_jobjob_idA job’s state, exit code and output once finished (read-only)
host_list_jobsteam_id, limit?A team’s recent jobs (read-only)
host_get_job_eventsjob_id, after?A job’s lifecycle events (read-only)
host_cancel_jobjob_idCancel a job that has not started running
host_deploy_and_waitenvironment_id, poll_interval_seconds?, poll_timeout_seconds?Deploy, then poll to terminal status
host_artifact_lineageteam_id, digest? or commit?, include_impact?Trace an artifact’s lineage
host_artifact_passportartifact_idFetch an artifact’s passport ({available: false} if not generated yet)
host_release_and_promoteproject_id, source_environment_id, target_environment_id, version, build_id?, notes?, ...Full release → promote → approve → poll chain
host_catalog_searchteam_id, q?Search the workflow marketplace
host_catalog_installteam_id, workflow_id, granted_permissionsInstall a workflow
host_catalog_runteam_id, installation_idRun an installed workflow
host_environment_recommendationsenvironment_idRead-only rightsizing recommendations
host_compliance_statusteam_idList compliance evidence packages
host_compliance_packageteam_id, package_idFetch one package
host_environment_residencyenvironment_idResidency attestations for an environment
host_artifact_residencyartifact_idResidency attestations for an artifact
host_list_ci_connectionsteam_idList Canopy Connect connections
host_list_ci_pipelinesconnection_idList pipelines for a connection
host_list_ci_runspipeline_idList runs for a pipeline
host_get_ci_runrun_idFetch a run + its jobs
host_explain_ci_failurerun_idFailed jobs only, with failure excerpts (deterministic, no model call)
host_import_ci_connectionconnection_idImport an existing CI connection
host_get_timelineenvironment_idUnified build + CI-run timeline
host_cost_summaryteam_id, since?, until?Cost summary
host_cost_anomaliesteam_id, threshold_pct?Spend anomalies
host_budgetsteam_idList budgets
host_pipeline_get_graphgraph_idFetch a pipeline graph (preview)
host_pipeline_get_plangraph_idFetch a pipeline’s execution plan (preview)
host_pipeline_get_run_statusgraph_idFetch a pipeline run’s status (preview)
host_pipeline_diff_graphsgraph_id, against_graph_idDiff two pipeline graphs (preview)
host_pipeline_simulategraph_id, ...Simulate a pipeline run (preview)
host_pipeline_validategraph_id, ...Validate a pipeline graph (preview)
host_pipeline_detect_dead_stepsgraph_idFind unreachable/dead steps (preview)
host_pipeline_suggest_parallelgraph_idSuggest steps safe to parallelize (preview)
host_list_runnersteam_idList enrolled BYOC runners
host_runner_diagnoseteam_idDiagnose a team’s runner health
host_graph_noderefFetch one engineering-graph node (preview)
host_graph_edgesref, depth?Traverse graph edges (depth clamped 0-3) (preview)
host_graph_commitshaCorrelate a commit across the graph (preview)
host_graph_kinds-List engineering-graph node kinds (preview)
host_graph_dependenciesrefList a node’s dependencies (preview)
host_graph_impactrefBlast-radius/impact analysis for a node (preview)
host_graph_eventsref, ...Events associated with a node (preview)
host_graph_release_live_atenvironment_id, at?What was live on an environment at a point in time (preview)
host_space_searchspace_id, query, kinds?Search within a Space, Host-only (preview)
host_deploy_spacespace_idDeploy a Space (preview)
host_get_space_deployspace_id, space_deploy_idFetch a Space deploy’s status (preview)
host_list_teams-List teams
host_list_templates-List templates
host_get_account-Current user
host_get_plan-Current billing plan
host_audit_searchteam_id, event_type?Search the audit event ledger
host_list_webhooksenvironment_idList git provider webhooks for an environment’s repository
host_create_webhookenvironment_idRegister a webhook, if one isn’t already (idempotent)
host_secure_webhookenvironment_idGenerate/rotate the webhook signing secret
host_delete_webhookenvironment_id, hook_idDelete one provider webhook by id (from host_list_webhooks)
host_observability_status-Unresolved findings from every platform detection sweep (staff-only, read-only)
host_list_groves-List every enrolled Forest Grove (staff-only)
host_grove_build_jobsgrove_id, status?, build_id?, limit?, offset?A Grove’s build-dispatch jobs (staff-only)
host_grove_workloadsgrove_idA Grove’s raw workloads rows, incl. sync_cursor (staff-only)
host_migrate_planenvironment_idAudit a Dokku environment’s Forest-migration readiness (staff-only, read-only)
host_migrate_executeenvironment_id, plan_id, confirm?Advance a Dokku-to-Forest migration (staff-only)
host_migrate_abortenvironment_idRoll back an in-progress migration, unfreeze deploys (staff-only)
host_pipeline_graphs_reapbuild_id?, environment_id?, commit?, confirm?Delete stale pipeline_graphs row(s) by build, or by environment and commit (staff-only)
host_admin_set_team_feature_opt_infeature_key, team_id, opted_in, reasonOpt a team in to or out of a preview platform feature (staff-only)
host_pipeline_images_auditimagesIs each pinned image digest reachable from the platform registry and every active build Grove’s own registry? (staff-only, read-only)

Deliberately not exposed: reporting a CI run (that’s a CI credential’s job via canopy ci report, not something an agent should do on a user’s behalf) - see host_explain_ci_failure/host_get_ci_run for the read-only equivalent.

Cortex’s MCP server

Package cortex-mcp (cortex/mcp/), a separate process with its own tool set for Cortex’s knowledge/RAG/training/agent-run surfaces.

Connecting

  • Transport: stdio, streamable-http, or sse (CORTEX_MCP_TRANSPORT).
  • Stronger auth than Host’s server for HTTP transports: set CORTEX_MCP_REQUIRE_BEARER_AUTH=true and CORTEX_MCP_BEARER_TOKEN to require Authorization: Bearer <token> on every request (not enforced over stdio, which has no HTTP headers).
  • CORTEX_API_URL (default http://localhost:8082) + CORTEX_API_KEY - used to call the Cortex API on your behalf.
  • Scoping defaults: CORTEX_MCP_DEFAULT_PRODUCT_INSTANCE_ID, CORTEX_MCP_DEFAULT_TENANT_ID, CORTEX_MCP_DEFAULT_EXTERNAL_USER_ID.
  • Public URL: https://mcp.canopy.pm, health at https://mcp.canopy.pm/mcp/health.

Feature-gated: cortex.mcp (visibility: internal) - only a master-type Cortex API key gets a definitive resolution; anything else fails open (tools stay registered).

Tools

ToolParamsWhat it does
cortex_list_knowledge_bases-List active knowledge spaces
cortex_create_knowledge_basename, slug, scope_type?, product_instance_id?, description?Create a knowledge space
cortex_retrievequery, knowledge_space_id?, knowledge_space_slug?, product_instance_id?, top_k?Hybrid search, returns ranked chunks with source refs
cortex_askquestion, knowledge_space_id?, ..., assistant_id?, top_k?, max_new_tokens?, temperature?, top_p?RAG Q&A with citations
cortex_list_projectsname?, external_tenant_id?, product_instance_id?List tenants/projects
cortex_list_documentstenant_id?, tenant_external_id?, scope?, include_archived?, limit?List ingested documents
cortex_get_context-List available knowledge bases (call first in a session)
cortex_ask_codebasequestion, external_user_id?, top_k?RAG over Cortex’s own ingested codebase (needs scripts/ingest_codebase.py run first)
cortex_remembercontent, user_id?, agent_id?Store a persistent memory
cortex_recallquery, user_id?, agent_id?, top_k?Search persistent memories
cortex_ingest_and_waitcontent, name, path?, library_path?, product_instance_id?, poll_interval_seconds?, poll_timeout_seconds?Submit text/markdown for ingestion, poll to completion
cortex_training_run_createname, base_model_name, product_instance_id?, knowledge_space_id?, dataset_id?Create a pending training run
cortex_training_run_list-List training runs
cortex_training_run_launchtraining_run_idStart a pending run
cortex_training_run_canceltraining_run_idCancel a run
cortex_training_run_statustraining_run_idStatus/loss metrics/error
cortex_agent_run_statusrun_idRead-only status/steps/chat history for an agent run (404 if the CORTEX_FEATURE_AGENT_RUNS flag is off)

Hosted MCP servers (marketplace)

canopy mcp (CLI) and sdk.mcpHosting (SDK) are not a way to connect to either server above - they’re a Canopy Host feature that lets a team publish and run their own MCP-shaped tool server on Canopy’s infrastructure, then invoke its tools over a plain REST endpoint:

canopy mcp create <name> --namespace <id> --slug <slug>
canopy mcp publish <server_id> --version <v> --artifact <id> --tools-json <json>
canopy mcp start <server_id>
canopy mcp invoke <server_id> <tool_name>

canopy mcp install <namespace>/<slug> --team <id> prints the invoke endpoint: POST {api_url}/teams/{team_id}/mcp/by-slug/{namespace}/{slug}/invoke with Authorization: Bearer <Canopy API key> and body {"tool_name": "<name>"}. This is a REST tool-invocation endpoint, not full MCP-protocol (JSON-RPC/SSE) wire compatibility - don’t point a generic MCP client at it expecting the standard handshake.

This feature is gated behind host.mcp.hosting, lifecycle: preview - see Platform Features.