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

> ## Agent Instructions
> To act on a user's behalf in Guild, use the Guild REST API at https://api.guild.ai/v1.
> The OpenAPI spec is unauthenticated: https://docs.guild.ai/openapi.json (or openapi.yaml).
> Authenticate with an account API key, sent as HTTP Basic (key id as username, secret as password) or as `Authorization: Bearer <api_key_id>:<api_key_secret>`. See https://docs.guild.ai/api-reference/introduction#authentication.
> To run one agent on demand without account-wide access, use an API trigger instead: https://docs.guild.ai/platform/api-triggers.
> To act on Guild from an MCP client, connect to https://api.guild.ai/mcp (OAuth) or run `guild mcp` locally. Setup: https://docs.guild.ai/api-reference/mcp.
> To search these docs from an MCP client, connect to https://docs.guild.ai/mcp. The full page index is https://docs.guild.ai/llms.txt.

# Migrate from the Cursor Agent SDK to Guild

> Port a Cursor Agent SDK project to a Guild TypeScript agent: instructions, typed tools, MCP connections, subagents, channels, and schedules.

Cursor's Agent SDK is the harness behind Bugbot and Security Review, opened up for your own agents and generally available since October 2026. An agent is a TypeScript project whose `bot/` folder holds instructions, typed tools, MCP connections, subagents, channels, and cron schedules, with evals beside it. It deploys to Cursor's hosting with `agent-sdk deploy`, or runs on your own Node host with `agent-sdk serve`. The npm package is `@grok/agent-sdk`; older projects use `@cursor/bdk`.

A Cursor agent is close to a Guild TypeScript agent in shape: instructions become the `systemPrompt`, typed tools become integration operations or functions in `logic.ts`, and channels and schedules become triggers.

> [!NOTE]
>
> This guide covers the Agent SDK. The Cursor SDK (`@cursor/sdk`) is a client library that drives Cursor's own coding agent; it has no `bot/` folder to port.

## Who this is for

Teams with agents built on Cursor's Agent SDK, on Cursor's hosting or their own Node hosts, who want credentials the agent code never sees, ALLOW/DENY policies set by admins, and agents others can install and fork from the Hub.

## Concept map

