@cursor/july 0.1.5 → 0.1.6

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.
Files changed (169) hide show
  1. package/dist/ab.d.ts +8 -95
  2. package/dist/ab.d.ts.map +1 -1
  3. package/dist/ab.js +9 -150
  4. package/dist/bin/agent-serve.js +14 -6
  5. package/dist/docs/404.html +2 -2
  6. package/dist/docs/ab.html +4 -4
  7. package/dist/docs/assets/{app.DabPG-io.js → app.DMboGKUD.js} +1 -1
  8. package/dist/docs/assets/chunks/@localSearchIndexroot.O6eP7QZr.js +1 -0
  9. package/dist/docs/assets/chunks/{VPLocalSearchBox.jmyr0bU0.js → VPLocalSearchBox.DkEqEnJU.js} +1 -1
  10. package/dist/docs/assets/chunks/{theme.DysN9-VN.js → theme.ASugdMNm.js} +2 -2
  11. package/dist/docs/assets/deployment.md.BtfEsc9S.js +55 -0
  12. package/dist/docs/assets/deployment.md.BtfEsc9S.lean.js +1 -0
  13. package/dist/docs/assets/example-agents_approval-buddy.md.8R5phXb5.js +10 -0
  14. package/dist/docs/assets/example-agents_approval-buddy.md.8R5phXb5.lean.js +1 -0
  15. package/dist/docs/assets/example-agents_benny.md.B0gjhI-p.js +7 -0
  16. package/dist/docs/assets/example-agents_benny.md.B0gjhI-p.lean.js +1 -0
  17. package/dist/docs/assets/example-agents_bugbot.md.DelIdhxB.js +11 -0
  18. package/dist/docs/assets/example-agents_bugbot.md.DelIdhxB.lean.js +1 -0
  19. package/dist/docs/assets/example-agents_codebase-wiki.md.DC6sgwn0.js +8 -0
  20. package/dist/docs/assets/example-agents_codebase-wiki.md.DC6sgwn0.lean.js +1 -0
  21. package/dist/docs/assets/example-agents_codeowners-review.md.Ku_tG2RY.js +8 -0
  22. package/dist/docs/assets/example-agents_codeowners-review.md.Ku_tG2RY.lean.js +1 -0
  23. package/dist/docs/assets/example-agents_concierge.md.4rQTSMXt.js +23 -0
  24. package/dist/docs/assets/example-agents_concierge.md.4rQTSMXt.lean.js +1 -0
  25. package/dist/docs/assets/example-agents_fsd.md.CzgUrDfi.js +15 -0
  26. package/dist/docs/assets/example-agents_fsd.md.CzgUrDfi.lean.js +1 -0
  27. package/dist/docs/assets/example-agents_index.md.CRqJlnIf.js +2 -0
  28. package/dist/docs/assets/example-agents_index.md.CRqJlnIf.lean.js +1 -0
  29. package/dist/docs/assets/example-agents_knowledge-base.md.BPJiVueF.js +11 -0
  30. package/dist/docs/assets/example-agents_knowledge-base.md.BPJiVueF.lean.js +1 -0
  31. package/dist/docs/assets/example-agents_security-reviewer.md.D2rtwDTO.js +19 -0
  32. package/dist/docs/assets/example-agents_security-reviewer.md.D2rtwDTO.lean.js +1 -0
  33. package/dist/docs/assets/example-agents_slack-agent.md.buLbgvBf.js +5 -0
  34. package/dist/docs/assets/example-agents_slack-agent.md.buLbgvBf.lean.js +1 -0
  35. package/dist/docs/assets/example-agents_weather-agent.md.C9Qv-W0o.js +24 -0
  36. package/dist/docs/assets/example-agents_weather-agent.md.C9Qv-W0o.lean.js +1 -0
  37. package/dist/docs/assets/index.md.COiu-1jL.js +20 -0
  38. package/dist/docs/assets/{index.md.Cylk70gg.lean.js → index.md.COiu-1jL.lean.js} +1 -1
  39. package/dist/docs/assets/reference_cli.md.D189RBCH.js +60 -0
  40. package/dist/docs/assets/reference_cli.md.D189RBCH.lean.js +1 -0
  41. package/dist/docs/building-with-agents.html +4 -4
  42. package/dist/docs/concepts.html +4 -4
  43. package/dist/docs/deployment.html +58 -17
  44. package/dist/docs/evals.html +4 -4
  45. package/dist/docs/example-agents/approval-buddy.html +34 -0
  46. package/dist/docs/example-agents/benny.html +31 -0
  47. package/dist/docs/example-agents/bugbot.html +35 -0
  48. package/dist/docs/example-agents/codebase-wiki.html +32 -0
  49. package/dist/docs/example-agents/codeowners-review.html +32 -0
  50. package/dist/docs/example-agents/concierge.html +47 -0
  51. package/dist/docs/example-agents/fsd.html +39 -0
  52. package/dist/docs/example-agents/index.html +26 -0
  53. package/dist/docs/example-agents/knowledge-base.html +35 -0
  54. package/dist/docs/example-agents/security-reviewer.html +43 -0
  55. package/dist/docs/example-agents/slack-agent.html +29 -0
  56. package/dist/docs/example-agents/weather-agent.html +48 -0
  57. package/dist/docs/guides/agent-to-agent.html +4 -4
  58. package/dist/docs/guides/cloud-runtime.html +5 -5
  59. package/dist/docs/guides/github.html +4 -4
  60. package/dist/docs/guides/human-in-the-loop.html +4 -4
  61. package/dist/docs/guides/slack.html +4 -4
  62. package/dist/docs/guides/webhooks.html +4 -4
  63. package/dist/docs/hashmap.json +1 -1
  64. package/dist/docs/hillclimbing.html +4 -4
  65. package/dist/docs/index.html +7 -7
  66. package/dist/docs/quickstart.html +4 -4
  67. package/dist/docs/reference/agent-config.html +4 -4
  68. package/dist/docs/reference/channels.html +4 -4
  69. package/dist/docs/reference/cli.html +52 -30
  70. package/dist/docs/reference/connections.html +4 -4
  71. package/dist/docs/reference/hooks.html +4 -4
  72. package/dist/docs/reference/http-api.html +4 -4
  73. package/dist/docs/reference/instructions.html +4 -4
  74. package/dist/docs/reference/playground.html +4 -4
  75. package/dist/docs/reference/project-layout.html +4 -4
  76. package/dist/docs/reference/schedules.html +4 -4
  77. package/dist/docs/reference/sessions.html +4 -4
  78. package/dist/docs/reference/skills.html +4 -4
  79. package/dist/docs/reference/subagents.html +4 -4
  80. package/dist/docs/reference/tools.html +4 -4
  81. package/dist/docs/scaffolding-agents.html +4 -4
  82. package/dist/docs/storage.html +4 -4
  83. package/dist/docs/troubleshooting.html +4 -4
  84. package/dist/evals.d.ts +4 -61
  85. package/dist/evals.d.ts.map +1 -1
  86. package/dist/evals.js +3 -66
  87. package/dist/index.d.ts +1 -1
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/internal/ab-collector.d.ts +7 -5
  90. package/dist/internal/ab-collector.d.ts.map +1 -1
  91. package/dist/internal/ab-collector.js +3 -14
  92. package/dist/internal/ab-snapshot.d.ts +2 -4
  93. package/dist/internal/ab-snapshot.d.ts.map +1 -1
  94. package/dist/internal/cli-ax.d.ts +18 -3
  95. package/dist/internal/cli-ax.d.ts.map +1 -1
  96. package/dist/internal/cli-ax.js +80 -42
  97. package/dist/internal/cli-deploy.js +1 -1
  98. package/dist/internal/discovery.js +3 -3
  99. package/dist/internal/eval-run-store.d.ts +33 -30
  100. package/dist/internal/eval-run-store.d.ts.map +1 -1
  101. package/dist/internal/eval-run-store.js +84 -96
  102. package/dist/internal/init-project.d.ts.map +1 -1
  103. package/dist/internal/init-project.js +3 -2
  104. package/dist/internal/playground-proxy.d.ts +5 -5
  105. package/dist/internal/playground-proxy.js +3 -3
  106. package/dist/internal/resolve-prod-target.d.ts +30 -0
  107. package/dist/internal/resolve-prod-target.d.ts.map +1 -1
  108. package/dist/internal/resolve-prod-target.js +74 -2
  109. package/dist/internal/server.d.ts.map +1 -1
  110. package/dist/internal/server.js +5 -3
  111. package/dist/internal/session-engine.d.ts +1 -2
  112. package/dist/internal/session-engine.d.ts.map +1 -1
  113. package/dist/internal/session-engine.js +14 -31
  114. package/dist/internal/storage-coordinator.d.ts +16 -15
  115. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  116. package/dist/internal/storage-coordinator.js +73 -80
  117. package/dist/playground/assets/cursor-icons-16-CQ50JpfO.woff2 +0 -0
  118. package/dist/playground/assets/index-7GJIUFQj.css +1 -0
  119. package/dist/playground/assets/index-mux9aj5P.js +319 -0
  120. package/dist/playground/index.html +2 -2
  121. package/dist/storage.d.ts +51 -10
  122. package/dist/storage.d.ts.map +1 -1
  123. package/dist/storage.js +27 -10
  124. package/docs/README.md +34 -5
  125. package/docs/deployment.md +352 -149
  126. package/docs/example-agents/approval-buddy.md +270 -0
  127. package/docs/example-agents/benny.md +186 -0
  128. package/docs/example-agents/bugbot.md +231 -0
  129. package/docs/example-agents/codebase-wiki.md +174 -0
  130. package/docs/example-agents/codeowners-review.md +195 -0
  131. package/docs/example-agents/concierge.md +205 -0
  132. package/docs/example-agents/fsd.md +330 -0
  133. package/docs/example-agents/index.md +102 -0
  134. package/docs/example-agents/knowledge-base.md +171 -0
  135. package/docs/example-agents/security-reviewer.md +296 -0
  136. package/docs/example-agents/slack-agent.md +146 -0
  137. package/docs/example-agents/weather-agent.md +302 -0
  138. package/docs/reference/cli.md +546 -147
  139. package/package.json +1 -1
  140. package/src/ab.ts +9 -261
  141. package/src/bin/agent-serve.ts +14 -6
  142. package/src/evals.ts +4 -118
  143. package/src/index.ts +2 -0
  144. package/src/internal/ab-collector.ts +12 -22
  145. package/src/internal/ab-snapshot.ts +2 -4
  146. package/src/internal/cli-ax.ts +101 -45
  147. package/src/internal/cli-deploy.ts +1 -1
  148. package/src/internal/discovery.ts +2 -2
  149. package/src/internal/eval-run-store.ts +86 -100
  150. package/src/internal/init-project.ts +3 -2
  151. package/src/internal/playground-proxy.ts +5 -5
  152. package/src/internal/resolve-prod-target.ts +101 -3
  153. package/src/internal/server.ts +5 -3
  154. package/src/internal/session-engine.ts +9 -29
  155. package/src/internal/storage-coordinator.ts +109 -101
  156. package/src/storage.ts +79 -14
  157. package/dist/docs/assets/chunks/@localSearchIndexroot.QwK5BtEH.js +0 -1
  158. package/dist/docs/assets/deployment.md.DTKwE15Z.js +0 -14
  159. package/dist/docs/assets/deployment.md.DTKwE15Z.lean.js +0 -1
  160. package/dist/docs/assets/index.md.Cylk70gg.js +0 -20
  161. package/dist/docs/assets/reference_cli.md.Bv6pOxcF.js +0 -38
  162. package/dist/docs/assets/reference_cli.md.Bv6pOxcF.lean.js +0 -1
  163. package/dist/internal/json-dir-store.d.ts +0 -32
  164. package/dist/internal/json-dir-store.d.ts.map +0 -1
  165. package/dist/internal/json-dir-store.js +0 -100
  166. package/dist/playground/assets/cursor-icons-outline-BxTT_FVJ.woff2 +0 -0
  167. package/dist/playground/assets/index-BEauYlII.css +0 -1
  168. package/dist/playground/assets/index-BtM0wEGg.js +0 -319
  169. package/src/internal/json-dir-store.ts +0 -109
