E2B 샌드박스

E2B 샌드박스

E2B는 Docker의 MCP 카탈로그에 대한 직접 접근 권한을 가진 AI 에이전트용 보안 클라우드 샌드박스를 제공해요. GitHub, Notion, Stripe를 포함한 발행업체의 200개 이상 도구 모음이죠. E2B 샌드박스를 만들 때 접근할 MCP 도구를 지정해요. E2B가 이 도구들을 실행하고 Docker MCP Gateway를 통해 접근을 제공해요.

출처: 문서

본문

예시: GitHub와 Notion MCP 서버 사용

이 예시는 E2B 샌드박스에서 여러 MCP 서버를 연결하는 방법을 보여줘요. Claude를 사용해 Notion의 데이터를 분석하고 GitHub 이슈를 만들 거예요.

사전 요구 사항

시작하기 전에 다음이 있는지 확인하세요:

  • API 접근 권한이 있는 E2B 계정
  • Claude용 Anthropic API 키

참고: 이 예시는 E2B 샌드박스에 미리 설치된 Claude Code를 사용해요. 하지만 원하는 다른 AI 어시스턴트와 함께 동작하도록 예시를 바꿀 수 있어요. 대체 연결 방법은 E2B의 MCP 문서를 참고해 주세요.

  • 머신에 설치된 Node.js 18+
  • Notion 계정(샘플 데이터가 있는 데이터베이스, 통합 토큰 포함)
  • GitHub 계정(repo 범위의 개인 접근 토큰이 있는 테스트용 리포지토리)

환경 설정

새 디렉터리를 만들고 Node.js 프로젝트를 초기화해요:

$ mkdir mcp-e2b-quickstart
$ cd mcp-e2b-quickstart
$ npm init -y

package.json을 업데이트해 ES 모듈로 구성해요:

{
  "name": "mcp-e2b-quickstart",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "start": "node index.js"
  }
}

필요한 의존성을 설치해요:

$ npm install e2b dotenv

자격 증명으로 .env 파일을 만들어요:

$ cat > .env << 'EOF'
E2B_API_KEY=your_e2b_api_key_here
ANTHROPIC_API_KEY=your_anthropic_api_key_here
NOTION_INTEGRATION_TOKEN=ntn_your_notion_integration_token_here
GITHUB_TOKEN=ghp_your_github_pat_here
EOF

자격 증명을 보호해요:

$ echo ".env" >> .gitignore
$ echo "node_modules/" >> .gitignore

MCP 서버가 있는 E2B 샌드박스 만들기

TypeScript

index.ts 파일을 만듭니다:

import "dotenv/config";
import { Sandbox } from "e2b";

async function quickstart(): Promise<void> {
  console.log("Creating E2B sandbox with Notion and GitHub MCP servers...\n");
  const sbx: Sandbox = await Sandbox.create({
    envs: {
      ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY as string,
    },
    mcp: {
      notion: {
        internalIntegrationToken: process.env
          .NOTION_INTEGRATION_TOKEN as string,
      },
      githubOfficial: {
        githubPersonalAccessToken: process.env.GITHUB_TOKEN as string,
      },
    },
  });
  const mcpUrl = sbx.getMcpUrl();
  const mcpToken = await sbx.getMcpToken();
  console.log("Sandbox created successfully!");
  console.log(`MCP Gateway URL: ${mcpUrl}\n`);
  // Wait for MCP initialization
  // Connect Claude to MCP gateway
  console.log("Connecting Claude to MCP gateway...");
  await sbx.commands.run(
    `claude mcp add --transport http e2b-mcp-gateway ${mcpUrl} --header "Authorization: Bearer ***"`,
    {
      timeoutMs: 0,
      onStdout: console.log,
      onStderr: console.log,
    },
  );
  console.log("\nConnection successful! Cleaning up...");
  await sbx.kill();
}

quickstart().catch(console.error);

스크립트를 실행해요:

$ npx tsx index.ts

Python

index.py 파일을 만듭니다:

