Connect each VM's MCP client to a shared remote endpoint, and give each VM its own credential scoped to the systems and operations its job requires. Keep service credentials at the connection layer, inject the VM credential at runtime, and verify a real tool call before admitting the VM to the pool. The endpoint still needs network access to the upstream systems, and deleting a VM must be paired with revoking its credential.
Put the connection boundary outside the VM
Consider a disposable coding VM that needs an issue description, a database schema and a deployment status. Installing three adapters and distributing three service credentials makes every replacement VM repeat the integration setup. Instead, configure those connections behind a remote MCP endpoint. The VM receives the address and an identity; the connection layer resolves which upstream tools that identity may use.
The MCP Streamable HTTP specification describes a server endpoint accepting POST requests, with responses delivered as JSON or Server-Sent Events. Use a client and server with compatible protocol versions. A URL ending in /mcp is an address, not evidence that the server supports the transport your client expects.
Draw two network paths before provisioning: guest to endpoint, then endpoint to each upstream. An endpoint outside your private network cannot reach an internal database merely because the VM can. Decide where the connection service will run and how it reaches those systems. Allow the guest's tool traffic to that endpoint over HTTPS; account separately for model access, source checkout and other traffic the job requires.
Create the VM identity after cloning the image
Build the reusable image with the agent client and a credential-free configuration template. After creating an instance, issue a distinct endpoint credential and record its relationship to the VM identifier, job owner and intended sources. If multiple independently managed agents share a VM, give them separate credentials when they need separate revocation or permissions.
For the coding job above, start with the issue source, schema access and deployment reads. Leave production writes out of its identity. A separate release worker can receive a different grant. The useful property is that rebuilding the coding VM never requires copying a database password into it. For choosing those boundaries, see one scoped key per agent.
Deliver the endpoint credential through your runtime secret mechanism. Docker's build-secret documentation warns against passing secrets through build arguments or Dockerfile environment variables because they can persist in the image. Build-time secret mounts serve build operations; provision the running agent's credential separately. For VM templates, apply the same design rule: take the reusable snapshot before credential injection, and exclude authenticated home directories from cloning.
Configure Claude Code inside the guest
In the VM's checkout, register the endpoint using the command documented by Claude Code:
claude mcp add --transport http workspace-tools --scope project https://mcp.example.com/mcpThis creates a project-level .mcp.json. For an endpoint accepting bearer keys, set its entry to:
{
"mcpServers": {
"workspace-tools": {
"type": "http",
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer ${AGENT_MCP_KEY}"
}
}
}
}Replace the example URL with your endpoint. Claude Code documents environment expansion in header values. Supply AGENT_MCP_KEY to the Claude process through the VM launcher; keep the variable reference in the template. Make the launcher refuse startup if the value is missing. Avoid shell tracing or diagnostic environment dumps around injection.
Use claude mcp get workspace-tools and the interactive /mcp view to inspect connection status. Review the project server approval when prompted. A saved configuration does not establish that authentication or upstream access works.
Use the same endpoint with a different guest client
For Cursor installed inside a self-managed VM, Cursor's MCP integrations documentation supports remote entries with url and authentication headers. A runtime-generated .cursor/mcp.json can contain:
{
"mcpServers": {
"workspace-tools": {
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer REPLACE_AT_RUNTIME"
}
}
}
}The marker is a placeholder, not automatic interpolation. Have your provisioner serialize the actual credential into the private runtime file, restrict its filesystem access and keep it out of version control. Cursor documents restarting after configuration changes. This file contains a usable secret once rendered; exclude it from snapshots and support bundles.
Changing the client should change the small configuration adapter and credential delivery method. Keep upstream connection setup outside the guest. Test each client image independently, since a successful Claude connection does not verify Cursor's runtime configuration. Treat vendor-hosted agents as a separate deployment environment with their own configuration controls.
Commission the connection from the running agent
Test inside the guest under the same user and launcher that will run jobs. A successful request from your laptop misses guest DNS, certificate trust, proxy settings and environment inheritance. Run these checks before assigning real work:
- Confirm the guest resolves the endpoint hostname and completes TLS verification. Repair the guest trust store or network path rather than disabling certificate checks.
- Connect with the MCP client and inspect the available tools. Confirm an expected source appears for this VM's identity.
- Invoke a small read against a fixture, such as fetching a test issue by identifier. Compare the returned identifier with the expected record.
- Attempt an excluded operation against a disposable fixture. Require a server-side refusal; an agent declining to invoke it does not test authorization.
- Revoke the test credential while the VM stays running. Attempt another call, verify refusal, then provision a replacement credential through the normal launch path.
Inspect both legs when discovery succeeds but a tool fails. The endpoint may accept the VM while its upstream credential has expired or its database route is unavailable. Conversely, a simple browser GET does not exercise MCP POST behavior. The transport specification requires clients to support JSON and event-stream responses; inspect reverse-proxy buffering and timeouts if responses stall. Keep request outcomes and VM identifiers in commissioning records, with authorization headers excluded.
Doing this with SPYN3
SPYN3 provides one MCP endpoint per workspace at https://api.spyn3.com/agent/mcp. An admin or owner can create a source-scoped API key for each VM; upstream credentials stay envelope-encrypted in the workspace and never reach the agent. Grant call:tools for tools marked read-only; writes require call:write_tools. Sources open on demand through list_toolsets and enable_toolset. Revoking a key takes effect on the next call, and proxied tool calls are audit-logged. Start by connecting one source and testing a read from one disposable VM.
Make replacement and teardown part of provisioning
Destroy the commissioned VM and create another from the original image. Give it a new credential, run the same fixture read and confirm the old credential remains unusable. This catches a common provisioning mistake: the successful first machine depended on a manually edited home directory that the template never contained. Keep the endpoint URL and client configuration template versioned so the replacement follows the same setup.
Pair instance deletion with credential revocation in your teardown procedure. If deletion fails, revoke anyway; if revocation fails, retain an explicit cleanup task against that credential identifier. Reconcile issued credentials against live VM inventory so interrupted jobs do not leave forgotten access behind. Central revocation explains that operational boundary, while credentials in agent sandboxes covers what remains exposed inside the guest.
Finally, test endpoint unavailability with a disposable job. Require a visible failure and stop dependent work rather than letting the agent invent the missing issue or deployment state. A shared endpoint becomes a dependency for every connected VM; include that failure case in the image's acceptance checks.
Built for the next step
One key per sandbox
Point every VM or sandbox at one endpoint with its own scoped key; upstream secrets stay in the workspace.
Read the developer guideSPYN3 is a consolidated MCP layer: one hosted endpoint in front of every system you connect — MCP servers, Postgres, REST APIs, Google Drive — with tools foldered by source and read/write permissions per key. Switching agents means moving one URL. Free plan available; current capabilities are documented on the product facts page.
Sources
- MCP specification: Streamable HTTP — single endpoint POST transport, request headers, SSE responses and header validation. Verified 27 Oct 2026
- Anthropic docs: Claude Code MCP setup — Claude Code MCP commands, scopes, transports and JSON configuration. Verified 27 Oct 2026
- Cursor documentation: MCP integrations — Cursor MCP configuration locations, remote URL entries, headers and approval behavior. Verified 27 Oct 2026
- Docker: Build secrets — Why build arguments and environment variables are inappropriate for build secrets, and instruction-scoped secret mounts. Verified 27 Oct 2026
