Skip to content

Commit 6e5f6da

Browse files
committed
Merge remote-tracking branch 'origin/main' into 16511-dashboard-vscode-notif
2 parents e559d25 + f3e5bb9 commit 6e5f6da

File tree

46 files changed

+2299
-401
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2299
-401
lines changed

cli/exp_mcp.go

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ import (
44
"context"
55
"encoding/json"
66
"errors"
7-
"log"
87
"os"
98
"path/filepath"
109

10+
"github.com/mark3labs/mcp-go/server"
11+
1112
"cdr.dev/slog"
1213
"cdr.dev/slog/sloggers/sloghuman"
14+
"github.com/coder/coder/v2/buildinfo"
1315
"github.com/coder/coder/v2/cli/cliui"
1416
"github.com/coder/coder/v2/codersdk"
17+
"github.com/coder/coder/v2/codersdk/agentsdk"
1518
codermcp "github.com/coder/coder/v2/mcp"
1619
"github.com/coder/serpent"
1720
)
@@ -191,14 +194,15 @@ func (*RootCmd) mcpConfigureCursor() *serpent.Command {
191194

192195
func (r *RootCmd) mcpServer() *serpent.Command {
193196
var (
194-
client = new(codersdk.Client)
195-
instructions string
196-
allowedTools []string
197+
client = new(codersdk.Client)
198+
instructions string
199+
allowedTools []string
200+
appStatusSlug string
197201
)
198202
return &serpent.Command{
199203
Use: "server",
200204
Handler: func(inv *serpent.Invocation) error {
201-
return mcpServerHandler(inv, client, instructions, allowedTools)
205+
return mcpServerHandler(inv, client, instructions, allowedTools, appStatusSlug)
202206
},
203207
Short: "Start the Coder MCP server.",
204208
Middleware: serpent.Chain(
@@ -209,24 +213,32 @@ func (r *RootCmd) mcpServer() *serpent.Command {
209213
Name: "instructions",
210214
Description: "The instructions to pass to the MCP server.",
211215
Flag: "instructions",
216+
Env: "CODER_MCP_INSTRUCTIONS",
212217
Value: serpent.StringOf(&instructions),
213218
},
214219
{
215220
Name: "allowed-tools",
216221
Description: "Comma-separated list of allowed tools. If not specified, all tools are allowed.",
217222
Flag: "allowed-tools",
223+
Env: "CODER_MCP_ALLOWED_TOOLS",
218224
Value: serpent.StringArrayOf(&allowedTools),
219225
},
226+
{
227+
Name: "app-status-slug",
228+
Description: "When reporting a task, the coder_app slug under which to report the task.",
229+
Flag: "app-status-slug",
230+
Env: "CODER_MCP_APP_STATUS_SLUG",
231+
Value: serpent.StringOf(&appStatusSlug),
232+
Default: "",
233+
},
220234
},
221235
}
222236
}
223237

224-
func mcpServerHandler(inv *serpent.Invocation, client *codersdk.Client, instructions string, allowedTools []string) error {
238+
func mcpServerHandler(inv *serpent.Invocation, client *codersdk.Client, instructions string, allowedTools []string, appStatusSlug string) error {
225239
ctx, cancel := context.WithCancel(inv.Context())
226240
defer cancel()
227241

228-
logger := slog.Make(sloghuman.Sink(inv.Stdout))
229-
230242
me, err := client.User(ctx, codersdk.Me)
231243
if err != nil {
232244
cliui.Errorf(inv.Stderr, "Failed to log in to the Coder deployment.")
@@ -253,19 +265,42 @@ func mcpServerHandler(inv *serpent.Invocation, client *codersdk.Client, instruct
253265
inv.Stderr = invStderr
254266
}()
255267

256-
options := []codermcp.Option{
257-
codermcp.WithInstructions(instructions),
258-
codermcp.WithLogger(&logger),
268+
mcpSrv := server.NewMCPServer(
269+
"Coder Agent",
270+
buildinfo.Version(),
271+
server.WithInstructions(instructions),
272+
)
273+
274+
// Create a separate logger for the tools.
275+
toolLogger := slog.Make(sloghuman.Sink(invStderr))
276+
277+
toolDeps := codermcp.ToolDeps{
278+
Client: client,
279+
Logger: &toolLogger,
280+
AppStatusSlug: appStatusSlug,
281+
AgentClient: agentsdk.New(client.URL),
282+
}
283+
284+
// Get the workspace agent token from the environment.
285+
agentToken, ok := os.LookupEnv("CODER_AGENT_TOKEN")
286+
if ok && agentToken != "" {
287+
toolDeps.AgentClient.SetSessionToken(agentToken)
288+
} else {
289+
cliui.Warnf(inv.Stderr, "CODER_AGENT_TOKEN is not set, task reporting will not be available")
290+
}
291+
if appStatusSlug == "" {
292+
cliui.Warnf(inv.Stderr, "CODER_MCP_APP_STATUS_SLUG is not set, task reporting will not be available.")
259293
}
260294

261-
// Add allowed tools option if specified
295+
// Register tools based on the allowlist (if specified)
296+
reg := codermcp.AllTools()
262297
if len(allowedTools) > 0 {
263-
options = append(options, codermcp.WithAllowedTools(allowedTools))
298+
reg = reg.WithOnlyAllowed(allowedTools...)
264299
}
265300

266-
srv := codermcp.NewStdio(client, options...)
267-
srv.SetErrorLogger(log.New(invStderr, "", log.LstdFlags))
301+
reg.Register(mcpSrv, toolDeps)
268302

303+
srv := server.NewStdioServer(mcpSrv)
269304
done := make(chan error)
270305
go func() {
271306
defer close(done)

coderd/database/db2sdk/db2sdk.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ func WorkspaceAppStatus(status database.WorkspaceAppStatus) codersdk.WorkspaceAp
539539
return codersdk.WorkspaceAppStatus{
540540
ID: status.ID,
541541
CreatedAt: status.CreatedAt,
542+
WorkspaceID: status.WorkspaceID,
542543
AgentID: status.AgentID,
543544
AppID: status.AppID,
544545
NeedsUserAttention: status.NeedsUserAttention,

docs/admin/monitoring/notifications/index.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ existing one.
102102

103103
**Server Settings:**
104104

105-
| Required | CLI | Env | Type | Description | Default |
106-
|:--------:|---------------------|-------------------------|----------|-------------------------------------------|-----------|
107-
| ✔️ | `--email-from` | `CODER_EMAIL_FROM` | `string` | The sender's address to use. | |
108-
| ✔️ | `--email-smarthost` | `CODER_EMAIL_SMARTHOST` | `string` | The SMTP relay to send messages | |
109-
| ✔️ | `--email-hello` | `CODER_EMAIL_HELLO` | `string` | The hostname identifying the SMTP server. | localhost |
105+
| Required | CLI | Env | Type | Description | Default |
106+
|:--------:|---------------------|-------------------------|----------|-----------------------------------------------------------|-----------|
107+
| ✔️ | `--email-from` | `CODER_EMAIL_FROM` | `string` | The sender's address to use. | |
108+
| ✔️ | `--email-smarthost` | `CODER_EMAIL_SMARTHOST` | `string` | The SMTP relay to send messages (format: `hostname:port`) | |
109+
| ✔️ | `--email-hello` | `CODER_EMAIL_HELLO` | `string` | The hostname identifying the SMTP server. | localhost |
110110

111111
**Authentication Settings:**
112112

@@ -122,7 +122,7 @@ existing one.
122122
| Required | CLI | Env | Type | Description | Default |
123123
|:--------:|-----------------------------|-------------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|
124124
| - | `--email-force-tls` | `CODER_EMAIL_FORCE_TLS` | `bool` | Force a TLS connection to the configured SMTP smarthost. If port 465 is used, TLS will be forced. See <https://datatracker.ietf.org/doc/html/rfc8314#section-3.3>. | false |
125-
| - | `--email-tls-starttls` | `CODER_EMAIL_TLS_STARTTLS` | `bool` | Enable STARTTLS to upgrade insecure SMTP connections using TLS. Ignored if `CODER_NOTIFICATIONS_EMAIL_FORCE_TLS` is set. | false |
125+
| - | `--email-tls-starttls` | `CODER_EMAIL_TLS_STARTTLS` | `bool` | Enable STARTTLS to upgrade insecure SMTP connections using TLS. Ignored if `CODER_EMAIL_FORCE_TLS` is set. | false |
126126
| - | `--email-tls-skip-verify` | `CODER_EMAIL_TLS_SKIPVERIFY` | `bool` | Skip verification of the target server's certificate (**insecure**). | false |
127127
| - | `--email-tls-server-name` | `CODER_EMAIL_TLS_SERVERNAME` | `string` | Server name to verify against the target certificate. | |
128128
| - | `--email-tls-cert-file` | `CODER_EMAIL_TLS_CERTFILE` | `string` | Certificate file to use. | |
105 KB
Loading

docs/manifest.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@
166166
"title": "Zed",
167167
"description": "Access your workspace with Zed",
168168
"path": "./user-guides/workspace-access/zed.md"
169+
},
170+
{
171+
"title": "Cursor",
172+
"description": "Access your workspace with Cursor",
173+
"path": "./user-guides/workspace-access/cursor.md"
174+
},
175+
{
176+
"title": "Windsurf",
177+
"description": "Access your workspace with Windsurf",
178+
"path": "./user-guides/workspace-access/windsurf.md"
169179
}
170180
]
171181
},
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Cursor
2+
3+
[Cursor](https://cursor.sh/) is a modern IDE built on top of VS Code with enhanced AI capabilities.
4+
5+
Follow this guide to use Cursor to access your Coder workspaces.
6+
7+
If your team uses Cursor regularly, ask your Coder administrator to add a [Cursor module](https://registry.coder.com/modules/cursor) to your template.
8+
9+
## Install Cursor
10+
11+
Cursor can connect to a Coder workspace using the Coder extension:
12+
13+
1. [Install Cursor](https://docs.cursor.com/get-started/installation) on your local machine.
14+
15+
1. Open Cursor and log in or [create a Cursor account](https://authenticator.cursor.sh/sign-up)
16+
if you don't have one already.
17+
18+
## Install the Coder extension
19+
20+
1. You can install the Coder extension through the Marketplace built in to Cursor or manually.
21+
22+
<div class="tabs">
23+
24+
## Extension Marketplace
25+
26+
1. Search for Coder from the Extensions Pane and select **Install**.
27+
28+
1. Coder Remote uses the **Remote - SSH extension** to connect.
29+
30+
You can find it in the **Extension Pack** tab of the Coder extension.
31+
32+
## Manually
33+
34+
1. Download the [latest vscode-coder extension](https://github.com/coder/vscode-coder/releases/latest) `.vsix` file.
35+
36+
1. Drag the `.vsix` file into the extensions pane of Cursor.
37+
38+
Alternatively:
39+
40+
1. Open the Command Palette
41+
(<kdb>Ctrl</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb> or <kdb>Cmd</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb>)
42+
and search for `vsix`.
43+
44+
1. Select **Extensions: Install from VSIX** and select the vscode-coder extension you downloaded.
45+
46+
</div>
47+
48+
1. Coder Remote uses the **Remote - SSH extension** to connect.
49+
50+
You can find it in the **Extension Pack** tab of the Coder extension.
51+
52+
## Open a workspace in Cursor
53+
54+
1. From the Cursor Command Palette
55+
(<kdb>Ctrl</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb> or <kdb>Cmd</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb>),
56+
enter `coder` and select **Coder: Login**.
57+
58+
1. Follow the prompts to login and copy your session token.
59+
60+
Paste the session token in the **Paste your API key** box in Cursor.
61+
62+
1. Select **Open Workspace** or use the Command Palette to run **Coder: Open Workspace**.

docs/user-guides/workspace-access/index.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,18 @@ desktop client and VSCode in the browser with [code-server](#code-server).
8080

8181
Read more details on [using VSCode in your workspace](./vscode.md).
8282

83+
## Cursor
84+
85+
[Cursor](https://cursor.sh/) is an IDE built on VS Code with enhanced AI capabilities.
86+
Cursor connects using the Coder extension.
87+
88+
Read more about [using Cursor with your workspace](./cursor.md).
89+
90+
## Windsurf
91+
92+
[Windsurf](./windsurf.md) is Codeium's code editor designed for AI-assisted development.
93+
Windsurf connects using the Coder extension.
94+
8395
## JetBrains IDEs
8496

8597
We support JetBrains IDEs using
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Windsurf
2+
3+
[Windsurf](https://codeium.com/windsurf) is Codeium's code editor designed for AI-assisted
4+
development.
5+
6+
Follow this guide to use Windsurf to access your Coder workspaces.
7+
8+
If your team uses Windsurf regularly, ask your Coder administrator to add Windsurf as a workspace application in your template.
9+
10+
## Install Windsurf
11+
12+
Windsurf can connect to your Coder workspaces via SSH:
13+
14+
1. [Install Windsurf](https://docs.codeium.com/windsurf/getting-started) on your local machine.
15+
16+
1. Open Windsurf and select **Get started**.
17+
18+
Import your settings from another IDE, or select **Start fresh**.
19+
20+
1. Complete the setup flow and log in or [create a Codeium account](https://codeium.com/windsurf/signup)
21+
if you don't have one already.
22+
23+
## Install the Coder extension
24+
25+
![Coder extension in Windsurf](../../images/user-guides/ides/windsurf-coder-extension.png)
26+
27+
1. You can install the Coder extension through the Marketplace built in to Windsurf or manually.
28+
29+
<div class="tabs">
30+
31+
## Extension Marketplace
32+
33+
1. Search for Coder from the Extensions Pane and select **Install**.
34+
35+
## Manually
36+
37+
1. Download the [latest vscode-coder extension](https://github.com/coder/vscode-coder/releases/latest) `.vsix` file.
38+
39+
1. Drag the `.vsix` file into the extensions pane of Windsurf.
40+
41+
Alternatively:
42+
43+
1. Open the Command Palette
44+
(<kdb>Ctrl</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb> or <kdb>Cmd</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb>)
45+
and search for `vsix`.
46+
47+
1. Select **Extensions: Install from VSIX** and select the vscode-coder extension you downloaded.
48+
49+
</div>
50+
51+
## Open a workspace in Windsurf
52+
53+
1. From the Windsurf Command Palette
54+
(<kdb>Ctrl</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb> or <kdb>Cmd</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb>),
55+
enter `coder` and select **Coder: Login**.
56+
57+
1. Follow the prompts to login and copy your session token.
58+
59+
Paste the session token in the **Coder API Key** dialogue in Windsurf.
60+
61+
1. Windsurf prompts you to open a workspace, or you can use the Command Palette to run **Coder: Open Workspace**.

0 commit comments

Comments
 (0)