Connecting AI sandboxes to dev containers

· Tech

TLDR: Claude in a sandbox can reach your API at http://host.docker.internal:3333. Network access to a port does not give access to env vars. Three options: exposed ports (zero setup), shared Docker network (hides DB from Claude), MCP proxy (full audit trail).


An isolated agent that cannot test anything is useless. Claude needs to hit endpoints and see error responses. The key insight: network access to a container’s port does NOT give access to that container’s environment variables.

Your docker-compose.dev.yml already exposes ports. Claude uses host.docker.internal:

Terminal window
# Inside Claude's sandbox
curl http://host.docker.internal:3333/api/health

Zero setup. Works with Docker Desktop out of the box.

Option 2: Shared network (more controlled)

Only the API is visible to Claude. Database and Redis stay hidden:

services:
api:
networks: [dev-net, claude-shared]
postgres:
networks: [dev-net] # Claude cannot reach this
networks:
claude-shared:
name: claude-shared
external: true
Terminal window
docker network create claude-shared

Option 3: MCP proxy (most secure)

A lightweight MCP server that mediates all requests with logging:

server.tool(
"api_request",
"Send request to dev API",
{
method: { type: "string", enum: ["GET", "POST", "PUT", "DELETE"] },
path: { type: "string" },
},
async ({ method, path }) => {
console.error(`[MCP] ${method} ${path}`);
const res = await fetch(`http://api:3333${path}`, { method });
return {
content: [
{ type: "text", text: `HTTP ${res.status}\n${await res.text()}` },
],
};
},
);

Add to CLAUDE.md

## Local Development
API: http://host.docker.internal:3333
Frontend: http://host.docker.internal:3000
Check .env.example for required variables.
Never read .env files or access container env vars.

MCP server credentials

MCP config files (claude_desktop_config.json, .mcp.json) often contain API keys inline. This is a secret on disk that AI agents read automatically.

Fix: Use environment variable references:

{
"mcpServers": {
"github": {
"command": "mcp-server-github",
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
}
}
}

Set the variable before launching Claude:

Terminal window
export GITHUB_TOKEN=$(infisical secrets get GITHUB_TOKEN --env=dev --plain --silent)

Add MCP configs to .claudeignore:

claude_desktop_config.json
.mcp.json
**/mcp.json

Which option

Solo dev: Option 1. Want to hide DB: Option 2. Real money involved: Option 3.