--- name: configure-private-mcp-access description: Configure the address and network access of an existing MCP server or gateway in an AICP project, then check whether its plugin package reflects the new address. --- # Configure private access for an existing MCP Use the authenticated Speakeasy AI Control Plane (AICP) Platform MCP. Installing a plugin does not grant organization access, network access, or authorization to change an MCP. This workflow changes the address or network mode of an existing MCP server (including a hosted toolset) or gateway, not its upstream URL, its plugin membership, or its users' permissions. Hosted toolset network mode is managed through its canonical MCP server target; its address remains toolset-owned and must be changed in the dashboard. 1. Call `list_projects` and ask the administrator to select an exact project. The list caps at 100; if truncated, use the AICP dashboard to select the project rather than assuming the first page is complete. 2. Call `list_plugins` for that project and ask which existing plugin is affected. Call `get_plugin` for that exact plugin. Follow `membership_next_cursor` until all its members are listed. If a membership changes mid-pagination, restart. Preserve each typed target ID; do not guess an MCP from a display name or substitute a different server for a hosted toolset's canonical MCP server. 3. Ask the administrator to choose the exact MCP server or gateway. Call `get_mcp_connection_settings` with its `project_id`, `target_kind`, and `target_id`. Explain the current endpoints, network mode, configured ingress and plugin memberships. These are settings and observations, not evidence that a tailnet or client can connect. Stop if the target is ambiguous, unproxied, hidden, or the private address cannot be resolved safely. 4. If changing an address, use the dashboard for hosted toolsets. For other targets, ask which existing endpoint should move or whether to create a new endpoint, and which slug and existing custom domain to use. Present the exact before and after address, including whether changing domains clears an existing root alias. Never silently take another root alias, create a custom domain, alter backend IDs, or add the target to a plugin. 5. If changing network access, call `get_mcp_network_traffic` for the selected `project_id` and `target_id` with `window: "7d"`. For its `target_kind`, use `mcp` for an MCP server or `gateway` for a gateway (connection settings instead uses `mcp_server` or `gateway`). Report observed public and private request counts and last-seen times before proposing the exact transition among `public_only`, `dual`, and `private_only`. Counts cover only observed requests while telemetry was enabled: zero does not prove a route is unused or that every client has migrated. If traffic reporting is unavailable, say so and require an independent client inventory before cutting off either route. Explain that `private_only` can break public clients, while `dual` retains public access. A private mode requires the server's admission and ingress readiness checks; do not infer readiness from a configured DNS name alone. 6. Immediately before each change, refresh `get_mcp_connection_settings` for the same exact target. Explain the proposed change and ask for explicit confirmation. Call `set_mcp_address` or `set_mcp_network_access` only after confirmation, with the fresh `version` as `expected_version` and a stable `idempotency_key` for that exact request. On conflict or refusal, re-read and request confirmation again. Never silently retry with a different target or value. 7. Treat the mutation receipt as evidence of the historical committed change, not of publication. Read `get_mcp_connection_settings` again to check current settings. Call `get_plugin` for every affected plugin and compare its publication evidence and desired package addresses. An enqueued request is not a published package; `fresh: null` is unknown, and `fresh: false` means the package needs a refresh. Read `fresh` together with `last_publish`: `queued`, `running`, or `retrying` means an update is already on its way, so read `get_plugin` again later instead of republishing; `failed` with `failure_category: repository_conflict` cannot be fixed by republishing, so do not retry it and send the administrator to Speakeasy support; `last_publish.unavailable: true` means the attempt could not be read, so do not infer a failure; if the publication evidence reports `not_configured: true`, no publish has ever been recorded and `republish_plugin` would refuse it, so send the administrator to the dashboard or Speakeasy support instead of offering it. If the package still reports `fresh: false` without an update on its way or a repository conflict, and the administrator wants it refreshed now, explain that republishing regenerates every plugin in the project, ask for explicit confirmation, then call `republish_plugin` with the exact `project_id` selected in step 1, that exact plugin, `confirmed: true`, and a stable `idempotency_key`. If the outcome is `already_current`, report that the package is already current and that no publish was requested. If it is `enqueued`, it is only a request that can be accepted before its run starts: treat it as pending until `last_publish.requested_at` is later than the republish or the publication evidence reports `fresh: true` (a republish can fold into a run already in flight without moving `requested_at`), read `get_plugin` again later before reporting the package as current, and never treat an older failed or succeeded attempt as the new request failing or being missed, or republish again because of it. If `republish_plugin` refuses: for `not_configured`, report that no package repository is connected and present the returned Plugins link; for `not_found` or `ambiguous_target`, ask the user for the exact plugin and do not hand off to the dashboard; for `rate_limited`, say nothing changed and do not retry automatically. If emission is disabled, the best-effort signal fails, the tool is unavailable, or the package cannot be verified, say so plainly and use the dashboard. Do not claim installed clients have refreshed or OAuth sessions have reconnected. 8. Report the exact MCP and plugin, the current configured address and mode, whether the generated package would use the private address, whether stored published fingerprints are current, and what the administrator must do to test tailnet connectivity and refresh clients. Keep operational selectors, version hashes, idempotency keys, and receipts out of the user-facing summary. Never request or transmit API keys, OAuth codes, client secrets, access tokens, network credentials, or upstream authentication headers in chat. A public gateway does not become private because a member MCP is private; configure each selected endpoint independently.