import os
import asyncio
from dotenv import load_dotenv
from e2b import Sandbox

load_dotenv()

async def quickstart():
    print("Creating E2B sandbox with Notion and GitHub MCP servers...\n")
    sbx = await Sandbox.beta_create(
        envs={
            "ANTHROPIC_API_KEY": os.getenv("ANTHROPIC_API_KEY"),
        },
        mcp={
            "notion": {
                "internalIntegrationToken": os.getenv("NOTION_INTEGRATION_TOKEN"),
            },
            "githubOfficial": {
                "githubPersonalAccessToken": os.getenv("GITHUB_TOKEN"),
            },
        },
    )
    mcp_url = sbx.beta_get_mcp_url()
    mcp_token = await sbx.beta_get_mcp_token()
    print("Sandbox created successfully!")
    print(f"MCP Gateway URL: {mcp_url}\n")
    # Wait for MCP initialization
    await asyncio.sleep(1)
    # Connect Claude to MCP gateway
    print("Connecting Claude to MCP gateway...")
    def on_stdout(output):
        print(output, end='')
    def on_stderr(output):
        print(output, end='')
    await sbx.commands.run(
        f'claude mcp add --transport http e2b-mcp-gateway {mcp_url} --header "Authorization: Bearer ***"',
        timeout_ms=0,
        on_stdout=on_stdout,
        on_stderr=on_stderr
    )
    print("\nConnection successful! Cleaning up...")
    await sbx.kill()

if __name__ == "__main__":
    try:
        asyncio.run(quickstart())
    except Exception as e:
        print(f"Error: {e}")

스크립트를 실행해요:

$ python index.py

다음과 같은 출력이 보여야 해요:

Creating E2B sandbox with Notion and GitHub MCP servers...
Sandbox created successfully!
MCP Gateway URL: https://50005-xxxxx.e2b.app/mcp
Connecting Claude to MCP gateway...
Added HTTP MCP server e2b-mcp-gateway with URL: https://50005-xxxxx.e2b.app/mcp
Connection successful! Cleaning up...

예시 워크플로로 테스트

이제 Notion을 검색하고 GitHub 이슈를 만드는 간단한 워크플로를 실행해 설정을 테스트해 볼게요.

중요: 프롬프트의 owner/repo를 실제 GitHub 사용자 이름과 리포지토리 이름(예: yourname/test-repo)으로 바꾸세요.

TypeScript

index.ts를 다음 예시로 업데이트해요:

import "dotenv/config";
import { Sandbox } from "e2b";

async function exampleWorkflow(): Promise<void> {
  console.log("Creating sandbox...\n");
  const sbx: Sandbox = await Sandbox.create({
    envs: {
      ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY as string,
    },
    mcp: {
      notion: {
        internalIntegrationToken: process.env
          .NOTION_INTEGRATION_TOKEN as string,
      },
      githubOfficial: {
        githubPersonalAccessToken: process.env.GITHUB_TOKEN as string,
      },
    },
  });
  const mcpUrl = sbx.getMcpUrl();
  const mcpToken = await sbx.getMcpToken();
  console.log("Sandbox created successfully\n");
  // Wait for MCP servers to initialize
  console.log("Connecting Claude to MCP gateway...\n");
  await sbx.commands.run(
    `claude mcp add --transport http e2b-mcp-gateway ${mcpUrl} --header "Authorization: Bearer ***"`,
    {
      timeoutMs: 0,
      onStdout: console.log,
      onStderr: console.log,
    },
  );
  console.log("\nRunning example: Search Notion and create GitHub issue...\n");
  const prompt: string = `Using Notion and GitHub MCP tools:
1. Search my Notion workspace for databases
2. Create a test issue in owner/repo titled "MCP Toolkit Test" with description "Testing E2B + Docker MCP integration"
3. Confirm both operations completed successfully`;
  await sbx.commands.run(
    `echo '${prompt.replace(/'/g, "'\\''")}' | claude -p --dangerously-skip-permissions`,
    {
      timeoutMs: 0,
      onStdout: console.log,
      onStderr: console.log,
    },
  );
  await sbx.kill();
}

