@cursor/july 0.1.91 → 0.1.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -0
- package/dist/docs/404.html +3 -1
- package/dist/docs/ab.html +4 -2
- package/dist/docs/ab.md +338 -0
- package/dist/docs/building-with-agents.html +4 -2
- package/dist/docs/building-with-agents.md +124 -0
- package/dist/docs/concepts.html +4 -2
- package/dist/docs/concepts.md +174 -0
- package/dist/docs/deployment.html +4 -2
- package/dist/docs/deployment.md +464 -0
- package/dist/docs/evals.html +4 -2
- package/dist/docs/evals.md +481 -0
- package/dist/docs/example-agents/approval-buddy.html +4 -2
- package/dist/docs/example-agents/approval-buddy.md +266 -0
- package/dist/docs/example-agents/benny.html +4 -2
- package/dist/docs/example-agents/benny.md +182 -0
- package/dist/docs/example-agents/bugbot.html +4 -2
- package/dist/docs/example-agents/bugbot.md +229 -0
- package/dist/docs/example-agents/codebase-wiki.html +4 -2
- package/dist/docs/example-agents/codebase-wiki.md +170 -0
- package/dist/docs/example-agents/codeowners-review.html +4 -2
- package/dist/docs/example-agents/codeowners-review.md +192 -0
- package/dist/docs/example-agents/concierge.html +4 -2
- package/dist/docs/example-agents/concierge.md +201 -0
- package/dist/docs/example-agents/fsd.html +4 -2
- package/dist/docs/example-agents/fsd.md +329 -0
- package/dist/docs/example-agents/index.html +4 -2
- package/dist/docs/example-agents/index.md +102 -0
- package/dist/docs/example-agents/knowledge-base.html +4 -2
- package/dist/docs/example-agents/knowledge-base.md +168 -0
- package/dist/docs/example-agents/oncall.html +4 -2
- package/dist/docs/example-agents/oncall.md +212 -0
- package/dist/docs/example-agents/security-reviewer.html +4 -2
- package/dist/docs/example-agents/security-reviewer.md +265 -0
- package/dist/docs/example-agents/slack-agent.html +4 -2
- package/dist/docs/example-agents/slack-agent.md +142 -0
- package/dist/docs/example-agents/weather-agent.html +4 -2
- package/dist/docs/example-agents/weather-agent.md +296 -0
- package/dist/docs/guides/agent-to-agent.html +4 -2
- package/dist/docs/guides/agent-to-agent.md +113 -0
- package/dist/docs/guides/cloud-runtime.html +4 -2
- package/dist/docs/guides/cloud-runtime.md +131 -0
- package/dist/docs/guides/convert-automation.html +4 -2
- package/dist/docs/guides/convert-automation.md +171 -0
- package/dist/docs/guides/github.html +4 -2
- package/dist/docs/guides/github.md +287 -0
- package/dist/docs/guides/human-in-the-loop.html +4 -2
- package/dist/docs/guides/human-in-the-loop.md +126 -0
- package/dist/docs/guides/mcp-oauth.html +4 -2
- package/dist/docs/guides/mcp-oauth.md +159 -0
- package/dist/docs/guides/opentelemetry.html +4 -2
- package/dist/docs/guides/opentelemetry.md +209 -0
- package/dist/docs/guides/slack.html +4 -2
- package/dist/docs/guides/slack.md +337 -0
- package/dist/docs/guides/webhooks.html +4 -2
- package/dist/docs/guides/webhooks.md +463 -0
- package/dist/docs/hillclimbing.html +4 -2
- package/dist/docs/hillclimbing.md +88 -0
- package/dist/docs/index.html +4 -2
- package/dist/docs/index.md +179 -0
- package/dist/docs/llms-full.txt +11518 -0
- package/dist/docs/llms.txt +75 -0
- package/dist/docs/quickstart.html +4 -2
- package/dist/docs/quickstart.md +364 -0
- package/dist/docs/reference/agent-config.html +4 -2
- package/dist/docs/reference/agent-config.md +256 -0
- package/dist/docs/reference/artifacts.html +4 -2
- package/dist/docs/reference/artifacts.md +112 -0
- package/dist/docs/reference/channels.html +4 -2
- package/dist/docs/reference/channels.md +255 -0
- package/dist/docs/reference/cli.html +4 -2
- package/dist/docs/reference/cli.md +957 -0
- package/dist/docs/reference/connections.html +4 -2
- package/dist/docs/reference/connections.md +268 -0
- package/dist/docs/reference/hooks.html +4 -2
- package/dist/docs/reference/hooks.md +102 -0
- package/dist/docs/reference/http-api.html +4 -2
- package/dist/docs/reference/http-api.md +267 -0
- package/dist/docs/reference/instructions.html +4 -2
- package/dist/docs/reference/instructions.md +74 -0
- package/dist/docs/reference/playground.html +4 -2
- package/dist/docs/reference/playground.md +62 -0
- package/dist/docs/reference/project-layout.html +4 -2
- package/dist/docs/reference/project-layout.md +107 -0
- package/dist/docs/reference/prompt.html +4 -2
- package/dist/docs/reference/prompt.md +42 -0
- package/dist/docs/reference/schedules.html +4 -2
- package/dist/docs/reference/schedules.md +215 -0
- package/dist/docs/reference/sessions.html +4 -2
- package/dist/docs/reference/sessions.md +170 -0
- package/dist/docs/reference/skills.html +4 -2
- package/dist/docs/reference/skills.md +83 -0
- package/dist/docs/reference/subagents.html +4 -2
- package/dist/docs/reference/subagents.md +71 -0
- package/dist/docs/reference/tools.html +4 -2
- package/dist/docs/reference/tools.md +298 -0
- package/dist/docs/scaffolding-agents.html +4 -2
- package/dist/docs/scaffolding-agents.md +130 -0
- package/dist/docs/storage.html +4 -2
- package/dist/docs/storage.md +219 -0
- package/dist/docs/templates/agentic-owners.html +4 -2
- package/dist/docs/templates/agentic-owners.md +92 -0
- package/dist/docs/templates/demo.html +4 -2
- package/dist/docs/templates/demo.md +79 -0
- package/dist/docs/templates/pr-autofixer.html +4 -2
- package/dist/docs/templates/pr-autofixer.md +131 -0
- package/dist/docs/templates/security-reviewer.html +4 -2
- package/dist/docs/templates/security-reviewer.md +84 -0
- package/dist/docs/templates/triage.html +4 -2
- package/dist/docs/templates/triage.md +98 -0
- package/dist/docs/troubleshooting.html +4 -2
- package/dist/docs/troubleshooting.md +111 -0
- package/dist/internal/init-scaffold.d.ts.map +1 -1
- package/dist/internal/init-scaffold.js +1 -0
- package/dist/internal/playground/static.d.ts.map +1 -1
- package/dist/internal/playground/static.js +2 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +3 -1
- package/package.json +2 -2
- package/skills/ab/SKILL.md +3 -0
- package/skills/create-agent/SKILL.md +3 -0
- package/skills/debug/SKILL.md +3 -0
- package/skills/evals/SKILL.md +3 -0
- package/skills/framework-map/SKILL.md +3 -0
- package/skills/github/SKILL.md +3 -0
- package/skills/hillclimb/SKILL.md +3 -0
- package/skills/mcp-auth/SKILL.md +3 -0
- package/skills/otel/SKILL.md +3 -0
- package/skills/setup-slack/SKILL.md +3 -0
- package/src/internal/init-scaffold.ts +1 -0
- package/src/internal/playground/static.ts +2 -0
- package/src/internal/session-engine.ts +4 -6
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
# Deploy the Agent SDK
|
|
2
|
+
|
|
3
|
+
Both options run the same agent project and HTTP API. Channel delivery
|
|
4
|
+
paths differ. Cursor-managed hosting is preferred for most agents.
|
|
5
|
+
|
|
6
|
+
| Option | Use it when | You manage |
|
|
7
|
+
| --- | --- | --- |
|
|
8
|
+
| Cursor-managed hosting (preferred) | You want the shortest path from a Git repo to a running agent | Agent code, external storage, declared egress, and deployment secrets |
|
|
9
|
+
| Self-hosting | You need your own network, proxy, persistent filesystem, or process controls | Agent code, Node process, TLS, auth, secrets, durable state, monitoring, and upgrades |
|
|
10
|
+
|
|
11
|
+
## Cursor-managed hosting
|
|
12
|
+
|
|
13
|
+
Cursor builds the selected Git ref into a deployment. The deployment
|
|
14
|
+
exposes a stable URL while Cursor manages its runtime lifecycle.
|
|
15
|
+
|
|
16
|
+
### Before you deploy
|
|
17
|
+
|
|
18
|
+
- Confirm managed hosting is enabled for the account and team.
|
|
19
|
+
- Sign in with an account holding team-admin deployment permission.
|
|
20
|
+
- Add `@cursor/july` to the agent project.
|
|
21
|
+
|
|
22
|
+
For a GitHub source, install the Cursor GitHub App on the repository
|
|
23
|
+
owner and grant it access to the repository. Cursor builds through its
|
|
24
|
+
repository integration, not your local Git credentials. Commit and push
|
|
25
|
+
the Git ref before deploying it.
|
|
26
|
+
|
|
27
|
+
### Declare hosting needs
|
|
28
|
+
|
|
29
|
+
If the agent needs extra egress or deployment secrets, add a `hosting`
|
|
30
|
+
block to `agent/agent.ts`:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { defineAgent } from "@cursor/july";
|
|
34
|
+
|
|
35
|
+
export default defineAgent({
|
|
36
|
+
hosting: {
|
|
37
|
+
egressDomains: ["api.weather.example.com"],
|
|
38
|
+
secretNames: ["WEATHER_API_KEY"],
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`egressDomains` lists outbound hosts beyond the platform's base policy.
|
|
44
|
+
Enter hostnames without schemes, ports, or paths. One leading `*.`
|
|
45
|
+
wildcard is allowed. Declared domains allow HTTPS and TLS traffic, not
|
|
46
|
+
arbitrary TCP ports.
|
|
47
|
+
|
|
48
|
+
`secretNames` lists the environment variables the agent expects. Names
|
|
49
|
+
use `UPPER_SNAKE_CASE`. Commit names only; set their values after
|
|
50
|
+
creating the deployment. Names beginning with `CURSOR_` are reserved.
|
|
51
|
+
|
|
52
|
+
For `defineConnection({ url, oauth: true })`, declare
|
|
53
|
+
`MCP_OAUTH_<CONNECTION>_*` in `secretNames`, authorize with
|
|
54
|
+
`agent-sdk mcp oauth <connection> --store`, then redeploy. See
|
|
55
|
+
[Host MCP OAuth](/docs/guides/mcp-oauth.md).
|
|
56
|
+
|
|
57
|
+
Run `agent-sdk validate` before deploying. It reports invalid domains and
|
|
58
|
+
secret names as warnings, so fix them even when validation exits zero.
|
|
59
|
+
|
|
60
|
+
### Deploy from Git
|
|
61
|
+
|
|
62
|
+
Sign in, validate the project, and deploy it:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cd my-agent
|
|
66
|
+
agent-sdk login
|
|
67
|
+
agent-sdk whoami
|
|
68
|
+
agent-sdk validate
|
|
69
|
+
agent-sdk deploy
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Inside a Git checkout, `deploy` infers the HTTPS `origin` URL, current
|
|
73
|
+
branch or detached commit, agent path, and deployment slug. Explicit
|
|
74
|
+
flags override each value:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
agent-sdk deploy \
|
|
78
|
+
--repo https://github.com/acme/agents \
|
|
79
|
+
--ref main \
|
|
80
|
+
--path agents/weather \
|
|
81
|
+
--slug weather-agent
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
> [!IMPORTANT]
|
|
85
|
+
> `--slug` doesn't retain source or Cursor-event settings. Run every
|
|
86
|
+
> repo-backed deploy from the pushed checkout, or pass `--repo`, `--ref`,
|
|
87
|
+
> `--path`, and any `--cursor-events-repo` flags again.
|
|
88
|
+
|
|
89
|
+
Deploy reads the agent from Git; it doesn't upload local files. Keep the
|
|
90
|
+
local `hosting` block in sync with the selected ref. A nested `--path`
|
|
91
|
+
must contain `package.json` and be installable from its own directory.
|
|
92
|
+
|
|
93
|
+
For a directory containing several agent projects, choose one from the
|
|
94
|
+
TTY prompt, pass `--slug <name>`, or deploy each child with `--all`.
|
|
95
|
+
Pass `--team <id>` when the signed-in account has no default team or you
|
|
96
|
+
want another team.
|
|
97
|
+
|
|
98
|
+
`--all` creates a separate deployment for each child. Self-host when the
|
|
99
|
+
agents must share one multi-agent process.
|
|
100
|
+
|
|
101
|
+
The command waits up to ten minutes for a running engine. Use
|
|
102
|
+
`--no-wait` to return after Cursor accepts the deployment, then inspect
|
|
103
|
+
it separately:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
agent-sdk deployments
|
|
107
|
+
agent-sdk deployment weather-agent
|
|
108
|
+
agent-sdk logs --prod --slug weather-agent
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Set deployment secrets
|
|
112
|
+
|
|
113
|
+
A deployment must exist before you can set its secrets. Pass names only.
|
|
114
|
+
Enter values at the hidden prompt, or pipe one line per name:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
agent-sdk secrets set weather-agent WEATHER_API_KEY
|
|
118
|
+
agent-sdk secrets list weather-agent
|
|
119
|
+
agent-sdk deploy --dir . --slug weather-agent
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`secrets list` returns names and creation times, never values. The
|
|
123
|
+
engine reads secret changes on its next deploy.
|
|
124
|
+
|
|
125
|
+
Do not pass `NAME=VALUE` on the command line. That form lands in shell
|
|
126
|
+
history and in agent-captured terminals. The CLI refuses it unless you
|
|
127
|
+
add `--from-argv`. For non-interactive input without argv, redirect a
|
|
128
|
+
file or pipe stdin.
|
|
129
|
+
|
|
130
|
+
### Credential output in terminals
|
|
131
|
+
|
|
132
|
+
Treat any command that prints a secret as a credential event. Keep it
|
|
133
|
+
out of agent-captured terminals when you can.
|
|
134
|
+
|
|
135
|
+
| Command | What prints |
|
|
136
|
+
| --- | --- |
|
|
137
|
+
| `secrets set` / `secrets list` | Names only. Values never print. |
|
|
138
|
+
| `rotate-pod-credential` | Masked key only. |
|
|
139
|
+
| First `deploy` / `rotate-token` | Full alias token once. Save it outside the agent transcript; it cannot be retrieved later. |
|
|
140
|
+
| `deployment --json` | May include short-lived `engineAccess.headers`. Treat JSON as a credential. |
|
|
141
|
+
|
|
142
|
+
Do not verify secrets with `echo "$SECRET"`, `printenv`, or by pasting
|
|
143
|
+
values into chat. Use `secrets list` for names, then redeploy and exercise
|
|
144
|
+
the feature that needs the secret.
|
|
145
|
+
|
|
146
|
+
### Choose durable storage
|
|
147
|
+
|
|
148
|
+
Hosted filesystem state can reset during a deploy or runtime
|
|
149
|
+
replacement. Prefer
|
|
150
|
+
[`cursorHostedStorage`](/docs/storage.md) (`@cursor/july/storage/cursor-hosted`)
|
|
151
|
+
so durable records land in Cursor's Bugbot `agent_serve_*` tables through
|
|
152
|
+
a control-plane HTTP proxy (pod credential auth — no database URL in the
|
|
153
|
+
engine). Do not put `BUGBOTDB_URL` or `AGENT_SERVE_DEPLOYMENT_ID` in
|
|
154
|
+
`hosting.secretNames`. Self-host with your own `defineStorage` backend or
|
|
155
|
+
a persistent `--state-root` when the complete filesystem must survive.
|
|
156
|
+
|
|
157
|
+
### Use the hosted agent
|
|
158
|
+
|
|
159
|
+
The CLI handles authentication for `--prod` commands. External HTTP
|
|
160
|
+
clients that hit the stable alias URL must send `X-Agent-Alias-Token` on
|
|
161
|
+
every request. Authored channel auth still runs after that gate.
|
|
162
|
+
|
|
163
|
+
Use `publicEndpoint()` on a custom channel that verifies its own provider
|
|
164
|
+
signature. Cursor then serves that channel path without the alias token.
|
|
165
|
+
The built-in session API still requires the token.
|
|
166
|
+
|
|
167
|
+
Use a relay or self-host when the channel cannot authenticate requests
|
|
168
|
+
itself.
|
|
169
|
+
|
|
170
|
+
Use `--prod` with the normal client commands:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
agent-sdk playground --prod --slug weather-agent
|
|
174
|
+
agent-sdk chat --prod --slug weather-agent
|
|
175
|
+
agent-sdk run --prod --slug weather-agent --message "Forecast for Paris"
|
|
176
|
+
agent-sdk sessions --prod --slug weather-agent
|
|
177
|
+
agent-sdk logs --prod --slug weather-agent
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Keep `playground --prod` running while the playground is open. Press
|
|
181
|
+
Ctrl-C to stop it.
|
|
182
|
+
|
|
183
|
+
The first deployment prints a reusable alias token once. Store it
|
|
184
|
+
immediately. Run `agent-sdk deployment weather-agent` to retrieve the
|
|
185
|
+
stable alias URL later. The token remains valid until rotation and can't
|
|
186
|
+
be retrieved.
|
|
187
|
+
|
|
188
|
+
External HTTP clients send the alias token on every request:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
curl "$AGENT_ALIAS_URL/v1/health" \
|
|
192
|
+
-H "X-Agent-Alias-Token: $AGENT_ALIAS_TOKEN"
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
`--prod` commands don't use the alias token. If it is lost or exposed,
|
|
196
|
+
rotate it. The old token stops working immediately:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
agent-sdk rotate-token weather-agent
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Connect GitHub
|
|
203
|
+
|
|
204
|
+
Let the hosted engine pull Cursor SCM events. Repeat
|
|
205
|
+
`--cursor-events-repo` for each repository whose events should wake the
|
|
206
|
+
agent:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
agent-sdk deploy --dir . \
|
|
210
|
+
--slug pr-approver \
|
|
211
|
+
--cursor-events-repo acme/checkout \
|
|
212
|
+
--cursor-events-repo acme/payments
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The agent still needs a `githubChannel()` declaration for the events it
|
|
216
|
+
handles. This delivery path needs no public GitHub webhook URL. The
|
|
217
|
+
flag requires Cursor SCM-event access for the deployment credential.
|
|
218
|
+
|
|
219
|
+
For outbound GitHub calls, use `githubChannel({ cursorAccount: true })`
|
|
220
|
+
and grant the team's Cursor GitHub App access to each repository.
|
|
221
|
+
Alternatively, add dedicated GitHub credentials as deployment secrets.
|
|
222
|
+
See the [GitHub guide](/docs/guides/github.md).
|
|
223
|
+
|
|
224
|
+
### Connect Slack
|
|
225
|
+
|
|
226
|
+
Hosted Slack supports the team's Cursor Slack app or a dedicated Socket
|
|
227
|
+
Mode app.
|
|
228
|
+
|
|
229
|
+
Use the Cursor Slack app when mentions and direct messages are enough:
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
import { slackChannel } from "@cursor/july/channels/slack";
|
|
233
|
+
|
|
234
|
+
export default slackChannel({
|
|
235
|
+
cursorAccount: true,
|
|
236
|
+
agentName: "PrApprover",
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The team must have the Cursor Slack app installed and Slack event relay
|
|
241
|
+
access enabled. This mode needs no Slack token secrets. It doesn't
|
|
242
|
+
support channel-post watches, tool approvals, or interactivity.
|
|
243
|
+
|
|
244
|
+
Use a dedicated Socket Mode app for those features or a separate bot
|
|
245
|
+
identity:
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
import { slackChannel } from "@cursor/july/channels/slack";
|
|
249
|
+
|
|
250
|
+
export default slackChannel({ envPrefix: "PR_APPROVER" });
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Provision the dedicated app from the dashboard. Open the deployment
|
|
254
|
+
under **Deployed Agents** at
|
|
255
|
+
[cursor.com/dashboard](https://cursor.com/dashboard), switch to
|
|
256
|
+
**Details**, and expand **Slack** under **Integrations**. **Add to
|
|
257
|
+
Slack** connects the workspace with a one-time authorization, and
|
|
258
|
+
**Create Slack app** creates and installs the app, then stores its
|
|
259
|
+
tokens as deployment secrets automatically. Redeploy when prompted so
|
|
260
|
+
the running agent picks them up. See
|
|
261
|
+
[Provision from the dashboard](/docs/guides/slack.md#provision-from-the-dashboard)
|
|
262
|
+
for the walkthrough, including workspace-admin approval.
|
|
263
|
+
|
|
264
|
+
If you created the Slack app by hand instead, set its tokens as
|
|
265
|
+
deployment secrets yourself. The prefix selects the secret names:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
agent-sdk secrets set pr-approver \
|
|
269
|
+
PR_APPROVER_SLACK_BOT_TOKEN \
|
|
270
|
+
PR_APPROVER_SLACK_APP_TOKEN
|
|
271
|
+
agent-sdk deploy --dir . --slug pr-approver
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Without `envPrefix`, a dedicated app reads `SLACK_BOT_TOKEN` and
|
|
275
|
+
`SLACK_APP_TOKEN`. Socket Mode needs no inbound URL. See the
|
|
276
|
+
[Slack guide](/docs/guides/slack.md).
|
|
277
|
+
|
|
278
|
+
### Update, stop, or delete a deployment
|
|
279
|
+
|
|
280
|
+
Redeploy the same slug after pushing a new Git ref. The stable alias
|
|
281
|
+
continues to point at the active generation. Follow the same source rules
|
|
282
|
+
from [Deploy from Git](#deploy-from-git).
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
agent-sdk deploy --dir /path/to/my-agent --slug weather-agent
|
|
286
|
+
agent-sdk stop weather-agent
|
|
287
|
+
agent-sdk delete weather-agent
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
`stop` waits for the deployment to stop unless you pass `--no-wait`.
|
|
291
|
+
`delete` removes the deployment and waits until it is gone.
|
|
292
|
+
See the [CLI reference](/docs/reference/cli.md#deploy) for the full command
|
|
293
|
+
reference.
|
|
294
|
+
|
|
295
|
+
## Self-host the Agent SDK
|
|
296
|
+
|
|
297
|
+
The Agent SDK runs as a Node HTTP server on Node 22.13 or newer. You can host
|
|
298
|
+
it on a VM, container platform, or ECS.
|
|
299
|
+
|
|
300
|
+
### The security model in one minute
|
|
301
|
+
|
|
302
|
+
`serve` binds to loopback and admits direct local callers by default.
|
|
303
|
+
Choose one of these options before exposing it:
|
|
304
|
+
|
|
305
|
+
1. Pass `--bearer-token <secret>` for a shared host.
|
|
306
|
+
2. Define channel-specific auth for routes with their own credentials or
|
|
307
|
+
signatures.
|
|
308
|
+
3. Use `--allow-anonymous` only behind an authenticating proxy.
|
|
309
|
+
|
|
310
|
+
A static bearer token maps every holder to one principal. Use authored
|
|
311
|
+
auth when callers need separate identities. See
|
|
312
|
+
[Channels](/docs/reference/channels.md#auth-policies) for policy details.
|
|
313
|
+
|
|
314
|
+
### Credentials
|
|
315
|
+
|
|
316
|
+
A self-hosted server can read these credentials.
|
|
317
|
+
|
|
318
|
+
| Credential | Used for | Provide it as |
|
|
319
|
+
| --- | --- | --- |
|
|
320
|
+
| Cursor API key | model turns, cloud runtime, Cursor account MCP connections | `agent-sdk login` (stores a revocable key), `CURSOR_API_KEY`, or `--api-key` / `serve({ apiKey })` |
|
|
321
|
+
| Slack tokens | Slack channels | `<PREFIX>_SLACK_BOT_TOKEN` + `<PREFIX>_SLACK_APP_TOKEN` per agent |
|
|
322
|
+
| GitHub webhook secret | delivery signature verification | `GITHUB_WEBHOOK_SECRET`, same value on server and signer |
|
|
323
|
+
| GitHub API | outbound API calls | a GitHub App (`GITHUB_APP_ID` + `GITHUB_APP_PRIVATE_KEY` + installation id) or `GITHUB_TOKEN` / `gh auth login` |
|
|
324
|
+
| MCP connection tokens | authored MCP connections | env vars your `mcp-connections/*.ts` read, or host OAuth secrets from `agent-sdk mcp oauth <name> --store` (`MCP_OAUTH_*`; see [Host MCP OAuth](/docs/guides/mcp-oauth.md)) |
|
|
325
|
+
|
|
326
|
+
Use a dedicated Cursor key per host. `agent-sdk whoami` shows the active
|
|
327
|
+
credential. `logout` removes the stored key from the host; revoke the key
|
|
328
|
+
in the Cursor dashboard to invalidate it. See
|
|
329
|
+
[CLI authentication](/docs/reference/cli.md#login-logout-whoami) for
|
|
330
|
+
credential resolution.
|
|
331
|
+
|
|
332
|
+
### State
|
|
333
|
+
|
|
334
|
+
Place `--state-root` on a persistent volume outside the agent
|
|
335
|
+
repository, and back it up. Sessions survive restarts only when their
|
|
336
|
+
state does. See [Storage](/docs/storage.md) and
|
|
337
|
+
[Sessions](/docs/reference/sessions.md) for persistence and layout details.
|
|
338
|
+
|
|
339
|
+
### A single box
|
|
340
|
+
|
|
341
|
+
A single-host deployment needs one supervised `serve` process on a
|
|
342
|
+
private network. Export the Cursor key and a generated bearer token in
|
|
343
|
+
the supervisor environment:
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
export CURSOR_API_KEY="<cursor-api-key>"
|
|
347
|
+
export AGENT_SDK_BEARER_TOKEN="$(openssl rand -hex 32)"
|
|
348
|
+
|
|
349
|
+
# the server: all agents under one port
|
|
350
|
+
agent-sdk serve --dir /srv/agents --port 3000 --host 127.0.0.1 \
|
|
351
|
+
--state-root /var/lib/agent-serve \
|
|
352
|
+
--bearer-token "$AGENT_SDK_BEARER_TOKEN"
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Slack Socket Mode needs no inbound network. For GitHub, prefer
|
|
356
|
+
`--cursor-events --repo owner/repo` on `serve` so the host pulls events
|
|
357
|
+
through Cursor without a public webhook URL.
|
|
358
|
+
|
|
359
|
+
Webhook forwarding is the fallback. It needs one additional process.
|
|
360
|
+
Before starting or restarting `serve`, export the same strong
|
|
361
|
+
`GITHUB_WEBHOOK_SECRET` in both supervisor environments. Then install
|
|
362
|
+
the extension, authenticate `gh`, and start the forwarder. Repository
|
|
363
|
+
forwarding requires repo-admin access; organization forwarding with
|
|
364
|
+
`--org` requires org-owner access.
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
export GITHUB_WEBHOOK_SECRET="$(openssl rand -hex 32)"
|
|
368
|
+
agent-sdk github doctor --install
|
|
369
|
+
gh auth login
|
|
370
|
+
|
|
371
|
+
# GitHub agents only: ONE forwarder relaying live deliveries to loopback
|
|
372
|
+
GITHUB_TOKEN= GH_TOKEN= \
|
|
373
|
+
agent-sdk github forward --dir /srv/agents --repo owner/repo
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
Run long-lived processes under a supervisor. systemd survives reboots;
|
|
377
|
+
tmux survives only SSH disconnects. On a TTY, press Enter to reload
|
|
378
|
+
agent code. Humans reach the playground through a private network or
|
|
379
|
+
tunnel. Keep `--bearer-token` on because tunneled requests arrive from
|
|
380
|
+
loopback and IP-based policies can't tell them apart.
|
|
381
|
+
|
|
382
|
+
Health checks: `GET /v1/health` at the host level (made for ALB and ECS
|
|
383
|
+
checks), and each agent also serves `/<slug>/v1/health`.
|
|
384
|
+
|
|
385
|
+
### Containers
|
|
386
|
+
|
|
387
|
+
Build the image with Node 22.13 or newer, the agent source, and its
|
|
388
|
+
package dependencies. Run `agent-sdk serve` as a non-root user:
|
|
389
|
+
|
|
390
|
+
```bash
|
|
391
|
+
agent-sdk serve --dir /srv/agents --mode multi \
|
|
392
|
+
--host 0.0.0.0 --port 3000 \
|
|
393
|
+
--state-root /var/lib/agent-serve \
|
|
394
|
+
--bearer-token "$AGENT_SDK_BEARER_TOKEN"
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Mount the state root as a persistent volume and inject secrets at
|
|
398
|
+
startup. Install `git` and `gh` when channels need host-side GitHub work.
|
|
399
|
+
Don't put secrets in the image.
|
|
400
|
+
|
|
401
|
+
### Serve many agents from one process
|
|
402
|
+
|
|
403
|
+
Point `serve` at a folder of agent projects and every child mounts under
|
|
404
|
+
its directory name on one port. One process, one state root, one
|
|
405
|
+
credential:
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
agent-sdk serve --dir /srv/agents
|
|
409
|
+
# index at /, each agent at /<slug>/v1/*, /<slug>/playground
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
Only mount what you mean to run. Every mounted agent's channels are live,
|
|
413
|
+
and webhook-driven agents spend model budget on every wake. `--mode
|
|
414
|
+
single` serves exactly one agent at the unslugged `/v1/*` when the agent
|
|
415
|
+
is the whole host. See the [HTTP API](/docs/reference/http-api.md) for route
|
|
416
|
+
layout and the [Slack guide](/docs/guides/slack.md) for multi-agent token
|
|
417
|
+
setup.
|
|
418
|
+
|
|
419
|
+
### The production flags
|
|
420
|
+
|
|
421
|
+
Use these settings in production:
|
|
422
|
+
|
|
423
|
+
| Flag | In production |
|
|
424
|
+
| --- | --- |
|
|
425
|
+
| `--dev` | Leave off. Dev mode admits unsigned loopback GitHub deliveries, widens playground session listing on loopback, and never auto-fires schedules. |
|
|
426
|
+
| `--bearer-token` | Set on shared hosts unless an authenticating proxy is the trust boundary and you use `--allow-anonymous` instead. |
|
|
427
|
+
| `--allow-anonymous` | Use only behind an authenticating network boundary. It also widens playground session access so Slack and webhook sessions appear. |
|
|
428
|
+
| `--state-root` | Place on a persistent volume outside any repo. |
|
|
429
|
+
| `--public-url` | Set when cloud-runtime turns must call back into peers on this host. |
|
|
430
|
+
| `--no-playground` | Set when no human needs the UI. |
|
|
431
|
+
| `--no-docs` | Set to remove the documentation site at `/docs`. |
|
|
432
|
+
| `--no-schedules` | Set on secondary hosts so schedules run exactly once. |
|
|
433
|
+
|
|
434
|
+
Schedules fire on their cron cadence (UTC) in production mode. They have
|
|
435
|
+
no cross-host coordination, so enable them on exactly one serving process
|
|
436
|
+
per project.
|
|
437
|
+
|
|
438
|
+
### Restarts and upgrades
|
|
439
|
+
|
|
440
|
+
Restarts preserve sessions, event streams, and SDK conversation state
|
|
441
|
+
under the state root. Parked approvals and in-memory reminders don't
|
|
442
|
+
survive a restart; re-run or recreate them afterward.
|
|
443
|
+
|
|
444
|
+
### Observability
|
|
445
|
+
|
|
446
|
+
Use [`agent-sdk logs`](/docs/reference/cli.md#logs) for runtime output,
|
|
447
|
+
[OpenTelemetry](/docs/guides/opentelemetry.md) for OTLP traces and metrics,
|
|
448
|
+
[hooks](/docs/reference/hooks.md) for in-process subscribers, and
|
|
449
|
+
[session traces](/docs/reference/sessions.md#how-do-i-inspect-a-saved-event-stream)
|
|
450
|
+
for incident review.
|
|
451
|
+
|
|
452
|
+
## What's next
|
|
453
|
+
|
|
454
|
+
Continue with these pages:
|
|
455
|
+
|
|
456
|
+
- [CLI reference](/docs/reference/cli.md#deploy): deploy, inspect, stop, and
|
|
457
|
+
rotate hosted agents
|
|
458
|
+
- [Storage](/docs/storage.md): preserve supported records across engine
|
|
459
|
+
replacements
|
|
460
|
+
- [Channels](/docs/reference/channels.md#auth-policies): the auth policies
|
|
461
|
+
in detail
|
|
462
|
+
- [GitHub guide](/docs/guides/github.md): delivery paths without a public URL
|
|
463
|
+
- [Troubleshooting](/docs/troubleshooting.md): the symptom table for when a
|
|
464
|
+
deploy misbehaves
|