--- name: add-mcp-from-catalog description: Add a reviewed MCP Catalogue server to an explicit AICP project through the Speakeasy AI Control Plane Platform MCP. --- # Add an MCP from the catalog Use this workflow only through the authenticated Speakeasy AI Control Plane (AICP) Platform MCP. It follows the same guarded outcome a user would complete manually in the AICP dashboard: select a reviewed MCP, configure it for an explicit project, finish secure setup, and verify readiness. The package itself grants no organization access. If the user instead supplies a remote MCP URL outside the reviewed catalogue, use the `add-mcp-from-remote-url` workflow. ## Safety rules - Never ask the user to paste API keys, passwords, access or refresh tokens, OAuth codes, client secrets, secret headers, or MCP credentials into chat. - Never ask the user to supply an MCP endpoint. Use the server-owned catalog candidate and registration workflow. - Show non-secret provider and setup URLs only when a Platform MCP tool returns them. - Keep the chosen project and catalog candidate explicit. Do not infer either from a previous conversation or silently substitute another target. - Registration is private and does not distribute or publish the MCP. - Use `send_platform_mcp_feedback` only after asking for consent, and never include identifiers, URLs, credentials, payloads, headers, logs, or attachments. ## Workflow 1. Call `list_projects` to verify that the Platform MCP is authenticated and obtain the eligible projects. If authenticated discovery is unavailable, stop and ask the user to complete or repair AICP OAuth; do not claim that installation succeeded. 2. Call `search_mcp_catalog`. Present the eligible projects and reviewed candidates, then ask the user to choose one exact candidate and one exact project. Only when `create_project` is in your tool list may you also offer a new project if no listed project fits, or none exists yet; do not create it yet. A managed project assistant has no `create_project` tool and always registers in its own project, so never offer it there. 3. Call `inspect_mcp_candidate` for the selected candidate. Explain the bounded change and collect only the non-secret configuration fields declared by that result. 4. If the user chose a new project and still wants this candidate after inspection, agree the project's exact name and choose one idempotency key for this create; pass that same key on the preview and on the confirmed call. Call `create_project` with that name, that key, and `confirmed: false` to preview it: nothing is created, and the `confirmation_required` result returns the exact slug the project would get. Do not work the slug out yourself. Show that slug to the user as the project's permanent address in dashboard links; it does not change on rename. After the user confirms the name and slug, call `create_project` again with the same name, the same key, and `confirmed: true`. Use the project it returns; it starts empty. Use a fresh key only for a new attempt after a refusal. A `conflict` refusal means a project already holds that slug and nothing was created: offer that existing project or a different name. Creating a project needs organization administrator access; if it is refused, say so rather than choosing another project. Then, after explicit confirmation of the exact project, candidate, and configuration, call `register_catalog_mcp` with the exact selected project, reviewed candidate, declared non-secret configuration, and a fresh idempotency key. Do not distribute it. 5. Call `get_mcp_readiness` with the returned project and registration ID to inspect persisted readiness. 6. Route secure setup from the exact readiness evidence: - For `upstream_identity_provider_not_configured`, explain that AICP can attach the one identity provider discovered from the persisted reviewed MCP source. Ask for explicit confirmation, then call `attach_platform_mcp_identity_provider`, present its exact Inspect authorization URL, and wait for the user to use Connect or Authorize. - For `upstream_authorization_required`, call `attach_platform_mcp_identity_provider` again with confirmation to retrieve the current server-issued Inspect authorization URL. Present that exact clickable URL and wait for the user to use Connect or Authorize. - For any other secure dashboard setup result, present only its exact server-returned setup URL. The user completes OAuth or secret entry outside the agent. Never request the resulting code, token, or secret in chat. 7. After the user completes any secure handoff, branch by caller surface: - For a connected external Platform MCP client, call `get_mcp_readiness` with `force: true`. Do not rely on stale or inferred readiness. - For a managed project assistant, call `get_mcp_readiness` without `force` and report only the persisted actor-scoped evidence. A forced provider probe stays with connected external clients; identity-provider attachment does not. 8. When readiness is current and ready, report the server-returned evidence. Registration is still private at this point: an MCP takes effect only once a plugin carries it. 9. Call `get_mcp_client_admission` for the same project and registration ID and report the mode it returns together with the custom client ID metadata URLs it lists, which together decide which MCP clients may authorize against this server. Change it only when the user asks: explain what the proposed mode admits and refuses, ask for explicit confirmation, then call `set_mcp_client_admission` with that exact mode and `confirmed: true`. Known clients (`presets`) refuses an unlisted client at authorization with no fallback, so confirm the user accepts that before selecting it. Custom client ID metadata URLs are still added from the MCP server's Authentication settings in the AICP dashboard. 10. Call `list_plugins` for the selected project, present the plugins it returns, and ask the user which one should carry this MCP. Do not choose for them and do not assume the default plugin. Only when `create_plugin` is in your tool list may you offer a new plugin if no listed plugin fits. A managed project assistant has no `create_plugin` tool, so never offer or call it there: if no listed plugin fits, ask the user to create the plugin in the AICP dashboard or from an external MCP client, then call `list_plugins` again and continue with the plugin they created. If the user wants a new plugin and `create_plugin` is available, agree its name (and a slug only if they want to choose one), choose one idempotency key for this create, and call `create_plugin` for the selected project with that key and `confirmed: false`. Nothing is created and no receipt is stored; the `confirmation_required` refusal carries the exact `slug` the plugin would get. Show the user that slug as the plugin's permanent install name, which does not change on rename; never work a slug out yourself. Say that in the organization's default project a new plugin reaches every member, while elsewhere it reaches no one until people are assigned to it. After they confirm the name and slug, call `create_plugin` again with the same name, slug and description, the same idempotency key, and `confirmed: true`, and use the plugin it returns. If it refuses with `slug_taken`, another plugin already holds that slug: call `list_plugins` again, then ask whether to use that existing plugin or create one with a different slug, and preview and confirm the new slug as a new create, with a fresh idempotency key used for both its calls. If it refuses with `idempotency_key_reused`, the key was already spent on a different request: repeat the original request exactly with its original key, and use a new key only for a request the user has newly confirmed. If it refuses with `feature_unavailable`, creating a plugin is not available on this server: report that, stop creating, and do not retry or substitute another plugin. Instead ask the user to create the plugin in the AICP dashboard or from an external MCP client, then call `list_plugins` again and continue with the plugin they created. Never treat any of these refusals as having created a plugin. 11. After the user names a plugin, call `distribute_mcp_to_plugin` with that exact plugin. A name matching nothing is refused as `not_found` and a name matching more than one as `ambiguous_target`; report the refusal and ask again rather than retrying with a different plugin, creating a plugin the user did not ask for, or distributing to another project. OAuth consent and approved secret entry are the expected out-of-agent stops. Project and catalog selection and identity-provider attachment confirmation stay in the conversation.