| Cursor Agent SDK | Guild |
| - | - |
| `bot/instructions.md` | `systemPrompt` on `llmAgent`, or `PROMPT.md` in a Native agent |
| `bot/agent.ts` (`defineAgent`) | `agent.ts`, built with `llmAgent` or with `agent({ description, inputSchema, outputSchema, tools, run })` |
| `defineAgent({ model })` with Cursor model IDs | Account LLM settings, or the `models` list in `guild.yaml`. Cursor's own models aren't available |
| `bot/tools/<name>.ts` (`defineTool`) | An integration operation registered with `pick(...)` when the tool calls an API, or a function in `logic.ts` when it only computes |
| `bot/mcp-connections/` and `bot/host-connections/` | The catalog integration for the same service, or a [custom MCP integration](https://docs.guild.ai/services/create-an-integration.md) created from the server's URL in the web app |
| `tools` and `disallowedTools` on a connection | Registering only the operations the agent calls, plus [credential policies](https://docs.guild.ai/platform/credential-policies.md) set by admins |
| `agent-sdk secret set` and `${NAME}` header templates | [Credentials](https://docs.guild.ai/platform/credentials.md) for secrets, and [workspace variables](https://docs.guild.ai/platform/workspace-variables.md) for settings |
| `bot/subagents/` and agent connections | Separate Guild agents called with `guildAgentTool` |
| `bot/skills/` | `skills/<name>/SKILL.md` in an OpenClaw agent (same format), or a [Guild skill](https://docs.guild.ai/platform/skills.md) |
| `bot/schedules/*.md` with `cron:` frontmatter | A [schedule trigger](https://docs.guild.ai/platform/schedule-triggers.md) with `--frequency CRON` |
| `slackChannel()`, `githubChannel()` | An [event trigger](https://docs.guild.ai/platform/event-triggers.md) on the Slack or GitHub integration |
| `defineChannel` HTTP routes | An [API trigger](https://docs.guild.ai/platform/api-triggers.md) |
| `needsApproval` on a tool, Slack tool approvals | A `ui_prompt` confirmation before each call, plus a [credential policy](https://docs.guild.ai/platform/credential-policies.md) that limits which agents can call it |
| `evals/**/*.eval.ts` (`defineEval`, `t.judge`) | [Guild Evaluations](https://docs.guild.ai/platform/evaluations.md) and `guild agent test` |
| Sessions, `agent-sdk logs`, OpenTelemetry | Guild [sessions](https://docs.guild.ai/platform/sessions.md) and their event log |
| Viewer, Editor, and Owner roles on a deployment | Workspace membership and roles |
| `agent-sdk deploy` | `guild agent save --wait --publish` |

## Before you start

```bash theme={null}
guild auth login
guild workspace select
```

## Inventory

List these from the `bot/` folder before writing any Guild code. Older projects keep the same layout under `agent/`. Record names only, never secret values.

* `bot/instructions.md` (or `instructions.ts`) and the model in `bot/agent.ts`.
* Every file in `bot/tools/`, what it calls (Octokit, `fetch`, a vendor SDK), and the secrets it reads from `process.env`.
* Tools with `needsApproval`, and write tools that skip side effects when `ctx.session.purpose === "eval"`.
* Every file in `bot/mcp-connections/` and `bot/host-connections/`, with its URL, `tools` or `disallowedTools`, and auth.
* `bot/subagents/`, agent connections, and `bot/skills/`.
* Channels in `bot/channels/` (Slack, GitHub, GitLab, Bitbucket, PagerDuty, HTTP routes) and schedules in `bot/schedules/`.
* Harness tools turned on in `defineAgent({ tools })`, such as `shell` or `edit`, and any `bot/sandbox/workspace/` files.
* Hooks, reminders, the memory journal, and `evals/`.

## Steps

**1. Scaffold a TypeScript agent**

```bash theme={null}
guild agent init --name pr-reviewer --agent-type GUILD_TYPESCRIPT --template LLM \
  --category <category> --owner <owner>
```

`--category` and `--owner` stop the CLI from prompting, which a script or coding agent can't answer. List categories with `guild agent categories`.

If the agent turns on Cursor's file and shell tools, or works in `bot/sandbox/workspace/`, scaffold an OpenClaw agent (`--agent-type OPENCLAW`) instead.

**2. Move instructions and tools**

`bot/instructions.md` becomes the `systemPrompt`. Each tool that calls an API becomes an integration operation, because the Guild runtime has no general network egress. Tools that only compute move to `logic.ts`.

```ts Guild: agent.ts theme={null}
"use agent";
import { llmAgent, pick } from "@guildai/agents-sdk";
import { gitHubTools } from "@guildai-services/guildai~github";

export default llmAgent({
  description: "Reviews GitHub pull requests and gives a verdict. Never approves a draft.",
  tools: { ...pick(gitHubTools, ["github_pulls_get", "github_pulls_list_files"]) },
  systemPrompt: "You review GitHub pull requests. Call github_pulls_get first. Never approve a draft. End with one sentence: the verdict and why.",
  mode: "multi-turn",
});
```

```ts Cursor: bot/tools/inspect_pr.ts theme={null}
import { defineTool } from "@grok/agent-sdk/tools";
import { z } from "zod";

export default defineTool({
  description: "Inspect a pull request before approval.",
  inputSchema: z.object({ owner: z.string(), repo: z.string(), number: z.number().int() }),
  effect: "read",
  async execute({ owner, repo, number }, ctx) {
    const octokit = await ctx.host.github.getOctokit();
    const { data } = await octokit.pulls.get({ owner, repo, pull_number: number });
    return { title: data.title, draft: data.draft, changedFiles: data.changed_files };
  },
});
```

Cursor named each tool after its file; Guild tool names come from the integration. Update any instructions that mention the old names, such as `inspect_pr`. Check the real names with `guild integration operation list guildai~github --json`.

**3. Replace connections with integrations**

Each MCP or host connection becomes the catalog integration for the same service. Register only the operations in the connection's `tools` list, and leave out anything in `disallowedTools`.

```bash theme={null}
guild integration list
guild integration operation list <owner~integration> --json
```

For an MCP server with no catalog integration, create one from the server's URL in the web app by choosing the **MCP** protocol in [Create an integration](https://docs.guild.ai/services/create-an-integration.md). MCP-backed integrations export their tools in PascalCase, such as `ExaMcpTools` for an `exa-mcp` integration.

**4. Turn subagents into Guild agents**

Each `bot/subagents/<id>/` and each agent connection becomes its own Guild agent. Call it with `guildAgentTool({ calls: "owner~agent", inputSchema, outputSchema })`.

**5. Test**

```bash theme={null}
pnpm install && pnpm test
git add -A
guild agent test
```

The scaffold has no `test` script, so `pnpm test` passes without running anything. Add a `test` script to `package.json` before you rely on it, such as `"test": "tsc --build && node --test logic.test.mjs"`. If `pnpm install` fails with `ERR_PNPM_IGNORED_BUILDS`, newer pnpm is blocking esbuild's install script. Run `pnpm approve-builds`, approve esbuild, and install again.

`guild agent test` collects files by walking your local directory and honoring `.gitignore`, the same way `guild agent save` does, so new files such as `logic.ts` are uploaded even without `git add`.

Write tools that skipped side effects when `ctx.session.purpose === "eval"` have no such flag on Guild. Test them against a sandbox account.

**6. Publish and add triggers**

A `githubChannel` becomes an event trigger on the GitHub integration, and a schedule file becomes a schedule trigger. Cursor schedules run in UTC, so keep the cron expression as it is.

```bash theme={null}
guild agent save --message "Port from the Cursor Agent SDK" --wait --publish
guild workspace agent add <owner~agent> --workspace <owner~workspace>
guild trigger create --workspace <owner~workspace> --type webhook --agent <owner~agent> \
  --integration github --event pull_request --action opened \
  --input '{"type":"text","text":"Review this pull request: {webhook_payload}"}'
guild trigger create --workspace <owner~workspace> --type time --agent <owner~agent> \
  --frequency CRON --cron-expression "0 9 * * 1-5" \
  --input '{"type":"text","text":"Summarize the open pull requests."}'
```

> [!NOTE]
>
> The first `guild agent save --wait --publish` after `guild agent init` fails with "No saved state… use --force" because of the `.gitignore` the scaffold writes. Add `--force` to that first save for now.

You can also publish with the [Publish Agent to Guild](https://docs.guild.ai/migrations/overview.md#publish-from-github-actions) GitHub Action instead of `guild agent save --publish`. The Action needs an account API key with the `agents:write` scope:

```bash theme={null}
guild api-key create --owner <owner> --name "Publish migrated agent" --scopes agents:write
```

## Credentials and policies

Cursor tools read secrets from `process.env` inside `execute`, and connections use `${NAME}` templates. Recreate each one as a Guild [credential](https://docs.guild.ai/platform/credentials.md) on the matching integration; the credential proxy adds it to each call, so agent code never sees it. Connections that used `cursorAccount: true` stored their OAuth on Cursor's side, so connect those services again in Guild. Non-secret settings become [workspace variables](https://docs.guild.ai/platform/workspace-variables.md).

Guild splits a tool approval into two controls:

* **Who can call it.** Add a [credential policy](https://docs.guild.ai/platform/credential-policies.md) rule scoped to the agent and workspace that allows or denies the operation. DENY wins over ALLOW.
* **Sign-off on each call.** Add the `ui_prompt` built-in and have the agent confirm with the user before it calls the tool. The run pauses until someone answers.

## What doesn't map 1:1

> [accordion] Models
>
> Cursor model IDs, such as `grok-4.5` and `composer-2.5`, have no Guild equivalent, and all Cursor inference is billed through Cursor. Pick a model from a provider Guild supports.

> [accordion] Self-hosting
>
> `agent-sdk serve` runs an agent on your own Node host. Guild is a hosted platform, so self-hosted agents move to Guild's runtime.

> [accordion] Per-agent HTTP and MCP endpoints
>
> Every served Cursor agent has its own HTTP API and MCP endpoint. Guild agents are reached through workspace chat, triggers, and the Guild API.

> [accordion] Hooks, reminders, and dry runs
>
> `defineHook` observers, runtime reminders, tool `effect` and `dryRunResult`, and harness extensions have no equivalent. The Guild session event log records each run's model calls, tool calls, and errors.

> [accordion] Memory journal
>
> The memory hook appends every turn to `memory/journal.jsonl`, shared by all users. Guild has no equivalent across runs. Keep durable state in an outside store reached through an integration.

> [accordion] Channels without a Guild integration
>
> Cursor ships GitLab, Bitbucket, and PagerDuty channels. Check `guild integration list` for the service; if there's no integration, start the agent from an API trigger instead.

> [accordion] Evals
>
> Cursor evals don't run on Guild. Rebuild the important cases as Guild Evaluations or `guild agent test` sessions.

## Three ways to migrate

> [card] [guild-migrate skill](https://docs.guild.ai/migrations/guild-migrate-skill.md)
>
> Ask your coding agent: "Migrate the Cursor agent in `./bot` to Guild." It follows these steps and writes `MIGRATION.md`.

> [card] [Publish Agent to Guild Action](https://docs.guild.ai/migrations/overview.md#publish-from-github-actions)
>
> Commit the port to your repository, then publish it from GitHub Actions with an account API key.

> [card] [Migration agent](https://app.guild.ai/organizations/guildai/agents/guildai~migrate-to-guild)
>
> Point Migrate to Guild at your repository; it opens a draft pull request. The guild-migrate skill ships in the same package.

## Related pages

> [card] [LLM agents](https://docs.guild.ai/guide/llm-agents.md)
>
> `llmAgent`, `systemPrompt`, and modes.

> [card] [Triggers](https://docs.guild.ai/platform/triggers.md)
>
> Event, schedule, and API triggers.

Migrating a team? [Talk to us](https://www.guild.ai/talk-to-sales?utm_source=docs\&utm_medium=referral\&utm_campaign=migrations).
