@cursor/july 0.1.9 → 0.1.11
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 +1 -0
- package/dist/bin/agent-serve.js +26 -3
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +2 -1
- package/dist/channels/github/types.d.ts +4 -0
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +1 -1
- package/dist/channels/slack/dispatch.d.ts +13 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +36 -11
- package/dist/channels/slack/eval-directive.d.ts +63 -0
- package/dist/channels/slack/eval-directive.d.ts.map +1 -0
- package/dist/channels/slack/eval-directive.js +283 -0
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +4 -2
- package/dist/channels/slack/types.d.ts +7 -0
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/connections.d.ts +10 -5
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +10 -5
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.Ciosf24M.js → app.BcXUGca7.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BIbvK8M1.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BcRDly7n.js → VPLocalSearchBox.CWur6XGZ.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CMpbjdfx.js → theme.BnvulOX2.js} +2 -2
- package/dist/docs/assets/{deployment.md.DC5-ImcM.js → deployment.md.TecHo0_2.js} +3 -3
- package/dist/docs/assets/{deployment.md.DC5-ImcM.lean.js → deployment.md.TecHo0_2.lean.js} +1 -1
- package/dist/docs/assets/guides_mcp-oauth.md.DqmEOQY1.js +29 -0
- package/dist/docs/assets/guides_mcp-oauth.md.DqmEOQY1.lean.js +1 -0
- package/dist/docs/assets/{index.md.COiu-1jL.js → index.md.t0TM2Qzz.js} +3 -3
- package/dist/docs/assets/{index.md.COiu-1jL.lean.js → index.md.t0TM2Qzz.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.D189RBCH.js → reference_cli.md.B74NrVzb.js} +5 -4
- package/dist/docs/assets/{reference_cli.md.D189RBCH.lean.js → reference_cli.md.B74NrVzb.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.zaEYCLHT.js → reference_connections.md.CsSr3rDz.js} +9 -4
- package/dist/docs/assets/{reference_connections.md.zaEYCLHT.lean.js → reference_connections.md.CsSr3rDz.lean.js} +1 -1
- package/dist/docs/assets/reference_prompt.md.BaiweQxE.js +1 -0
- package/dist/docs/assets/reference_prompt.md.BaiweQxE.lean.js +1 -0
- package/dist/docs/assets/{reference_tools.md.CqgJroI0.js → reference_tools.md.BRSDnTbN.js} +16 -3
- package/dist/docs/assets/{reference_tools.md.CqgJroI0.lean.js → reference_tools.md.BRSDnTbN.lean.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.DkovjS7h.js → troubleshooting.md.CmQkmnzC.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.DkovjS7h.lean.js → troubleshooting.md.CmQkmnzC.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/evals.html +4 -4
- package/dist/docs/example-agents/approval-buddy.html +4 -4
- package/dist/docs/example-agents/benny.html +4 -4
- package/dist/docs/example-agents/bugbot.html +4 -4
- package/dist/docs/example-agents/codebase-wiki.html +4 -4
- package/dist/docs/example-agents/codeowners-review.html +4 -4
- package/dist/docs/example-agents/concierge.html +4 -4
- package/dist/docs/example-agents/fsd.html +4 -4
- package/dist/docs/example-agents/index.html +4 -4
- package/dist/docs/example-agents/knowledge-base.html +4 -4
- package/dist/docs/example-agents/oncall.html +4 -4
- package/dist/docs/example-agents/security-reviewer.html +4 -4
- package/dist/docs/example-agents/slack-agent.html +4 -4
- package/dist/docs/example-agents/weather-agent.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +53 -0
- package/dist/docs/guides/slack.html +4 -4
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +6 -6
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +8 -7
- package/dist/docs/reference/connections.html +13 -8
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +4 -4
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/prompt.html +33 -0
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +5 -5
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +20 -7
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/evals.d.ts +39 -0
- package/dist/evals.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +7 -4
- package/dist/internal/cli-mcp-oauth.d.ts +16 -0
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -0
- package/dist/internal/cli-mcp-oauth.js +194 -0
- package/dist/internal/cli-mcp.d.ts +4 -1
- package/dist/internal/cli-mcp.d.ts.map +1 -1
- package/dist/internal/cli-mcp.js +19 -1
- package/dist/internal/corp-ca.d.ts +9 -0
- package/dist/internal/corp-ca.d.ts.map +1 -0
- package/dist/internal/corp-ca.js +44 -0
- package/dist/internal/cursor/account-mcp.d.ts +17 -4
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +105 -17
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +64 -10
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/logs-client.js +1 -1
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +49 -26
- package/dist/internal/mcp-oauth.d.ts +88 -0
- package/dist/internal/mcp-oauth.d.ts.map +1 -0
- package/dist/internal/mcp-oauth.js +385 -0
- package/dist/internal/resolved-connections.d.ts +6 -0
- package/dist/internal/resolved-connections.d.ts.map +1 -1
- package/dist/internal/resolved-connections.js +10 -3
- package/dist/internal/sdk-runner.d.ts +9 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +28 -2
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +24 -6
- package/dist/internal/session-engine.d.ts +30 -10
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +166 -74
- package/dist/internal/sessions-client.d.ts +16 -2
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +30 -13
- package/dist/internal/storage-coordinator.d.ts +11 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +30 -0
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +8 -4
- package/dist/internal/turn-governor.d.ts +54 -0
- package/dist/internal/turn-governor.d.ts.map +1 -0
- package/dist/internal/turn-governor.js +111 -0
- package/dist/playground/assets/{index-C0-QEG4O.js → index-BIGLubwK.js} +46 -46
- package/dist/playground/assets/{index-z3JY9O2x.css → index-C17ZQKDG.css} +1 -1
- package/dist/playground/index.html +2 -2
- package/dist/prompt.d.ts +39 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +70 -0
- package/dist/storage-backends/cursor-hosted.d.ts +10 -0
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +14 -0
- package/dist/types.d.ts +93 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -0
- package/docs/README.md +4 -0
- package/docs/deployment.md +6 -1
- package/docs/guides/mcp-oauth.md +157 -0
- package/docs/reference/cli.md +30 -0
- package/docs/reference/connections.md +32 -2
- package/docs/reference/prompt.md +47 -0
- package/docs/reference/tools.md +21 -0
- package/docs/troubleshooting.md +11 -0
- package/package.json +9 -2
- package/skills/create-agent/SKILL.md +7 -3
- package/skills/framework-map/SKILL.md +1 -0
- package/skills/mcp-auth/SKILL.md +138 -0
- package/src/bin/agent-serve.ts +30 -3
- package/src/channels/github/github-channel.ts +2 -0
- package/src/channels/github/types.ts +4 -0
- package/src/channels/slack/cursor-account.ts +2 -0
- package/src/channels/slack/dispatch.ts +49 -0
- package/src/channels/slack/eval-directive.ts +348 -0
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/slack-channel.ts +3 -0
- package/src/channels/slack/types.ts +7 -0
- package/src/connections.ts +10 -5
- package/src/evals.ts +43 -0
- package/src/index.ts +3 -0
- package/src/internal/cli-ax.ts +10 -4
- package/src/internal/cli-mcp-oauth.ts +254 -0
- package/src/internal/cli-mcp.ts +25 -2
- package/src/internal/cursor/account-mcp.ts +153 -41
- package/src/internal/discovery.ts +70 -8
- package/src/internal/distribution.ts +1 -0
- package/src/internal/logs-client.ts +1 -1
- package/src/internal/mcp-host.ts +33 -9
- package/src/internal/mcp-oauth.ts +496 -0
- package/src/internal/resolved-connections.ts +20 -5
- package/src/internal/sdk-runner.ts +37 -1
- package/src/internal/server.ts +28 -6
- package/src/internal/session-engine.ts +192 -76
- package/src/internal/sessions-client.ts +51 -15
- package/src/internal/storage-coordinator.ts +36 -0
- package/src/internal/stream-progress.ts +8 -0
- package/src/internal/turn-governor.ts +145 -0
- package/src/prompt.ts +83 -0
- package/src/storage-backends/cursor-hosted.ts +21 -0
- package/src/types.ts +92 -6
- package/dist/docs/assets/chunks/@localSearchIndexroot.D154Detj.js +0 -1
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Host MCP OAuth"
|
|
3
|
+
description: "Authorize defineConnection({ url, oauth: true }) with agentkit mcp oauth, store tokens locally, and push MCP_OAUTH_* secrets to hosted deployments."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Host MCP OAuth
|
|
7
|
+
|
|
8
|
+
Use host MCP OAuth when your agent talks to a remote MCP server that
|
|
9
|
+
speaks OAuth, and you want credentials on the serve host (or the hosted
|
|
10
|
+
engine) instead of a Cursor account connector. Local login writes tokens
|
|
11
|
+
next to your Cursor credentials. `--store` copies them onto the
|
|
12
|
+
deployment as secrets so prod can reconnect after a redeploy.
|
|
13
|
+
|
|
14
|
+
The companion skill is
|
|
15
|
+
[`skills/mcp-auth/SKILL.md`](../../skills/mcp-auth/SKILL.md).
|
|
16
|
+
|
|
17
|
+
## What can host MCP OAuth do?
|
|
18
|
+
|
|
19
|
+
- Authorize `defineConnection({ url, oauth: true })` with a browser PKCE
|
|
20
|
+
flow (`agentkit mcp oauth <connection>`)
|
|
21
|
+
- Keep tokens in `~/.config/agent-serve/mcp-auth.json`, bound to that
|
|
22
|
+
connection's resource URL
|
|
23
|
+
- Upsert deployment secrets with `--store` so hosted engines seed the
|
|
24
|
+
same tokens from env
|
|
25
|
+
- Keep privileged servers off the model with `hostOnly: true` while
|
|
26
|
+
tools still call them through `ctx.host.mcp`
|
|
27
|
+
|
|
28
|
+
Prefer a Cursor account MCP connection
|
|
29
|
+
(`defineConnection({ cursorAccount: true, servers: […] })`) when the
|
|
30
|
+
connector already lives in the signed-in account dashboard. Use host
|
|
31
|
+
OAuth when the server is yours (or private to your network) and the host
|
|
32
|
+
must hold tokens.
|
|
33
|
+
|
|
34
|
+
## How do I declare a host-OAuth connection?
|
|
35
|
+
|
|
36
|
+
Add one file under `agent/mcp-connections/`. The filename is the
|
|
37
|
+
connection name you pass to the CLI and to `host.mcp`.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// agent/mcp-connections/inventory.ts
|
|
41
|
+
import { defineConnection } from "@cursor/july/connections";
|
|
42
|
+
|
|
43
|
+
export default defineConnection({
|
|
44
|
+
url: "https://mcp.example.com/inventory",
|
|
45
|
+
oauth: true,
|
|
46
|
+
hostOnly: true,
|
|
47
|
+
description:
|
|
48
|
+
"Inventory MCP (privileged). Call only from host tools, not the model.",
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Rules of the road:
|
|
53
|
+
|
|
54
|
+
- `oauth: true` is required for `agentkit mcp oauth`
|
|
55
|
+
- `hostOnly: true` hides the server from the model; `ctx.host.mcp` and
|
|
56
|
+
channel handlers still see it
|
|
57
|
+
- Declare expected secret names on the agent when you plan to `--store`:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
// agent/agent.ts
|
|
61
|
+
export default defineAgent({
|
|
62
|
+
// …
|
|
63
|
+
hosting: {
|
|
64
|
+
secretNames: [
|
|
65
|
+
"MCP_OAUTH_INVENTORY_ACCESS_TOKEN",
|
|
66
|
+
"MCP_OAUTH_INVENTORY_REFRESH_TOKEN",
|
|
67
|
+
"MCP_OAUTH_INVENTORY_CLIENT_ID",
|
|
68
|
+
],
|
|
69
|
+
// Hosted engines need an explicit allowlist for non-bootstrap hosts.
|
|
70
|
+
egressDomains: ["mcp.example.com"],
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Secret names follow `MCP_OAUTH_<CONNECTION>_*` where `<CONNECTION>` is
|
|
76
|
+
the connection filename uppercased with non-alphanumerics turned into
|
|
77
|
+
underscores (`inventory` → `MCP_OAUTH_INVENTORY_…`).
|
|
78
|
+
|
|
79
|
+
## How do I authorize locally?
|
|
80
|
+
|
|
81
|
+
From the agent project (Node 22.13+, not Bun):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
agentkit mcp oauth inventory
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
What happens:
|
|
88
|
+
|
|
89
|
+
1. agentkit loads `agent/mcp-connections/inventory.ts` and checks
|
|
90
|
+
`oauth: true`
|
|
91
|
+
2. It opens the authorization URL in your browser
|
|
92
|
+
3. The callback lands on `http://localhost:8787/callback`
|
|
93
|
+
4. Tokens land in `~/.config/agent-serve/mcp-auth.json` (override the
|
|
94
|
+
config dir with `AGENT_SERVE_CONFIG_DIR`)
|
|
95
|
+
|
|
96
|
+
If you're already authorized, the command prints that and exits. Re-run
|
|
97
|
+
it after rotating tokens on the MCP server, or after you change the
|
|
98
|
+
connection URL (tokens are bound to the resource URL).
|
|
99
|
+
|
|
100
|
+
## How do I store credentials on a hosted deployment?
|
|
101
|
+
|
|
102
|
+
Authorize once, then push secrets to the deployment:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
agentkit mcp oauth inventory --store
|
|
106
|
+
# optional:
|
|
107
|
+
# --slug my-agent
|
|
108
|
+
# --team <cursor-team-id>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`--store` upserts:
|
|
112
|
+
|
|
113
|
+
| Secret | Source |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| `MCP_OAUTH_<NAME>_ACCESS_TOKEN` | access token (required) |
|
|
116
|
+
| `MCP_OAUTH_<NAME>_REFRESH_TOKEN` | refresh token when the server returns one |
|
|
117
|
+
| `MCP_OAUTH_<NAME>_CLIENT_ID` | dynamic client id when registration returned one |
|
|
118
|
+
|
|
119
|
+
You must be signed in (`agentkit login`) with permission to set secrets
|
|
120
|
+
on that slug. Secrets apply on the **next** deploy; run
|
|
121
|
+
`agentkit deploy` (or wait for your usual deploy path) after `--store`.
|
|
122
|
+
|
|
123
|
+
On the engine, when `mcp-auth.json` is empty, serve seeds the OAuth
|
|
124
|
+
provider from those env vars so host MCP calls work without a browser
|
|
125
|
+
on the pod.
|
|
126
|
+
|
|
127
|
+
## How do host tools call the server?
|
|
128
|
+
|
|
129
|
+
Keep privileged calls on the host:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
const result = await ctx.host.mcp.callTool(
|
|
133
|
+
"inventory",
|
|
134
|
+
"list_warehouses",
|
|
135
|
+
{ region: "us-east" }
|
|
136
|
+
);
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The model never sees `hostOnly` tools in its MCP namespace list. If the
|
|
140
|
+
agent asks to "check IDE MCP" or run `mcp_auth`, point it at your host
|
|
141
|
+
tool instead.
|
|
142
|
+
|
|
143
|
+
## What if authorization fails?
|
|
144
|
+
|
|
145
|
+
| What you see | What to do |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| `must be defineConnection({ url, oauth: true })` | Add `oauth: true` on that connection, or pick the right connection name |
|
|
148
|
+
| Callback never completes | Keep port `8787` free; finish the browser login on this machine |
|
|
149
|
+
| Hosted calls unauthorized after `--store` | Confirm secrets with `agentkit secrets list <slug>`, then redeploy |
|
|
150
|
+
| Tokens ignored after URL change | Expected: resource URL binding drops stale entries. Re-run `mcp oauth` |
|
|
151
|
+
|
|
152
|
+
## What's next
|
|
153
|
+
|
|
154
|
+
- [MCP connections](../reference/connections.md): transports, `hostOnly`, account MCP
|
|
155
|
+
- [CLI](../reference/cli.md#mcp-oauth): full flag list for `mcp oauth`
|
|
156
|
+
- [Deployment](../deployment.md): secrets, egress, and hosted engines
|
|
157
|
+
- [Fix common agent problems](../troubleshooting.md): more symptom → fix tables
|
package/docs/reference/cli.md
CHANGED
|
@@ -43,6 +43,7 @@ also provide `agentkit slack help` and `agentkit github help`.
|
|
|
43
43
|
| [`rotate-token`](#rotate-token) | Replace a deployment's alias token |
|
|
44
44
|
| [`rotate-pod-credential`](#rotate-pod-credential) | Replace a deployment's pod credential |
|
|
45
45
|
| [`secrets`](#secrets) | Manage deployment secrets |
|
|
46
|
+
| [`mcp oauth`](#mcp-oauth) | Authorize host MCP OAuth; optional `--store` to deployment secrets |
|
|
46
47
|
| [`slack ...`](#slack) | Set up and check Slack channels |
|
|
47
48
|
| [`github ...`](#github) | Forward, replay, and inspect GitHub webhook channels |
|
|
48
49
|
|
|
@@ -86,6 +87,7 @@ agentkit serve [--dir <path>] [--port 3000] [--host 127.0.0.1] [--dev]
|
|
|
86
87
|
[--mode multi|single] [--api-key <key>]
|
|
87
88
|
[--state-root <path>] [--bearer-token <secret> | --allow-anonymous]
|
|
88
89
|
[--allow-anonymous-cursor-github]
|
|
90
|
+
[--allow-anonymous-cursor-account-mcp]
|
|
89
91
|
[--public-url <url>] [--no-schedules] [--no-playground]
|
|
90
92
|
[--no-docs] [--cursor-events --repo owner/name]...
|
|
91
93
|
```
|
|
@@ -109,6 +111,7 @@ Unless `--state-root` is set, each mount uses
|
|
|
109
111
|
| `--bearer-token` | Require this bearer token on routes without authored auth. Mutually exclusive with `--allow-anonymous`. |
|
|
110
112
|
| `--allow-anonymous` | Admit every caller as one `anonymous` principal. Use only behind a trusted network boundary. |
|
|
111
113
|
| `--allow-anonymous-cursor-github` | Allow anonymous callers to drive sessions holding a Cursor account's repo-scoped GitHub credential. Use only behind an authenticating proxy. |
|
|
114
|
+
| `--allow-anonymous-cursor-account-mcp` | Allow anonymous callers to drive Cursor account MCP connectors (`defineConnection({ cursorAccount: true })`). Use only behind an authenticating proxy (hosted alias token counts). |
|
|
112
115
|
| `--public-url` | Set the externally reachable host URL. Cloud-runtime peer connections need it to call back into this server. |
|
|
113
116
|
| `--no-schedules` | Disable the cron runner outside dev mode. |
|
|
114
117
|
| `--no-playground` | Skip the web playground and its build or HMR process. |
|
|
@@ -558,6 +561,33 @@ The command returns only the masked key and revokes the old credential
|
|
|
558
561
|
immediately. Redeploy at once to inject the replacement; the current
|
|
559
562
|
pod can't authenticate to Cursor in between.
|
|
560
563
|
|
|
564
|
+
## mcp oauth
|
|
565
|
+
|
|
566
|
+
`mcp oauth` authorizes a `defineConnection({ url, oauth: true })`
|
|
567
|
+
connection with a browser PKCE flow. Tokens are written to
|
|
568
|
+
`mcp-auth.json` under the agent-serve config dir (default
|
|
569
|
+
`~/.config/agent-serve`). Pass `--store` to upsert matching
|
|
570
|
+
`MCP_OAUTH_<CONNECTION>_*` secrets on the hosted deployment.
|
|
571
|
+
|
|
572
|
+
```bash
|
|
573
|
+
agentkit mcp oauth <connection> [--dir .] [--store] [--slug <slug>] [--team <id>]
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
`<connection>` is the `agent/mcp-connections/<connection>.ts` basename.
|
|
577
|
+
`--slug` defaults to the `--dir` basename. `--team` defaults to the
|
|
578
|
+
signed-in account's team. You need `agentkit login` (or `--api-key`)
|
|
579
|
+
before `--store`.
|
|
580
|
+
|
|
581
|
+
Secret names are `MCP_OAUTH_<NAME>_ACCESS_TOKEN`,
|
|
582
|
+
`_REFRESH_TOKEN`, and `_CLIENT_ID` (`<NAME>` is the connection id in
|
|
583
|
+
upper snake case). Declare them in `hosting.secretNames` so deploy
|
|
584
|
+
validation expects them. Secrets apply on the next deploy.
|
|
585
|
+
|
|
586
|
+
Tokens are bound to the connection's resource URL. Changing the URL
|
|
587
|
+
invalidates the local entry; run `mcp oauth` again.
|
|
588
|
+
|
|
589
|
+
See the [Host MCP OAuth guide](../guides/mcp-oauth.md).
|
|
590
|
+
|
|
561
591
|
## secrets
|
|
562
592
|
|
|
563
593
|
`secrets` manages environment secrets for a deployment.
|
|
@@ -27,6 +27,33 @@ export default defineConnection({
|
|
|
27
27
|
|
|
28
28
|
Tokens come from env vars. Never hardcode them in the file.
|
|
29
29
|
|
|
30
|
+
## Host MCP OAuth
|
|
31
|
+
|
|
32
|
+
For servers that speak OAuth, set `oauth: true` and authorize with the
|
|
33
|
+
CLI. Tokens live in `~/.config/agent-serve/mcp-auth.json`. `--store`
|
|
34
|
+
copies them onto the hosted deployment as `MCP_OAUTH_<NAME>_*` secrets.
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
export default defineConnection({
|
|
38
|
+
url: "https://mcp.example.com/inventory",
|
|
39
|
+
oauth: true,
|
|
40
|
+
hostOnly: true, // model cannot call; host.mcp still can
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
agentkit mcp oauth inventory # browser PKCE → local mcp-auth.json
|
|
46
|
+
agentkit mcp oauth inventory --store # also upsert deployment secrets
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Full walkthrough: [Host MCP OAuth](../guides/mcp-oauth.md). Companion
|
|
50
|
+
skill: [`skills/mcp-auth/SKILL.md`](../../skills/mcp-auth/SKILL.md).
|
|
51
|
+
|
|
52
|
+
Use `hostOnly: true` when only deterministic host tools should call the
|
|
53
|
+
server (deploys, admin APIs). Account MCP
|
|
54
|
+
(`cursorAccount: true`) stays the right choice for connectors already
|
|
55
|
+
linked in the Cursor dashboard.
|
|
56
|
+
|
|
30
57
|
## Local stdio MCP server
|
|
31
58
|
|
|
32
59
|
Run a local MCP server as a child process with `command`.
|
|
@@ -72,8 +99,10 @@ author a `{ command }` MCP connection for those.
|
|
|
72
99
|
> [!CAUTION]
|
|
73
100
|
> Whoever can talk to the agent can drive these connectors, because they
|
|
74
101
|
> are ordinary agent tools. `serve` refuses to start when
|
|
75
|
-
> `--allow-anonymous` is combined with account MCP connections
|
|
76
|
-
> `--
|
|
102
|
+
> `--allow-anonymous` is combined with account MCP connections unless you
|
|
103
|
+
> also pass `--allow-anonymous-cursor-account-mcp` (trusted boundary only —
|
|
104
|
+
> e.g. an SSO proxy or the hosted alias token). Prefer `--bearer-token` on
|
|
105
|
+
> shared hosts.
|
|
77
106
|
|
|
78
107
|
## Peer MCP connection
|
|
79
108
|
|
|
@@ -132,6 +161,7 @@ lazily on first use.
|
|
|
132
161
|
|
|
133
162
|
Continue with these pages:
|
|
134
163
|
|
|
164
|
+
- [Host MCP OAuth](../guides/mcp-oauth.md): `mcp oauth`, `--store`, `hostOnly`
|
|
135
165
|
- [Agent-to-agent](../guides/agent-to-agent.md): peers in depth
|
|
136
166
|
- [Tools](./tools.md): authored tools that wrap MCP connections
|
|
137
167
|
- [Webhooks](../guides/webhooks.md): calling MCP connections from handlers
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "prompt"
|
|
3
|
+
description: "Dedented multi-line strings for tool descriptions, reminder prompts, channel context, and errors."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `prompt`
|
|
7
|
+
|
|
8
|
+
Authoring helper for long strings that live next to indented TypeScript:
|
|
9
|
+
tool descriptions, reminder `prompt` fields, GitHub channel `context`,
|
|
10
|
+
and error messages.
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { prompt } from "@cursor/july";
|
|
14
|
+
// or: import { prompt } from "@cursor/july/prompt";
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## `prompt\`…\``
|
|
18
|
+
|
|
19
|
+
Returns a single dedented string. Common leading whitespace is stripped;
|
|
20
|
+
a leading newline after the opening backtick is dropped so the usual
|
|
21
|
+
multiline form stays readable in source.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
throw new Error(prompt`
|
|
25
|
+
It is outside business hours (Mon–Fri 9am–5pm ET).
|
|
26
|
+
Use request_author_approval, or pass approval=human_request.
|
|
27
|
+
`);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Blank lines inside the body are preserved. Relative indentation after the
|
|
31
|
+
common prefix is kept (handy for nested bullet lists).
|
|
32
|
+
|
|
33
|
+
When interpolating multi-line values (for example a list of services), give
|
|
34
|
+
those lines the same indent as the `prompt` body so dedent stays consistent.
|
|
35
|
+
|
|
36
|
+
## `prompt.lines\`…\``
|
|
37
|
+
|
|
38
|
+
Same dedent rules, but returns `string[]` — one entry per line. Use this
|
|
39
|
+
where an API wants separate lines (for example GitHub channel `context`):
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
context: prompt.lines`
|
|
43
|
+
Merged PR detected: ${pr.url} by ${author}.
|
|
44
|
+
|
|
45
|
+
Call plan_deploy, then follow its nextStep.
|
|
46
|
+
`
|
|
47
|
+
```
|
package/docs/reference/tools.md
CHANGED
|
@@ -39,6 +39,27 @@ code that runs it. With a Zod `inputSchema`, the input is validated before
|
|
|
39
39
|
`execute` runs and the input type is inferred. A plain JSON Schema
|
|
40
40
|
object is forwarded as-is and the input arrives as raw JSON.
|
|
41
41
|
|
|
42
|
+
For multi-line descriptions, reminder prompts, and error messages, use
|
|
43
|
+
[`prompt`](./prompt.md) so the string can sit indented with the surrounding
|
|
44
|
+
TypeScript:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { prompt } from "@cursor/july";
|
|
48
|
+
import { defineTool } from "@cursor/july/tools";
|
|
49
|
+
import { z } from "zod";
|
|
50
|
+
|
|
51
|
+
export default defineTool({
|
|
52
|
+
description: prompt`
|
|
53
|
+
Inspect a pull request before approval.
|
|
54
|
+
Prefer this over guessing from the title alone.
|
|
55
|
+
`,
|
|
56
|
+
inputSchema: z.object({ prUrl: z.string().url() }),
|
|
57
|
+
async execute({ prUrl }) {
|
|
58
|
+
return { prUrl };
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
42
63
|
### The `ctx` parameter
|
|
43
64
|
|
|
44
65
|
`execute` receives a `ctx` with the runtime accessors:
|
package/docs/troubleshooting.md
CHANGED
|
@@ -63,6 +63,17 @@ Match your symptom below. Keep the commands as `agentkit`; see
|
|
|
63
63
|
| The bot ignores ordinary channel posts | Default engagement is mentions and DMs only. Enable `engagement.channelPosts` with an allowlist, and subscribe the app to `message.channels` / `message.groups`. |
|
|
64
64
|
| Approve / Deny buttons do nothing | Re-import a Slack app manifest with interactivity enabled. Channels that post approval cards need `toolApprovals: true` (and `interactivity: true` when you compose events by hand). |
|
|
65
65
|
|
|
66
|
+
## What if host MCP OAuth fails?
|
|
67
|
+
|
|
68
|
+
| What you see | What to do |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| `must be defineConnection({ url, oauth: true })` | The connection file needs `oauth: true`, or you passed the wrong connection name to `agentkit mcp oauth`. |
|
|
71
|
+
| Local auth works; hosted calls unauthorized | Run `agentkit mcp oauth <name> --store`, confirm names with `agentkit secrets list <slug>`, then redeploy. |
|
|
72
|
+
| Model asks for `mcp_auth` or IDE MCP for a privileged server | That connection is likely `hostOnly`. Call it from a host tool via `ctx.host.mcp`, and update instructions. |
|
|
73
|
+
|
|
74
|
+
See [Host MCP OAuth](./guides/mcp-oauth.md) and
|
|
75
|
+
[`skills/mcp-auth/SKILL.md`](../skills/mcp-auth/SKILL.md).
|
|
76
|
+
|
|
66
77
|
## What if schedules, reminders, or approvals stall?
|
|
67
78
|
|
|
68
79
|
| What you see | What to do |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cursor/july",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "(early alpha) Filesystem-first framework for defining Cursor agents as markdown and TypeScript and serving them over channels with the Cursor SDK.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"repository": {
|
|
@@ -103,6 +103,13 @@
|
|
|
103
103
|
"import": "./dist/hooks.js",
|
|
104
104
|
"default": "./dist/hooks.js"
|
|
105
105
|
},
|
|
106
|
+
"./prompt": {
|
|
107
|
+
"anysphere-source": "./src/prompt.ts",
|
|
108
|
+
"bun": "./src/prompt.ts",
|
|
109
|
+
"types": "./dist/prompt.d.ts",
|
|
110
|
+
"import": "./dist/prompt.js",
|
|
111
|
+
"default": "./dist/prompt.js"
|
|
112
|
+
},
|
|
106
113
|
"./evals": {
|
|
107
114
|
"anysphere-source": "./src/evals.ts",
|
|
108
115
|
"bun": "./src/evals.ts",
|
|
@@ -213,4 +220,4 @@
|
|
|
213
220
|
"vitest": "^4.0.18",
|
|
214
221
|
"zustand": "^5.0.9"
|
|
215
222
|
}
|
|
216
|
-
}
|
|
223
|
+
}
|
|
@@ -15,8 +15,9 @@ Stand up one new agent project via a short interview, scaffold it, get
|
|
|
15
15
|
channels working
|
|
16
16
|
with the user, prove a turn runs end-to-end, and set up the improvement loop.
|
|
17
17
|
Sibling skills: `framework-map` for orientation, `setup-slack` for Slack
|
|
18
|
-
wiring, `
|
|
19
|
-
`ab` for live A/B metrics, `hillclimb`
|
|
18
|
+
wiring, `mcp-auth` for host MCP OAuth, `github` for webhook-driven
|
|
19
|
+
agents, `evals` for the eval API, `ab` for live A/B metrics, `hillclimb`
|
|
20
|
+
for iteration once the agent runs.
|
|
20
21
|
|
|
21
22
|
Read `framework-map/SKILL.md` first if you haven't; treat the package
|
|
22
23
|
`AGENTS.md` and `README.md` as ground truth for
|
|
@@ -91,7 +92,10 @@ Defaults that make first cuts good:
|
|
|
91
92
|
- **Tool per file**, filename = tool name the model sees. Prefer
|
|
92
93
|
`execution: "server"` with a zod `inputSchema`; use `execution: "agent"`
|
|
93
94
|
(script) only when the tool must run where the agent runs (or runtime is
|
|
94
|
-
cloud). Gate side-effecting tools with `needsApproval: true`.
|
|
95
|
+
cloud). Gate side-effecting tools with `needsApproval: true`. For long
|
|
96
|
+
tool descriptions, reminder prompts, channel `context`, and errors, use
|
|
97
|
+
`prompt\`…\`` / `prompt.lines\`…\`` from `@cursor/july` (dedents indented
|
|
98
|
+
multi-line strings).
|
|
95
99
|
- **Env prefix** for Slack tokens = upper-snake slug (`my-agent` →
|
|
96
100
|
`MY_AGENT_SLACK_*`); `agentkit slack init` derives it for you.
|
|
97
101
|
- **Host prep beats model wandering:** when the purpose has a deterministic
|
|
@@ -139,6 +139,7 @@ folder mounts every sibling agent too.
|
|
|
139
139
|
- Live A/B metrics → `packages/agent-serve/skills/ab/SKILL.md`
|
|
140
140
|
- GitHub webhooks → `packages/agent-serve/skills/github/SKILL.md`
|
|
141
141
|
- Slack → `packages/agent-serve/skills/setup-slack/SKILL.md`
|
|
142
|
+
- Host MCP OAuth → `packages/agent-serve/skills/mcp-auth/SKILL.md`
|
|
142
143
|
- Local triage → `packages/agent-serve/skills/debug/SKILL.md`
|
|
143
144
|
- Measured improvement → `packages/agent-serve/skills/hillclimb/SKILL.md`
|
|
144
145
|
- Dogfood / deploy → `packages/agent-serve/skills/operate/SKILL.md`
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentkit-mcp-auth
|
|
3
|
+
description: >-
|
|
4
|
+
Authorize host MCP OAuth for defineConnection({ url, oauth: true }):
|
|
5
|
+
agentkit mcp oauth, local mcp-auth.json, --store deployment secrets,
|
|
6
|
+
hostOnly, and egress. Read when wiring or debugging MCP auth.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Host MCP OAuth (mcp auth)
|
|
10
|
+
|
|
11
|
+
Use this skill when a human asks to authorize a remote MCP server on an
|
|
12
|
+
agentkit host, store credentials for Cursor-managed hosting, or debug
|
|
13
|
+
`host.mcp` auth failures for `oauth: true` connections.
|
|
14
|
+
|
|
15
|
+
Sibling skills: `framework-map` for layout, `create-agent` when scaffolding,
|
|
16
|
+
`debug` for unrelated local failures, `operate` for deploy/secrets ops.
|
|
17
|
+
|
|
18
|
+
Docs: `docs/guides/mcp-oauth.md`, `docs/reference/connections.md`,
|
|
19
|
+
`docs/reference/cli.md#mcp-oauth`.
|
|
20
|
+
|
|
21
|
+
## When to use host OAuth vs account MCP
|
|
22
|
+
|
|
23
|
+
| Need | Use |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| Connector already in Cursor dashboard (Linear, Notion, …) | `defineConnection({ cursorAccount: true, servers: […] })` |
|
|
26
|
+
| Remote URL that speaks OAuth; host must hold tokens | `defineConnection({ url, oauth: true })` + this skill |
|
|
27
|
+
| Static bearer / API key | `headers` / env on a plain `{ url }` connection |
|
|
28
|
+
|
|
29
|
+
Prefer `hostOnly: true` when only host tools / channel handlers should
|
|
30
|
+
call the server (admin APIs, privileged writes). The model will not see
|
|
31
|
+
those tools.
|
|
32
|
+
|
|
33
|
+
## Goal checklist
|
|
34
|
+
|
|
35
|
+
- [ ] `agent/mcp-connections/<name>.ts` with `url` + `oauth: true` (+ `hostOnly` if privileged)
|
|
36
|
+
- [ ] `hosting.secretNames` lists `MCP_OAUTH_<NAME>_{ACCESS_TOKEN,REFRESH_TOKEN,CLIENT_ID}` when you will `--store`
|
|
37
|
+
- [ ] Hosted engines that reach non-bootstrap hosts declare `hosting.egressDomains`
|
|
38
|
+
- [ ] Local: `agentkit mcp oauth <name>` succeeds
|
|
39
|
+
- [ ] Hosted: `agentkit mcp oauth <name> --store` then redeploy; `secrets list` shows the names
|
|
40
|
+
|
|
41
|
+
## Phase 0 — Author the connection (agent)
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
// agent/mcp-connections/inventory.ts
|
|
45
|
+
import { defineConnection } from "@cursor/july/connections";
|
|
46
|
+
|
|
47
|
+
export default defineConnection({
|
|
48
|
+
url: "https://mcp.example.com/inventory",
|
|
49
|
+
oauth: true,
|
|
50
|
+
hostOnly: true,
|
|
51
|
+
description: "Privileged inventory MCP; call via ctx.host.mcp only.",
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
In `agent/agent.ts`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
hosting: {
|
|
59
|
+
egressDomains: ["mcp.example.com"], // if hosted + non-bootstrap host
|
|
60
|
+
secretNames: [
|
|
61
|
+
"MCP_OAUTH_INVENTORY_ACCESS_TOKEN",
|
|
62
|
+
"MCP_OAUTH_INVENTORY_REFRESH_TOKEN",
|
|
63
|
+
"MCP_OAUTH_INVENTORY_CLIENT_ID",
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Naming: connection file `inventory.ts` → env prefix `MCP_OAUTH_INVENTORY`.
|
|
69
|
+
Do **not** put `CURSOR_*` or hosted-storage names in `secretNames`.
|
|
70
|
+
|
|
71
|
+
Wire privileged calls through host tools:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
await ctx.host.mcp.callTool("inventory", "list_warehouses", {
|
|
75
|
+
region: input.region,
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Update instructions so the model does not hunt IDE MCP namespaces or
|
|
80
|
+
`mcp_auth` for `hostOnly` servers.
|
|
81
|
+
|
|
82
|
+
## Phase 1 — Local authorize (agent + human)
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
cd <agent-project>
|
|
86
|
+
agentkit mcp oauth <connection>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Human completes the browser login. Callback:
|
|
90
|
+
`http://localhost:8787/callback`. Tokens:
|
|
91
|
+
`~/.config/agent-serve/mcp-auth.json` (or `$AGENT_SERVE_CONFIG_DIR`).
|
|
92
|
+
|
|
93
|
+
Already authorized → command prints that and exits 0. URL change →
|
|
94
|
+
re-run; resource URL binding drops the old entry.
|
|
95
|
+
|
|
96
|
+
## Phase 2 — Store on the deployment (agent + human)
|
|
97
|
+
|
|
98
|
+
Requires `agentkit login` (or `CURSOR_API_KEY`) and deploy rights.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
agentkit mcp oauth <connection> --store [--slug <slug>] [--team <id>]
|
|
102
|
+
agentkit secrets list <slug>
|
|
103
|
+
agentkit deploy # or your usual deploy; secrets apply next deploy
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`--store` upserts access (required), refresh (if present), and client id
|
|
107
|
+
(if present). It does not remove unrelated secrets.
|
|
108
|
+
|
|
109
|
+
## Phase 3 — Verify (agent)
|
|
110
|
+
|
|
111
|
+
Local:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
agentkit validate --dir .
|
|
115
|
+
agentkit call <tool-that-uses-host.mcp> --dir .
|
|
116
|
+
# or exercise the same path from the playground
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Hosted: confirm egress allowlist includes the MCP host, secrets exist,
|
|
120
|
+
redeploy completed, then exercise the same host tool once.
|
|
121
|
+
|
|
122
|
+
## Failure table
|
|
123
|
+
|
|
124
|
+
| Symptom | Fix |
|
|
125
|
+
| --- | --- |
|
|
126
|
+
| `must be defineConnection({ url, oauth: true })` | Wrong connection name, or missing `oauth: true` |
|
|
127
|
+
| `Unknown MCP connection` | Filename under `agent/mcp-connections/` must match CLI arg |
|
|
128
|
+
| Callback hang | Free port 8787; finish browser flow on this machine |
|
|
129
|
+
| Hosted 401 / unauthorized | `secrets list`; re-run `--store`; redeploy |
|
|
130
|
+
| Model invents `mcp_auth` / IDE MCP | Connection is `hostOnly`; fix instructions + use host tools |
|
|
131
|
+
| Tokens ignored after URL edit | Expected; run `mcp oauth` again for the new resource URL |
|
|
132
|
+
|
|
133
|
+
## Don't
|
|
134
|
+
|
|
135
|
+
- Don't put raw OAuth tokens in git or in connection source files
|
|
136
|
+
- Don't add `BUGBOTDB_URL` / `AGENT_SERVE_DEPLOYMENT_ID` to `secretNames`
|
|
137
|
+
- Don't use Bun for the CLI (use Node / `tsx`)
|
|
138
|
+
- Don't expect `--store` alone to restart a running engine; redeploy
|