Add existing MCP servers
Add selected supported remote servers to a Speakeasy AI Control Plane (AICP) project without editing local client configuration. Installation grants no access; live authentication, entitlement, membership and administrator checks remain authoritative. All management mutations use authenticated Platform MCP tools, never direct backend APIs.
1. Verify access and request discovery permission
Before any local discovery (including asking for manual inventory), successfully call list_projects with limit: 100 through your OWN Speakeasy connection in this Claude Code session. Dashboard state, install intent, another client's authentication, or a prior session's result is not proof of access. It accepts only limit (capped at 100), not cursor or search. If unavailable or denied, stop and offer the normal Speakeasy sign-in/setup flow. If truncated: true, project discovery is incomplete: stop and hand off project selection to the AICP dashboard rather than inventing pagination or guessing a destination.
Before running claude mcp list locally, obtain explicit permission. Require explicit informed consent for the following effects, not merely permission to view a list. Explain that it health-checks approved/enabled servers, can launch stdio processes and contact local/private-network endpoints BEFORE filtering out unsupported entries. Those processes may write files or contact services; do not promise zero process side effects or passive/read-only discovery. Approval of a server in Claude is not consent to run this discovery now. Explain the scope: current CLI user, working directory and configuration scope, not every client, account or workspace. Connection status does not establish remote importability.
Offer a user-sanitized manual inventory instead (non-secret alias, safe endpoint, transport only), without running discovery, if the user declines those effects or local execution is unavailable. Never demand raw output. Do not inspect credential files, expand environment values, or forward raw output to any tool, service or report. Do not invent a no-connect flag. Never edit local configuration, approval settings or credentials to enable discovery. The no-edit rule constrains the agent; it cannot guarantee that the CLI or launched servers have no side effects.
If discovery succeeds but returns no entries, report that no servers were found in the inspected scope. Offer a user-sanitized manual inventory or the normal catalogue path (add-mcp-from-catalog) as explicit next choices; do not switch workflows without the user's choice. Do not claim import completion for an empty inventory.
2. Sanitize and classify locally
Retain only non-secret alias, exact safe endpoint, declared transport and provenance needed for selection. Never copy local credentials, including headers, tokens, passwords, environment secrets or OAuth state. Do not request secrets in chat.
Only public HTTPS Streamable HTTP endpoints are candidates. Exclude stdio commands, localhost/loopback, private-network or link-local endpoints, unsupported transports (including legacy SSE), fragments, embedded credentials, credential-like query parameters and uncertain URLs. Safe non-secret endpoint query parameters can be meaningful; preserve them. Never manufacture a safe URL by silently stripping credentials or changing its path. Block the entire uncertain item and ask for secure/manual resolution; do not echo sensitive URL components. Server validation remains authoritative, including network safety checks.
Exclude the connected Speakeasy management endpoint itself to prevent recursive import. Establish its identity from trusted connection endpoint metadata or other exact endpoint evidence, not display name alone. If that evidence is unavailable or ambiguous, flag the possible self-reference for manual resolution rather than importing it.
3. Confirm selection and check live inventory
Present sanitized candidates and blocked items. Confirm candidate selection and destination from the eligible projects returned above; keep that project's ID and slug paired. Never infer the destination from a local alias or the Default project.
Use find_mcp with the selected project_id and limit: 100, no query or readiness filter. Follow every next_cursor using cursor with the same project until exhausted. Never combine query and cursor; a name search is not an exhaustive inventory. If listing fails or pagination cannot finish, do not conclude a candidate is missing.
Use get_mcp with project_id and returned mcp_id to inspect possible matches. Compare exact upstream URL and server-issued source/registration evidence. Deduplicate aliases only by proven identity, not hostname or display name: different paths or meaningful query values may represent different servers. Preserve the alias-to-item mapping for the final report. If identity cannot be proven, block for manual resolution rather than guessing or creating a duplicate. An identity match alone is not an already-present success: apply the model-specific completion evidence in step 6 before classifying it. A matching pending or incomplete registration must not be reported as already present or complete, and must not trigger a duplicate registration.
4. Inspect missing candidates and confirm the exact batch
Prefer a suitable reviewed catalogue entry, even when its endpoint differs from the local server, but never silently substitute based on a name. Keep the original sanitized alias/endpoint and the effective confirmed target as separate identities.
- Search exact endpoint identity FIRST: call
search_mcp_catalogwith the safe full endpoint asquery. This is text search, not an exact URL lookup: its only inputs are optionalquery,provider_keyandcursor; there is no URL lookup flag orremote_urlsearch input. Follownext_cursorwith the samequeryandprovider_key(unlikefind_mcppagination). Results containprovider_key,catalog_ref, name, description, version, tool count and setup intent, not guaranteed endpoint evidence. Inspect plausible results withinspect_mcp_candidateusing the returnedprovider_keyandcatalog_ref, withoutremote_url. Claim exact endpoint identity only if returned evidence proves it; an absentcanonical_urlis unknown, not a match. - If no suitable exact match is established, search local non-secret alias/provider/name SECONDARY using
query. Do not invent aprovider_keyfrom a product name: it is a server-issued source filter. Deduplicate results by returnedprovider_keypluscatalog_ref. A name hit is only a proposed alternative, never proof of equivalence. A URL search miss does not rule out a reviewed alternative. - Inspect plausible reviewed alternatives using those exact returned identities. Present candidate name, description, version, source/reference, transport, tool names/count, declared configuration and setup needs. Compare the original endpoint with the candidate's returned endpoint where available; explain region, product and tools differences, and explicitly mark unknown differences. Do not infer regional or functional equivalence from a shared name. If ambiguous, present the alternatives and ask for one exact candidate; do not choose automatically.
- Catalogue substitutions require separate confirmation of the exact candidate, differences/unknowns, declared non-secret configuration and destination project. Only after explicit acceptance set the effective target to the returned
provider_key/catalog_refplus confirmed configuration and any returned endpoint. Recheck existing registrations after substitution: repeat the selected project's completefind_mcpinventory and inspect matches withget_mcp, comparing server-issued source/registration evidence for this confirmed catalogue target, not only the original URL. Deduplicate confirmed catalogue targets across aliases too, only when configuration identity is proven. Two configurations of one catalogue reference are not the same target. Inventory does not expose selected configuration values or a configuration fingerprint; source/reference alone cannot prove configuration equivalence. For any registration without server-backed proof of its exact effective configuration, keep configuration identity unverified and request manual resolution; do not claim already present or create a duplicate. If already present, apply step 6's completion checks and do not register again; pending/incomplete or uncertain identity blocks duplicate creation. - If the user declines, no suitable match exists, or catalogue search is unavailable, offer the original safe direct remote path; disclose search failure rather than claiming no match. Unresolved ambiguity must not trigger a catalogue write: ask the user to choose or explicitly continue direct remote. For a direct fallback, call
inspect_mcp_candidatewith the originalremote_url, withoutprovider_keyorcatalog_ref. Present itscanonical_url,transport,tool_names/tool_count,trust,authentication,oauth_discovery,requires_dashboard_setup,setup_categoryandactionswhere returned. After declining a catalogue candidate, require explicit confirmation of the inspected direct target, destination project and exact direct batch beforeregister_remote_mcp; declining the candidate is not consent to the fallback. Never manufacture a direct URL from a catalogue name. Unsupported, denied or inconclusive candidates remain blocked pending returned guidance.
Distinguish observed tools from missing evidence; an empty tool list or authentication requirement is not proof of readiness. Obtain explicit confirmation of the exact inspected batch and project before any write: show each effective target, original alias/endpoint, chosen catalogue or direct path, evidence and outstanding setup needs, plus already-present and blocked items. If inspection changes the endpoint, disclose it and reconfirm. Changed project, candidate or configuration requires fresh inspection as applicable and renewed confirmation. Use only the catalogue inspection/registration portion here, not the entire add-mcp-from-catalog workflow: import does not require readiness or plugin distribution.
5. Add confirmed supported items independently
For each confirmed missing catalogue target, call register_catalog_mcp with project_slug, the exact returned provider_key and catalog_ref, only declared non_secret_config, and a caller-generated idempotency_key. Never create a custom direct-remote entry for a confirmed catalogue replacement. Correlate the exact submitted confirmed configuration, project and catalogue identity with the returned registration_id in the non-secret operation receipt; retain this mapping for final verification. This correlates a request with a returned registration ID only; it does not prove creation or persisted configuration. register_catalog_mcp can reuse an existing registration for the same source/reference with different configuration unchanged. Neither a new receipt nor replayed: false proves that the submitted configuration took effect.
For each confirmed missing direct remote item, call register_remote_mcp with project_slug, the confirmed remote_url, optional display_name, and a caller-generated idempotency_key. Keep one key per logical operation. Preserve all logical-operation inputs and the same idempotency key on retries, including after timeouts or uncertain write outcomes. Do not generate a new key merely because the result was lost. A changed operation requires renewed confirmation and a fresh key.
Apply returned repair/retry guidance and rate limits; do not retry permanent denial unchanged or bypass validation. Continue independent items after failure. Retain non-secret receipts, registration_id, canonical_url, next_action and any dashboard_setup_url for verification and handoff. A successful response alone is not completion.
6. Verify every selected item live
Re-read the selected project's complete inventory with find_mcp pagination and get_mcp for matching entries. Verify all selected items, including already-present entries and uncertain write outcomes, against the effective confirmed target identity and project. For catalogue replacements, match fresh inventory registration.id to the receipt's returned registration_id where available, and verify the same project and returned source.provider/source.reference against the accepted provider_key/catalog_ref, plus any returned endpoint. Receipt-ID correlation alone is not persisted configuration proof. Require server-backed evidence of the registration's exact effective confirmed configuration before reporting added, already present or complete. register_catalog_mcp, find_mcp and get_mcp do not expose persisted configuration values or a persisted configuration fingerprint: do not invent fields or claim current configuration was read back. With this contract, configuration equivalence remains unverified and requires manual resolution, not automatic reuse. This applies even when the returned ID matches the receipt and live status is registered with complete components. A concurrent registration after preflight, an unknown existing registration or an uncertain write outcome must not be treated as newly created or correctly configured from the receipt; keep it unverified, do not create a duplicate, and offer manual dashboard resolution.
Distinguish a configless candidate from an empty submitted non_secret_config: omitted values can use declared defaults, and a field may be optional or secret. Inspection's absent/empty configuration only describes the current candidate, not persisted settings of a reused registration; it is not a configless-success exemption. The current inspection does not return a catalogue canonical_url, and inventory does not bind persisted configuration to that inspected candidate version. If exact effective configuration cannot be proven server-side, even an apparently configless candidate remains unverified/manual resolution; never claim success from an empty request or absence of declared fields. In every case, do not verify against the original URL when the confirmed replacement differs. Preserve the original alias-to-confirmed-target mapping in the report. Do not use cached preflight results as final evidence. Reconcile uncertain writes before retrying with their original inputs/key; if still unverified, report uncertainty rather than success.
For model: platform_managed, require a returned registration ID, registration.status: registered and registration.components_complete: true in addition to the exact project and effective target identity match (endpoint for direct remote; confirmed source identity and server-backed exact effective configuration proof for catalogue; receipt-ID correlation is insufficient) before reporting added, already present or complete. A missing registration, pending status or incomplete components means blocked/unverified; use returned repair guidance or a dashboard handoff, not duplicate creation. For an exact matching remote entry with model: dashboard_managed and no registration, report already present (dashboard-managed), not newly registered by this workflow. Do not require or invent a registration record for dashboard-managed entries; their readiness.state: unsupported is not evidence of a failed import or of working authentication. Other models or inconclusive identity/evidence remain blocked for manual resolution.
Report added / already present / blocked / failed per item, with alias mappings and evidence or a reason. Every selected supported server must be confirmed present in the selected project's live inventory to claim completion. Zero selections is not success. If any item remains blocked, failed or unverified, report partial completion and next steps, not unqualified success.
7. Keep authentication separate
Report registration and authentication/readiness separately: “added to the project” does not mean connected, authorized, working or distributed. Offer exact server-returned Speakeasy setup/authorization links as clickable links, including dashboard_setup_url; never reconstruct or invent them. If no link is returned, say so and offer a manual dashboard handoff.
Skip provider attachment for anonymous servers. Offer attachment only when inspection reports an authentication requirement and advertises a supported identity provider through its authentication/OAuth discovery evidence, and a registration ID is available. For direct remote inspection, require authentication: authentication_required and oauth_discovery: available_dcr before offering attachment; available alone or incomplete does not establish support for this dynamic-registration flow. These are prerequisites, not a guarantee: the attachment tool still validates the supported provider and may return repair guidance. Authentication required with no supported provider evidence means a secure/manual setup handoff, not a speculative attachment call. Retain separate explicit consent for provider attachment. Only after those evidence checks and that consent, attach_platform_mcp_identity_provider takes project_slug, returned registration_id and confirmed: true; present its exact returned provider_url and authorization_url. Secret entry and provider sign-in belong in that secure browser flow, never in chat or tool arguments. Do not force readiness, provider attachment or distribution to finish import. Leave local config unchanged; do not migrate credentials or remove local entries.