@@ -1,54 +1,277 @@
1
1
  ---
2
2
  title: "Deployment"
3
- description: "Run agentkit on a real host: the auth model, credentials, durable state, single-box and Docker setups, and the production flags."
3
+ description: "Deploy agentkit with Cursor-managed hosting or on infrastructure you control."
4
4
  ---
5
5
 
6
- # Deployment
7
-
8
- agentkit is a plain Node HTTP server. It runs anywhere Node
9
- 22.13+ runs: a VM, a container platform, ECS. This page covers the parts
10
- that matter beyond local development: who can reach the server, where
11
- credentials and state live, and the flags that change meaning in
12
- production.
13
-
14
- ## The security model in one minute
15
-
16
- Everything defaults to loopback-only. Until you change something, no
17
- route is reachable from another machine. `serve` binds `127.0.0.1`
18
- unless you pass `--host`. Every route runs an auth-policy chain whose
19
- default, `localDevStrict()`, admits direct loopback callers only, rejects
20
- requests carrying proxy-forwarding headers (`X-Forwarded-For`,
21
- `X-Real-IP`, `Forwarded`, `X-Forwarded-Host`), and requires a loopback
22
- `Host` header. A same-host reverse proxy, a tunnel, or a DNS-rebinding
23
- page can't silently re-expose the API.
24
-
25
- Three ways to open it up, in order of preference:
26
-
27
- 1. **`--bearer-token <secret>`** replaces the default with
28
- `bearerAuth(secret)` on every channel that doesn't author its own
29
- auth. Clients send `Authorization: Bearer <secret>`; the playground
30
- has a token field. Use this for anything shared.
31
- 2. **Authored auth.** Channels declare their own `auth` chains:
32
- `bearerAuth`, signature verification, custom policies. Authored
33
- chains always win over serve-level flags. The GitHub channel is the
34
- model: `allowAll()` at the route plus HMAC verification in the
35
- channel.
36
- 3. **`--allow-anonymous`** replaces the default with `allowAll()`, and
37
- every caller shares one `anonymous` principal. Only behind a trusted
38
- network boundary. The server refuses to start when
39
- `--allow-anonymous` is combined with Cursor account MCP connections,
40
- because any admitted caller could drive the signed-in account's
41
- connectors. Mutually exclusive with `--bearer-token`.
42
-
43
- Session routes also bind to the principal that created the session
44
- (other principals get `403`). A single static bearer token maps every
45
- holder to one shared principal. So it isolates the host, not the users
46
- on it. For per-user isolation, pass a verifier function to `bearerAuth`
47
- that returns a distinct principal per presented token.
48
-
49
- ## Credentials
50
-
51
- A host reads at most five kinds of credentials.
6
+ # Deploy agentkit
7
+
8
+ Both options run the same agent project and HTTP API. Channel delivery
9
+ paths differ. Cursor-managed hosting is preferred for most agents.
10
+
11
+ | Option | Use it when | You manage |
12
+ | --- | --- | --- |
13
+ | 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 |
14
+ | 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 |
15
+
16
+ ## Cursor-managed hosting
17
+
18
+ Cursor builds the selected Git ref into a deployment. The deployment
19
+ exposes a stable URL while Cursor manages its runtime lifecycle.
20
+
21
+ ### Before you deploy
22
+
23
+ - Confirm managed hosting is enabled for the account and team.
24
+ - Sign in with an account holding team-admin deployment permission.
25
+ - Add `@cursor/july` to the agent project.
26
+
27
+ For a GitHub source, install the Cursor GitHub App on the repository
28
+ owner and grant it access to the repository. Cursor builds through its
29
+ repository integration, not your local Git credentials. Commit and push
30
+ the Git ref before deploying it.
31
+
32
+ ### Declare hosting needs
33
+
34
+ If the agent needs extra egress or deployment secrets, add a `hosting`
35
+ block to `agent/agent.ts`:
36
+
37
+ ```ts
38
+ import { defineAgent } from "@cursor/july";
39
+
40
+ export default defineAgent({
41
+ hosting: {
42
+ egressDomains: ["api.weather.example.com"],
43
+ secretNames: ["WEATHER_API_KEY"],
44
+ },
45
+ });
46
+ ```
47
+
48
+ `egressDomains` lists outbound hosts beyond the platform's base policy.
49
+ Enter hostnames without schemes, ports, or paths. One leading `*.`
50
+ wildcard is allowed. Declared domains allow HTTPS and TLS traffic, not
51
+ arbitrary TCP ports.
52
+
53
+ `secretNames` lists the environment variables the agent expects. Names
54
+ use `UPPER_SNAKE_CASE`. Commit names only; set their values after
55
+ creating the deployment. Names beginning with `CURSOR_` are reserved.
56
+
57
+ Run `agentkit 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
+ agentkit login
67
+ agentkit whoami
68
+ agentkit validate
69
+ agentkit 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
+ agentkit 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
+ agentkit deployments
107
+ agentkit deployment weather-agent
108
+ agentkit logs --prod --slug weather-agent
109
+ ```
110
+
111
+ ### Set deployment secrets
112
+
113
+ A deployment must exist before you can set its secrets. Omit values from
114
+ the command line to enter them through the hidden prompt:
115
+
116
+ ```bash
117
+ agentkit secrets set weather-agent WEATHER_API_KEY
118
+ agentkit secrets list weather-agent
119
+ agentkit deploy --dir . --slug weather-agent
120
+ ```
121
+
122
+ The engine reads secret changes on its next deploy. `secrets list`
123
+ returns names and creation times, never values. To set several values
124
+ from automation, pipe one line per name instead of putting values in
125
+ shell arguments.
126
+
127
+ ### Choose durable storage
128
+
129
+ Hosted filesystem state can reset during a deploy or runtime
130
+ replacement. Use [`defineStorage`](./storage.md) to preserve supported
131
+ records across deployments. Self-host with a persistent `--state-root`
132
+ when the complete filesystem must survive.
133
+
134
+ ### Use the hosted agent
135
+
136
+ The CLI handles authentication for `--prod` commands. External clients
137
+ and managed HTTP channels send `X-Agent-Alias-Token`; authored channel
138
+ auth still applies. Use a Cursor relay, Socket Mode, a
139
+ signature-validating intermediary, or self-host when a webhook provider
140
+ can't add this header.
141
+
142
+ Use `--prod` with the normal client commands:
143
+
144
+ ```bash
145
+ agentkit playground --prod --slug weather-agent
146
+ agentkit chat --prod --slug weather-agent
147
+ agentkit run --prod --slug weather-agent --message "Forecast for Paris"
148
+ agentkit sessions --prod --slug weather-agent
149
+ agentkit logs --prod --slug weather-agent
150
+ ```
151
+
152
+ Keep `playground --prod` running while the playground is open. Press
153
+ Ctrl-C to stop it.
154
+
155
+ The first deployment prints a reusable alias token once. Store it
156
+ immediately. Run `agentkit deployment weather-agent` to retrieve the
157
+ stable alias URL later. The token remains valid until rotation and can't
158
+ be retrieved.
159
+
160
+ External HTTP clients send the alias token on every request:
161
+
162
+ ```bash
163
+ curl "$AGENT_ALIAS_URL/v1/health" \
164
+ -H "X-Agent-Alias-Token: $AGENT_ALIAS_TOKEN"
165
+ ```
166
+
167
+ `--prod` commands don't use the alias token. If it is lost or exposed,
168
+ rotate it. The old token stops working immediately:
169
+
170
+ ```bash
171
+ agentkit rotate-token weather-agent
172
+ ```
173
+
174
+ ### Connect GitHub
175
+
176
+ Let the hosted engine pull Cursor SCM events. Repeat
177
+ `--cursor-events-repo` for each repository whose events should wake the
178
+ agent:
179
+
180
+ ```bash
181
+ agentkit deploy --dir . \
182
+ --slug pr-approver \
183
+ --cursor-events-repo acme/checkout \
184
+ --cursor-events-repo acme/payments
185
+ ```
186
+
187
+ The agent still needs a `githubChannel()` declaration for the events it
188
+ handles. This delivery path needs no public GitHub webhook URL. The
189
+ flag requires Cursor SCM-event access for the deployment credential.
190
+
191
+ For outbound GitHub calls, use `githubChannel({ cursorAccount: true })`
192
+ and grant the team's Cursor GitHub App access to each repository.
193
+ Alternatively, add dedicated GitHub credentials as deployment secrets.
194
+ See the [GitHub guide](./guides/github.md).
195
+
196
+ ### Connect Slack
197
+
198
+ Hosted Slack supports the team's Cursor Slack app or a dedicated Socket
199
+ Mode app.
200
+
201
+ Use the Cursor Slack app when mentions and direct messages are enough:
202
+
203
+ ```ts
204
+ import { slackChannel } from "@cursor/july/channels/slack";
205
+
206
+ export default slackChannel({
207
+ cursorAccount: true,
208
+ agentName: "PrApprover",
209
+ });
210
+ ```
211
+
212
+ The team must have the Cursor Slack app installed and Slack event relay
213
+ access enabled. This mode needs no Slack token secrets. It doesn't
214
+ support channel-post watches, tool approvals, or interactivity.
215
+
216
+ Use a dedicated Socket Mode app for those features or a separate bot
217
+ identity:
218
+
219
+ ```ts
220
+ import { slackChannel } from "@cursor/july/channels/slack";
221
+
222
+ export default slackChannel({ envPrefix: "PR_APPROVER" });
223
+ ```
224
+
225
+ The prefix selects the deployment secret names:
226
+
227
+ ```bash
228
+ agentkit secrets set pr-approver \
229
+ PR_APPROVER_SLACK_BOT_TOKEN \
230
+ PR_APPROVER_SLACK_APP_TOKEN
231
+ agentkit deploy --dir . --slug pr-approver
232
+ ```
233
+
234
+ Without `envPrefix`, a dedicated app reads `SLACK_BOT_TOKEN` and
235
+ `SLACK_APP_TOKEN`. Socket Mode needs no inbound URL. See the
236
+ [Slack guide](./guides/slack.md).
237
+
238
+ ### Update or stop a deployment
239
+
240
+ Redeploy the same slug after pushing a new Git ref. The stable alias
241
+ continues to point at the active generation. Follow the same source rules
242
+ from [Deploy from Git](#deploy-from-git).
243
+
244
+ ```bash
245
+ agentkit deploy --dir /path/to/my-agent --slug weather-agent
246
+ agentkit stop weather-agent
247
+ ```
248
+
249
+ `stop` waits for the deployment to stop unless you pass `--no-wait`.
250
+ See the [CLI reference](./reference/cli.md#deploy) for the full command
251
+ reference.
252
+
253
+ ## Self-host agentkit
254
+
255
+ agentkit runs as a Node HTTP server on Node 22.13 or newer. You can host
256
+ it on a VM, container platform, or ECS.
257
+
258
+ ### The security model in one minute
259
+
260
+ `serve` binds to loopback and admits direct local callers by default.
261
+ Choose one of these options before exposing it:
262
+
263
+ 1. Pass `--bearer-token <secret>` for a shared host.
264
+ 2. Define channel-specific auth for routes with their own credentials or
265
+ signatures.
266
+ 3. Use `--allow-anonymous` only behind an authenticating proxy.
267
+
268
+ A static bearer token maps every holder to one principal. Use authored
269
+ auth when callers need separate identities. See
270
+ [Channels](./reference/channels.md#auth-policies) for policy details.
271
+
272
+ ### Credentials
273
+
274
+ A self-hosted server can read these credentials.
52
275
 
53
276
  | Credential | Used for | Provide it as |
54
277
  | --- | --- | --- |
@@ -58,95 +281,82 @@ A host reads at most five kinds of credentials.
58
281
  | GitHub API | outbound API calls | a GitHub App (`GITHUB_APP_ID` + `GITHUB_APP_PRIVATE_KEY` + installation id) or `GITHUB_TOKEN` / `gh auth login` |
59
282
  | MCP connection tokens | authored MCP connections | whatever env vars your `mcp-connections/*.ts` read |
60
283
 
61
- The Cursor credential resolves in one order everywhere: an explicit
62
- `apiKey` option or `--api-key`, then `CURSOR_API_KEY`, then the key
63
- stored by `agentkit login`. `agentkit whoami` shows which
64
- one is active and why. `logout` removes the stored key, and revoking it
65
- in the Cursor dashboard invalidates it immediately. Mint a dedicated key
66
- per host. `login` names it after the hostname, so you can revoke each one
67
- independently.
284
+ Use a dedicated Cursor key per host. `agentkit whoami` shows the active
285
+ credential. `logout` removes the stored key from the host; revoke the key
286
+ in the Cursor dashboard to invalidate it. See
287
+ [CLI authentication](./reference/cli.md#login--logout--whoami) for
288
+ credential resolution.
68
289
 
69
- ## State
290
+ ### State
70
291
 
71
- Durable state lives under `--state-root` (default
72
- `<project>/.agentkit`): sessions, event streams, session
73
- workspaces, the SDK conversation store, channel buffers, cursor-events
74
- offsets.
292
+ Place `--state-root` on a persistent volume outside the agent
293
+ repository, and back it up. Sessions survive restarts only when their
294
+ state does. See [Storage](./storage.md) and
295
+ [Sessions](./reference/sessions.md) for persistence and layout details.
75
296
 
76
- Put it on a persistent volume. Sessions survive restarts and streams
77
- replay only if the directory does. Put it outside any repository, to keep
78
- ambient `AGENTS.md` or `.cursor` rules out of session workspaces.
79
- `/var/lib/agentkit` is a good home. Back it up like the
80
- conversation history it is. Deleting a session directory removes that
81
- session from the server. The SDK conversation store under `runner/` keeps
82
- its own copy until you delete it too.
297
+ ### A single box
83
298
 
84
- ## A single box
85
-
86
- The minimum production host is two processes and a private network:
299
+ A single-host deployment needs one supervised `serve` process on a
300
+ private network. Export the Cursor key and a generated bearer token in
301
+ the supervisor environment:
87
302
 
88
303
  ```bash
304
+ export CURSOR_API_KEY="<cursor-api-key>"
305
+ export AGENTKIT_BEARER_TOKEN="$(openssl rand -hex 32)"
306
+
89
307
  # the server: all agents under one port
90
- CURSOR_API_KEY=… GITHUB_WEBHOOK_SECRET=… \
91
- agentkit serve --dir /srv/agents --port 3000 --host 127.0.0.1 \
92
- --state-root /var/lib/agentkit --bearer-token "$CURSOR_AGENT_KIT_TOKEN"
308
+ agentkit serve --dir /srv/agents --port 3000 --host 127.0.0.1 \
309
+ --state-root /var/lib/agent-serve \
310
+ --bearer-token "$AGENTKIT_BEARER_TOKEN"
311
+ ```
312
+
313
+ Slack Socket Mode needs no inbound network. For GitHub, prefer
314
+ `--cursor-events --repo owner/repo` on `serve` so the host pulls events
315
+ through Cursor without a public webhook URL.
316
+
317
+ Webhook forwarding is the fallback. It needs one additional process.
318
+ Before starting or restarting `serve`, export the same strong
319
+ `GITHUB_WEBHOOK_SECRET` in both supervisor environments. Then install
320
+ the extension, authenticate `gh`, and start the forwarder. Repository
321
+ forwarding requires repo-admin access; organization forwarding with
322
+ `--org` requires org-owner access.
323
+
324
+ ```bash
325
+ export GITHUB_WEBHOOK_SECRET="$(openssl rand -hex 32)"
326
+ agentkit github doctor --install
327
+ gh auth login
93
328
 
94
329
  # GitHub agents only: ONE forwarder relaying live deliveries to loopback
95
- GITHUB_TOKEN= GH_TOKEN= GITHUB_WEBHOOK_SECRET=… \
330
+ GITHUB_TOKEN= GH_TOKEN= \
96
331
  agentkit github forward --dir /srv/agents --repo owner/repo
97
332
  ```
98
333
 
99
- Run both under a supervisor. systemd is the durable choice. tmux
100
- survives SSH disconnects but not reboots. On a TTY, `serve` restarts on
101
- Enter (it reloads agent code). Under a supervisor, restart the process.
102
- Sessions and streams are durable either way.
103
-
104
- Inbound network requirements are small. Slack needs none at all: Socket
105
- Mode dials out. Prefer GitHub via `--cursor-events` so the host pulls
106
- events with no inbound network (see
107
- [Pull events from Cursor](./guides/github.md#pull-events-from-cursor)).
108
- A public HTTPS webhook endpoint with the secret on both ends, or the
109
- forwarder above, is the fallback when you terminate GitHub deliveries
110
- yourself. Humans reach the playground through your private network or a
111
- tunnel.
112
- Keep `--bearer-token` on, because tunneled requests arrive from loopback
113
- and IP-based policies can't tell them apart.
334
+ Run long-lived processes under a supervisor. systemd survives reboots;
335
+ tmux survives only SSH disconnects. On a TTY, press Enter to reload
336
+ agent code. Humans reach the playground through a private network or
337
+ tunnel. Keep `--bearer-token` on because tunneled requests arrive from
338
+ loopback and IP-based policies can't tell them apart.
114
339
 
115
340
  Health checks: `GET /v1/health` at the host level (made for ALB and ECS
116
341
  checks), and each agent also serves `/<slug>/v1/health`.
117
342
 
118
- ## Docker
343
+ ### Containers
119
344
 
120
- The repository includes a [`Dockerfile`](../Dockerfile) used for an
121
- internal deployment. It builds the workspace deps and the playground
122
- bundle and runs multi-agent serve as a non-root user. But its `CMD`
123
- passes `--allow-anonymous`, because that deployment sits behind an
124
- authenticating proxy. Don't copy that flag without one. That image also
125
- enables `--cursor-events` to pull GitHub events (see the
126
- [GitHub guide](./guides/github.md#pull-events-from-cursor)).
345
+ Build the image with Node 22.13 or newer, the agent source, and its
346
+ package dependencies. Run `agentkit serve` as a non-root user:
127
347
 
128
- Until the package rename ships, the real image paths are still
129
- `dist/bin/agent-serve.js` and `/var/lib/agent-serve` (see the
130
- [rename table](./README.md#run-the-cli)). The baseline shape to copy,
131
- shown with post-rename names:
132
-
133
- ```dockerfile
134
- # build: pnpm install + pnpm --filter @cursor/july run build
135
- # run (today: agent-serve.js and /var/lib/agent-serve):
136
- CMD ["node", "--import", "tsx", "dist/bin/agentkit.js", "serve", \
137
- "--dir", "examples", "--mode", "multi", \
138
- "--host", "0.0.0.0", "--port", "3000", \
139
- "--state-root", "/var/lib/agentkit"]
348
+ ```bash
349
+ agentkit serve --dir /srv/agents --mode multi \
350
+ --host 0.0.0.0 --port 3000 \
351
+ --state-root /var/lib/agent-serve \
352
+ --bearer-token "$AGENTKIT_BEARER_TOKEN"
140
353
  ```
141
354
 
142
- Inside a container, `--host 0.0.0.0` is required. Pair it with real auth
143
- (`--bearer-token`, or authored auth per channel), or keep the container
144
- on a private network. Mount the state root as a volume, install `git` and
145
- `gh` in the image when channels do host-side GitHub work (the shipped
146
- Dockerfile does), and inject secrets as env vars at start. Nothing secret
147
- belongs in the image.
355
+ Mount the state root as a persistent volume and inject secrets at
356
+ startup. Install `git` and `gh` when channels need host-side GitHub work.
357
+ Don't put secrets in the image.
148
358
 
149
- ## Serve many agents from one process
359
+ ### Serve many agents from one process
150
360
 
151
361
  Point `serve` at a folder of agent projects and every child mounts under
152
362
  its directory name on one port. One process, one state root, one
@@ -157,62 +367,55 @@ agentkit serve --dir /srv/agents
157
367
  # index at /, each agent at /<slug>/v1/*, /<slug>/playground
158
368
  ```
159
369
 
160
- `GET /` is a web index of every agent and `GET /v1/agents` is the JSON
161
- equivalent. Sessions are isolated per agent under `<stateRoot>/<slug>/`.
162
- Each agent needs its own Slack app and token pair. Agents without tokens
163
- mount with their Slack channel idle.
164
-
165
370
  Only mount what you mean to run. Every mounted agent's channels are live,
166
371
  and webhook-driven agents spend model budget on every wake. `--mode
167
- single` serves exactly one agent at the unslugged `/v1/*` when that agent
168
- is the whole host.
372
+ single` serves exactly one agent at the unslugged `/v1/*` when the agent
373
+ is the whole host. See the [HTTP API](./reference/http-api.md) for route
374
+ layout and the [Slack guide](./guides/slack.md) for multi-agent token
375
+ setup.
169
376
 
170
- ## The production flags
377
+ ### The production flags
171
378
 
172
- These flags change meaning between a laptop and production.
379
+ Use these settings in production:
173
380
 
174
381
  | Flag | In production |
175
382
  | --- | --- |
176
- | `--dev` | Off. Dev mode admits unsigned loopback GitHub deliveries, widens playground session listing on loopback, and never auto-fires schedules. |
177
- | `--bearer-token` | On for anything shared. Rotate it like any secret. |
178
- | `--allow-anonymous` | Only behind a trusted network boundary (e.g. an SSO-authenticating load balancer). Also widens playground session listing/streaming so Slack and webhook sessions appear. Never with account-level connectors. |
179
- | `--state-root` | A persistent volume, outside any repo. |
383
+ | `--dev` | Leave off. Dev mode admits unsigned loopback GitHub deliveries, widens playground session listing on loopback, and never auto-fires schedules. |
384
+ | `--bearer-token` | Set on shared hosts unless an authenticating proxy is the trust boundary and you use `--allow-anonymous` instead. |
385
+ | `--allow-anonymous` | Use only behind an authenticating network boundary. It also widens playground session access so Slack and webhook sessions appear. |
386
+ | `--state-root` | Place on a persistent volume outside any repo. |
180
387
  | `--public-url` | Set when cloud-runtime turns must call back into peers on this host. |
181
- | `--no-playground` | Optional hardening when no human needs the UI. Also removes the `/` and `/v1/agents` index routes. |
182
- | `--no-docs` | Removes the documentation site at `/docs`. |
183
- | `--no-schedules` | Disable cron firing on secondary hosts so schedules run exactly once. |
388
+ | `--no-playground` | Set when no human needs the UI. |
389
+ | `--no-docs` | Set to remove the documentation site at `/docs`. |
390
+ | `--no-schedules` | Set on secondary hosts so schedules run exactly once. |
184
391
 
185
392
  Schedules fire on their cron cadence (UTC) in production mode. They have
186
393
  no cross-host coordination, so enable them on exactly one serving process
187
394
  per project.
188
395
 
189
- ## Restarts and upgrades
396
+ ### Restarts and upgrades
190
397
 
191
- Restarts are safe by design: sessions, event streams, and the SDK
192
- conversation store are durable under the state root. Two caveats. Parked
193
- tool approvals don't survive a restart. They resolve as interrupted, and
194
- you re-run the turn. And reminders created with in-memory `run` handlers
195
- are disarmed after a restart (`handler_lost_on_restart`). Re-arm them
196
- from the code path that created them, or use prompt-form reminders.
398
+ Restarts preserve sessions, event streams, and SDK conversation state
399
+ under the state root. Parked approvals and in-memory reminders don't
400
+ survive a restart; re-run or recreate them afterward.
197
401
 
198
- ## Observability
402
+ ### Observability
199
403
 
200
- `GET /v1/logs` (per agent) exposes recent server log lines: the same ring
201
- buffer the playground's Logs tab polls. For structured export, author a
202
- [hook](./reference/hooks.md). Subscribe to `turn.completed`,
203
- `turn.failed`, and `action.result`, then forward to your metrics system.
204
- Hook errors are logged, never fatal. For any incident, the session
205
- streams under the state root are the source of truth:
206
- `agentkit trajectory --events <file>` summarizes one, and the
207
- playground renders it.
404
+ Use [`agentkit logs`](./reference/cli.md#logs) for runtime output,
405
+ [hooks](./reference/hooks.md) for metrics export, and
406
+ [session traces](./reference/sessions.md#how-do-i-inspect-a-saved-event-stream)
407
+ for incident review.
208
408
 
209
409
  ## What's next
210
410
 
211
411
  Continue with these pages:
212
412
 
413
+ - [CLI reference](./reference/cli.md#deploy): deploy, inspect, stop, and
414
+ rotate hosted agents
415
+ - [Storage](./storage.md): preserve supported records across engine
416
+ replacements
213
417
  - [Channels](./reference/channels.md#auth-policies): the auth policies
214
418
  in detail
215
- - [GitHub guide](./guides/github.md): delivery paths that don't need a
216
- public URL
419
+ - [GitHub guide](./guides/github.md): delivery paths without a public URL
217
420
  - [Troubleshooting](./troubleshooting.md): the symptom table for when a
218
421
  deploy misbehaves