> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 샌드박스에서 Cursor 실행하기

> CoreWeave 샌드박스에서 Cursor CLI를 대화형으로 실행하거나 코딩 작업을 자동화하세요.

CoreWeave 샌드박스에서 저장소를 대상으로 Cursor 명령줄 인터페이스(CLI)를 실행하세요.
대화형으로 작업하려면 터미널을 연결하고, 자동화하려면 Sandboxes 소프트웨어 개발 키트(SDK)로
프롬프트를 실행한 뒤 결과를 수집하세요. CLI 프로세스,
워크스페이스, 명령어는 모두 샌드박스 안에서 실행되며, 모델 요청은 Cursor로 전송됩니다.

Cursor는 [Self-Hosted Machines](https://cursor.com/docs/cloud-agent/self-hosted)도 지원합니다.
이 방식에서는 Cursor 클라우드가 에이전트 루프를 실행하고, 별도의 워커가 도구 호출을 실행합니다.

<h2 id="prerequisites">
  사전 요구 사항
</h2>

시작하기 전에 다음 항목을 준비하세요.

* `cws-agent` 경로에 대한 `SANDBOX_USER` 액션 권한이 있는 [CoreWeave API 액세스 토큰](/ko/products/sandboxes/get-started#coreweave-api-access-token). SDK는 시크릿 주입에 Forge API 키를 사용하는 방식도 지원합니다. 자세한 내용은 [Cursor 키 제공 방법 선택](#choose-how-to-supply-the-cursor-key)을 참조하세요.

* [Cursor 사용자 API 키](https://cursor.com/docs/cli/reference/authentication#api-key-authentication)
  및 Cursor CLI에서 지원하는 모델에 대한 액세스 권한.

* 공개 저장소 URL. 비공개 저장소를 사용하려면 샌드박스 내부에
  Git 사용자 인증 정보가 있어야 합니다.

* Cursor, Cursor 다운로드 호스트, Git 호스트에 대한 아웃바운드 연결.

로컬 터미널에서 CoreWeave API 액세스 토큰을 설정하세요.

```bash theme={"system"}
export CWSANDBOX_API_KEY="[API-ACCESS-TOKEN]"
```

Cursor는 샌드박스 내부에서 `CURSOR_API_KEY`를 읽습니다. Cursor는
프롬프트, 파일 내용, 도구 출력을 자사 서비스로 전송할 수 있습니다. 작업에 적합한 저장소와
사용자 인증 정보를 사용하세요.

<h2 id="run-cursor-cli-with-cws-agent">
  cws-agent로 Cursor CLI 실행
</h2>

`cws-agent`를 사용하여 샌드박스를 생성하고 Cursor를 설치한 다음 터미널을 연결하세요.
대화형으로 연결하려면 macOS, Linux 또는 Windows Subsystem for Linux(WSL)의
대화형 터미널(TTY)이 필요합니다. 네이티브 Windows 터미널은 지원되지 않습니다.

로컬 환경에서 Cursor 키를 환경 변수로 export하세요. `cws-agent`가 이 키를 샌드박스
환경으로 전달합니다.

```bash theme={"system"}
export CURSOR_API_KEY="[CURSOR-API-KEY]"
```

1. [`cws-agent` 설치 안내](https://github.com/coreweave/cws-agent#install)를 따르세요.

2. `[SANDBOX-NAME]`을 소문자, 숫자, 하이픈으로 구성된 1\~40자의 세션 이름으로
   바꾸세요. 이름은 문자나 숫자로 시작해야 합니다. `[REPOSITORY-URL]`은
   사용자의 저장소 URL로 바꾸세요.

   ```bash theme={"system"}
   cws-agent launch [SANDBOX-NAME] --agent cursor --repo-url [REPOSITORY-URL] --lifetime 2h --permission-mode native --no-config-sync
   ```

   Cursor는 `/workspace/project`에서 열립니다. 워크스페이스 신뢰 프롬프트가 표시되면
   수락하세요. `--permission-mode native`를 지정하면 Cursor의 승인 설정이 유지되며,
   지정하지 않으면 `cws-agent`는 `--force`를 사용합니다. `--no-config-sync`를 지정하면
   로컬 스킬과 Model Context Protocol(MCP) 설정을 임포트하지 않습니다.

3. 나중에 조회할 수 있는 파일을 생성하도록 Cursor에 요청하세요.

   ```text theme={"system"}
   Create sandbox-proof.txt in the current directory containing exactly
   Hello from CoreWeave followed by a newline, then read it back.
   Do not commit or push anything.
   ```

   작업 중 표시되는 프롬프트는 모두 승인하세요. `/exit`로 Cursor를 종료한 다음,
   로컬 터미널에서 파일을 읽으세요.

   ```bash theme={"system"}
   cws-agent exec [SANDBOX-NAME] 'cat /workspace/project/sandbox-proof.txt'
   ```

   `Hello from CoreWeave`가 출력되어야 합니다. Cursor를 종료해도
   샌드박스는 계속 실행됩니다.

4. 샌드박스의 Cursor 세션을 모두 종료한 후, Cursor가 남긴
   `worker.sock` 소켓 파일을 제거하고 워크스페이스를 저장한 다음 컴퓨팅을 중지하세요.

   ```bash theme={"system"}
   cws-agent exec [SANDBOX-NAME] 'find /workspace/home/.cursor/projects -type s -name worker.sock -delete'
   cws-agent down [SANDBOX-NAME]
   ```

   정리 작업에서는 스냅샷 생성을 방해할 수 있는 소켓 파일을 제거합니다. `down`은
   샌드박스를 중지하기 전에 스냅샷을 생성합니다.
   스냅샷 생성에 실패하면 샌드박스는 계속 실행됩니다. 복원하기 전에 오류를
   해결하고 `down`을 다시 시도하세요.

5. 저장된 워크스페이스로 돌아가려면 로컬에서 `CURSOR_API_KEY`를 export한 상태로 유지하고 다음 명령어를 실행하세요.

   ```bash theme={"system"}
   cws-agent restore [SANDBOX-NAME] --connect --permission-mode native --no-config-sync
   ```

   Cursor에 `sandbox-proof.txt` 파일을 읽도록 요청하여 파일이 복원되었는지 확인하세요.
   작업이 끝나면 Cursor를 종료하고 정리 작업과 `down` 명령어를 다시 실행하세요.

<h3 id="run-an-unattended-prompt">
  무인 모드로 프롬프트 실행
</h3>

새 세션 이름을 선택하세요. 로컬 터미널에서 `--detach` 옵션을 지정해 실행하면 터미널 연결을
건너뜁니다. 그런 다음 프롬프트를 보내세요.

```bash theme={"system"}
cws-agent launch [SANDBOX-NAME] --agent cursor --repo-url [REPOSITORY-URL] --lifetime 2h --permission-mode native --no-config-sync --detach
cws-agent run [SANDBOX-NAME] 'Create sandbox-proof.txt containing exactly Hello from CoreWeave followed by a newline, then read it back. Do not commit or push anything.'
```

`cws-agent run`은 기본적으로 Cursor의 `--force` 플래그를 전달하므로, 헤드리스 작업에서 대화형 승인 없이
파일을 쓸 수 있습니다. 단, Cursor에 명시적으로 설정된 거부 규칙은 그대로 적용됩니다.

실행 중인 세션에 터미널을 연결하려면 다음 명령을 실행하세요.

```bash theme={"system"}
cws-agent connect [SANDBOX-NAME] --permission-mode native --no-config-sync
```

작업이 끝나면 Cursor에 연결된 상태인 경우 Cursor를 종료하고, `cws-agent exec`로 결과를 확인한 다음,
[cws-agent로 Cursor CLI 실행](#run-cursor-cli-with-cws-agent)에 설명된 대로
`cws-agent down`으로 소켓을 정리하고 저장하세요.

<h2 id="run-a-task-with-the-sandbox-sdk">
  Sandboxes SDK로 작업 실행하기
</h2>

Sandboxes SDK를 사용하면 작업을 직접 관리할 수 있습니다. 이
방법은 별도의 샌드박스를 생성하고, Cursor를 print 모드로 실행한 뒤 파일을 조회하고,
정리 블록에서 샌드박스를 중지합니다. 스냅샷을 설정하지 않으며
`cws-agent`도 필요하지 않습니다.

<h3 id="choose-how-to-supply-the-cursor-key">
  Cursor 키 제공 방식 선택
</h3>

두 스크립트 모두 첫 번째 인수로 인증 모드를 받습니다.

| 모드 | 샌드박스 사용자 인증 정보 | Cursor 사용자 인증 정보 |
| - | - | - |
| `forge` | `FORGE_API_KEY` | 서버에서 확인하는 Forge 팀 시크릿입니다. |
| `coreweave` | `CWSANDBOX_API_KEY` | 샌드박스 환경 맵을 통해 전달되는 로컬 `CURSOR_API_KEY`입니다. |

이 예시에서는 서버리스 배치를 사용합니다. Forge 시크릿 주입을 사용하려면 Forge 인증과 서버리스 배치가 모두 필요합니다.

`forge` 모드를 사용하려면 Forge Admin에게 [Cursor 키를 팀 시크릿으로 추가](/ko/products/wandb/platform/secrets#add-a-secret)해 달라고 요청하세요.
그런 다음 로컬 터미널에서 `[FORGE-TEAM]`을 팀 이름으로,
`[CURSOR-SECRET-NAME]`을 시크릿 이름으로 바꾸세요.

```bash theme={"system"}
export FORGE_API_KEY="[FORGE-API-KEY]"
export FORGE_TEAM="[FORGE-TEAM]"
export CURSOR_SECRET_NAME="[CURSOR-SECRET-NAME]"
```

Forge API 키에 해당 팀에 대한 액세스 권한이 있어야 합니다. 스크립트는 이름이 지정된
시크릿을 샌드박스 내부의 `CURSOR_API_KEY`에 매핑합니다.
[Forge 시크릿 사용](/ko/products/sandboxes/secrets)을 참조하세요.

`coreweave` 모드에서는 `SANDBOX_USER` IAM 액션이 부여된 CoreWeave API 액세스 토큰을 `CWSANDBOX_API_KEY`로 설정하세요. [사용자 인증 정보 선택 및 조회](/ko/products/sandboxes/placement#choose-and-get-credentials)를 참조하세요. 같은 로컬 터미널에서 Cursor 키도 내보내세요.

```bash theme={"system"}
export CWSANDBOX_API_KEY="[API-ACCESS-TOKEN]"
export CURSOR_API_KEY="[CURSOR-API-KEY]"
```

`coreweave` 경로는 샌드박스 생성 요청에 Cursor 키를 일반 환경 변수 값으로 담아 전달합니다. 이는 사용자 인증 정보에 시크릿 참조를 사용하라는 SDK 권장 사항에 대한 예외입니다. 조직의 사용자 인증 정보 처리 정책에서 허용하는 경우에만 이 경로를 사용하세요. 요청을 로깅하거나 키를 커밋하지 마세요.

<h3 id="install-a-client">
  클라이언트 설치
</h3>

언어를 선택한 다음 클라이언트를 로컬에 설치하세요.

<Tabs>
  <Tab title="Python">
    Python 3.11 이상과 `uv`를 사용하세요. 새 프로젝트 디렉터리에서 다음 명령을 실행하세요.

    ```bash theme={"system"}
    uv init --python 3.11
    uv add 'cwsandbox==1.14.2'
    ```
  </Tab>

  <Tab title="TypeScript">
    Node.js 22 이상을 사용하세요. 프로젝트 디렉터리에서 다음 명령을 실행하세요.

    ```bash theme={"system"}
    npm install @coreweave/cwsandbox@0.5.0-beta.0 tsx
    ```
  </Tab>
</Tabs>

<h3 id="create-run-and-clean-up">
  생성, 실행 및 정리
</h3>

사용하는 언어에 맞는 스크립트를 표시된 파일 이름으로 저장하세요. 각 스크립트는
Cursor를 설치하고, 명령줄에서 전달한 저장소를 복제한 다음, Cursor에
`sandbox-proof.txt` 파일을 작성하도록 요청합니다.

`--print`, `--force`, `--trust` 플래그는 각각 비대화형 출력을 활성화하고,
파일 변경을 허용하며, 워크스페이스를 신뢰하도록 설정합니다. 이
예시는 신뢰할 수 있는 저장소에만 사용하세요. 자세한 내용은
[Cursor headless mode](https://cursor.com/docs/cli/headless)를 참조하세요.

<Tabs>
  <Tab title="Python">
    ```python title="run_cursor_sandbox.py" theme={"system"}
    import os
    import sys

    from cwsandbox import AuthHeaders, AuthStrategy, Sandbox, Secret

    if len(sys.argv) != 3 or sys.argv[1] not in ("forge", "coreweave"):
        raise SystemExit("Pass forge or coreweave, then a repository URL.")

    mode, repository = sys.argv[1:]
    if mode == "forge":
        auth = AuthHeaders(
            headers={
                "x-wandb-api-key": os.environ["FORGE_API_KEY"],
                "x-entity-id": os.environ["FORGE_TEAM"],
            },
            strategy="wandb_api_key",
        )
        credentials = {"secrets": [Secret(
            store="wandb", name=os.environ["CURSOR_SECRET_NAME"],
            env_var="CURSOR_API_KEY",
        )]}
    else:
        auth = AuthStrategy.COREWEAVE_API_KEY
        credentials = {
            "environment_variables": {"CURSOR_API_KEY": os.environ["CURSOR_API_KEY"]},
        }

    sandbox = Sandbox.run(
        auth=auth,
        placement_mode="serverless",
        container_image="node:22-bookworm",
        resources={"cpu": "2", "memory": "4Gi"},
        max_lifetime_seconds=2 * 3600,
        **credentials,
    )
    try:
        sandbox.wait()
        commands = [
            ["bash", "-o", "pipefail", "-ec", "curl -fsSL https://cursor.com/install | bash"],
            ["mkdir", "-p", "/workspace"],
            ["git", "clone", "--", repository, "/workspace/project"],
        ]
        for command in commands:
            sandbox.exec(command, timeout_seconds=900, check=True).result()

        result = sandbox.exec(
            [
                "/root/.local/bin/agent",
                "--print", "--force", "--trust", "--output-format", "text",
                "Create sandbox-proof.txt containing exactly Hello from CoreWeave "
                "followed by a newline, then read it back. Do not commit or push anything.",
            ],
            cwd="/workspace/project",
            timeout_seconds=300,
            check=True,
        ).result()
        print(result.stdout)
        proof = sandbox.exec(
            ["cat", "/workspace/project/sandbox-proof.txt"], check=True
        ).result()
        print(proof.stdout, end="")
    finally:
        sandbox.stop().result()
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript title="run_cursor_sandbox.mts" theme={"system"}
    import { createSandboxClientFromEnv as coreweaveClient } from "@coreweave/cwsandbox/node";
    import { createSandboxClient as forgeClient } from "@coreweave/cwsandbox/wandb";

    const [mode, repository] = process.argv.slice(2);
    if (!repository || (mode !== "forge" && mode !== "coreweave")) {
      throw new Error("Pass forge or coreweave, then a repository URL.");
    }

    const credential = mode === "forge"
      ? process.env.CURSOR_SECRET_NAME : process.env.CURSOR_API_KEY;
    if (!credential) {
      throw new Error("Set CURSOR_SECRET_NAME for forge or CURSOR_API_KEY for coreweave.");
    }
    const client = mode === "forge"
      ? forgeClient({ apiKey: process.env.FORGE_API_KEY, entity: process.env.FORGE_TEAM })
      : coreweaveClient();
    const credentials = mode === "forge"
      ? { secrets: [{ store: "wandb", name: credential, envVar: "CURSOR_API_KEY" }] }
      : { environmentVariables: { CURSOR_API_KEY: credential } };
    const sandbox = await client.create({
      containerImage: "node:22-bookworm",
      resources: { cpu: "2", memory: "4Gi" },
      maxLifetimeSeconds: 2 * 3600,
      ...credentials,
      waitUntilRunning: false,
    });
    try {
      await sandbox.wait();
      const commands = [
        ["bash", "-o", "pipefail", "-ec", "curl -fsSL https://cursor.com/install | bash"],
        ["mkdir", "-p", "/workspace"],
        ["git", "clone", "--", repository, "/workspace/project"],
      ];
      for (const command of commands) {
        await sandbox.commands.run(command, { timeoutMs: 900_000, check: true });
      }

      const result = await sandbox.commands.run(
        [
          "/root/.local/bin/agent",
          "--print", "--force", "--trust", "--output-format", "text",
          "Create sandbox-proof.txt containing exactly Hello from CoreWeave " +
            "followed by a newline, then read it back. Do not commit or push anything.",
        ],
        { cwd: "/workspace/project", timeoutMs: 300_000, check: true },
      );
      console.log(result.stdout);
      const proof = await sandbox.commands.run(
        ["cat", "/workspace/project/sandbox-proof.txt"], { check: true },
      );
      process.stdout.write(proof.stdout);
    } finally {
      await sandbox.stop();
    }
    ```
  </Tab>
</Tabs>

사용자 인증 정보를 설정한 로컬 터미널에서 `[AUTH-MODE]`를
`forge` 또는 `coreweave`로, `[REPOSITORY-URL]`을 저장소 URL로 바꾸세요.

<Tabs>
  <Tab title="Python">
    ```bash theme={"system"}
    uv run python run_cursor_sandbox.py [AUTH-MODE] [REPOSITORY-URL]
    ```
  </Tab>

  <Tab title="TypeScript">
    ```bash theme={"system"}
    npx tsx run_cursor_sandbox.mts [AUTH-MODE] [REPOSITORY-URL]
    ```
  </Tab>
</Tabs>

스크립트는 Cursor의 응답을 출력한 다음 파일 내용인
`Hello from CoreWeave`를 출력합니다. 정리 블록은 설정이나 실행 중에
오류가 발생하더라도 `stop()`을 호출합니다.
추가로 필요한 파일은 정리 블록이 실행되기 전에 조회하세요. 결과가 큰 경우에는
[파일 작업](/ko/products/sandboxes/client/guides/file-operations)을 사용하세요.

2시간 수명은 시작 시간을 포함한 최대 실제 경과 시간 제한입니다. 각
명령어에는 별도의 timeout도 있습니다. 명령어 timeout을 변경해도
샌드박스 수명은 연장되지 않습니다.

<h2 id="troubleshoot">
  문제 해결
</h2>

다음 항목을 확인하여 일반적인 문제를 해결하세요.

* 샌드박스 생성에 실패하면 선택한 인증 모드에 맞는 사용자 인증 정보를
  확인하세요.

* Forge 시크릿을 가져올 수 없으면 `FORGE_TEAM`, `CURSOR_SECRET_NAME`,
  API 키의 팀 액세스 권한을 확인하세요.

* Cursor에서 인증 오류가 발생하면 모드에 따라 Forge 시크릿 또는 로컬 `CURSOR_API_KEY`의 키를 확인하고, 계정의 모델 액세스 권한도 확인하세요.

* SDK 프롬프트가 변경 사항을 제안하기만 하고 적용하지 않는다면 Cursor 명령어에
  `--force`가 포함되어 있는지 확인하세요.

* 설치, 복제 또는 모델 요청이 실패하면 아웃바운드 연결 상태와
  공급자 사용자 인증 정보를 확인하세요. CoreWeave Kubernetes Service(CKS)에 배치하는 경우
  러너 정책에서 필요한 대상을 허용해야 합니다.

<h2 id="next-steps">
  다음 단계
</h2>

자세한 내용은 다음 가이드를 참조하세요.

* [CoreWeave 샌드박스에서 에이전트 실행하기](/ko/products/sandboxes/agents)에서는 배치,
  장시간 세션, 워크스페이스 라이프사이클을 설명합니다.
* [cws-agent와 함께 Cursor 사용하기](https://github.com/coreweave/cws-agent/blob/main/docs/cursor.md)에서는
  저장된 대화와 설정 임포트를 설명합니다.
* [Cursor CLI 문서](https://cursor.com/docs/cli/overview)에서는 에이전트
  설정과 지원되는 모드를 설명합니다.