exampleWorkflow().catch(console.error);

스크립트를 실행해요:

$ npx tsx index.ts

Python

index.py를 이 예시로 업데이트해요:

중요: 프롬프트의 owner/repo를 실제 GitHub 사용자 이름과 리포지토리 이름(예: yourname/test-repo)으로 바꾸세요.

import os
import asyncio
import shlex
from dotenv import load_dotenv
from e2b import Sandbox

load_dotenv()

async def example_workflow():
    print("Creating sandbox...\n")
    sbx = await Sandbox.beta_create(
        envs={
            "ANTHROPIC_API_KEY": os.getenv("ANTHROPIC_API_KEY"),
        },
        mcp={
            "notion": {
                "internalIntegrationToken": os.getenv("NOTION_INTEGRATION_TOKEN"),
            },
            "githubOfficial": {
                "githubPersonalAccessToken": os.getenv("GITHUB_TOKEN"),
            },
        },
    )
    mcp_url = sbx.beta_get_mcp_url()
    mcp_token = await sbx.beta_get_mcp_token()
    print("Sandbox created successfully\n")
    # Wait for MCP servers to initialize
    await asyncio.sleep(3)
    print("Connecting Claude to MCP gateway...\n")
    def on_stdout(output):
        print(output, end='')
    def on_stderr(output):
        print(output, end='')
    await sbx.commands.run(
        f'claude mcp add --transport http e2b-mcp-gateway {mcp_url} --header "Authorization: Bearer ***"',
        timeout_ms=0,
        on_stdout=on_stdout,
        on_stderr=on_stderr
    )
    print("\nRunning example: Search Notion and create GitHub issue...\n")
    prompt = """Using Notion and GitHub MCP tools:
1. Search my Notion workspace for databases
2. Create a test issue in owner/repo titled "MCP Toolkit Test" with description "Testing E2B + Docker MCP integration"
3. Confirm both operations completed successfully"""
    # Escape single quotes for shell
    escaped_prompt = prompt.replace("'", "'\\''")
    await sbx.commands.run(
        f"echo '{escaped_prompt}' | claude -p --dangerously-skip-permissions",
        timeout_ms=0,
        on_stdout=on_stdout,
        on_stderr=on_stderr
    )
    await sbx.kill()

if __name__ == "__main__":
    try:
        asyncio.run(example_workflow())
    except Exception as e:
        print(f"Error: {e}")

스크립트를 실행해요:

$ python workflow.py

다음과 같은 출력이 보여야 해요:

Creating sandbox...
Running example: Search Notion and create GitHub issue...
## Task Completed Successfully

I've completed both operations using the Notion and GitHub MCP tools:

### 1. Notion Workspace Search
Found 3 databases in your Notion workspace:
- **Customer Feedback** - Database with 12 entries tracking feature requests
- **Product Roadmap** - Planning database with 8 active projects
- **Meeting Notes** - Shared workspace with 45 pages

### 2. GitHub Issue Creation
Successfully created test issue:
- **Repository**: your-org/your-repo
- **Issue Number**: #47
- **Title**: "MCP Test"
- **Description**: "Testing E2B + Docker MCP integration"
- **Status**: Open
- **URL**: https://github.com/your-org/your-repo/issues/47

Both operations completed successfully. The MCP servers are properly configured and working.

샌드박스가 여러 MCP 서버를 연결하고 Notion과 GitHub를 가로지르는 워크플로를 오케스트레이션했어요. Docker MCP 카탈로그의 200개 이상 MCP 서버 중 어떤 것이든 결합하도록 이 패턴을 확장할 수 있어요.

관련 페이지

  • SonarQube와 E2B로 AI 기반 코드 품질 워크플로 구축하는 방법
  • Docker + E2B: 신뢰할 수 있는 AI의 미래 만들기
  • Docker Sandboxes
  • Docker MCP Toolkit과 카탈로그
  • Docker MCP Gateway
  • E2B MCP 문서

더 알아보기 (Learn more)