feat(connect-studio): Connect Studio modal for IDE MCP configuration#2765
feat(connect-studio): Connect Studio modal for IDE MCP configuration#2765
Conversation
Release OptionsShould a new version be published when this PR is merged? React with an emoji to vote on the release type:
Current version: Deployment
|
🧪 BenchmarkShould we run the Virtual MCP strategy benchmark for this PR? React with 👍 to run the benchmark.
Benchmark will run on the next push after you react. |
There was a problem hiding this comment.
3 issues found across 4 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/mesh/src/web/components/connect-studio/connect-studio-modal.tsx">
<violation number="1" location="apps/mesh/src/web/components/connect-studio/connect-studio-modal.tsx:43">
P3: Local environment detection misses IPv6 loopback (`::1`), which can hide the Connect action during local development.</violation>
</file>
<file name="apps/mesh/src/api/routes/decopilot/routes.ts">
<violation number="1" location="apps/mesh/src/api/routes/decopilot/routes.ts:327">
P1: Use `getUserId(ctx)` instead of `ctx.auth?.user?.id` — this will incorrectly return 401 for requests authenticated via API key. The DELETE endpoint already uses `getUserId(ctx)` correctly.
(Based on your team's feedback about using getUserId(ctx) for user-based or API-key authentication.) [FEEDBACK_USED]</violation>
<violation number="2" location="apps/mesh/src/api/routes/decopilot/routes.ts:343">
P1: Use `getUserId(ctx)` instead of `ctx.auth?.user?.id` — under API-key auth, this returns `undefined`, causing a spurious 401 and embedding `"undefined"` in the created API key name.
(Based on your team's feedback about using getUserId(ctx) for user-based or API-key authentication.) [FEEDBACK_USED]</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| app.post("/:org/decopilot/connect-studio", async (c) => { | ||
| const ctx = c.get("meshContext"); | ||
| const organization = ensureOrganization(c); | ||
| const userId = ctx.auth?.user?.id; |
There was a problem hiding this comment.
P1: Use getUserId(ctx) instead of ctx.auth?.user?.id — under API-key auth, this returns undefined, causing a spurious 401 and embedding "undefined" in the created API key name.
(Based on your team's feedback about using getUserId(ctx) for user-based or API-key authentication.)
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/api/routes/decopilot/routes.ts, line 343:
<comment>Use `getUserId(ctx)` instead of `ctx.auth?.user?.id` — under API-key auth, this returns `undefined`, causing a spurious 401 and embedding `"undefined"` in the created API key name.
(Based on your team's feedback about using getUserId(ctx) for user-based or API-key authentication.) </comment>
<file context>
@@ -192,6 +192,349 @@ export function createDecopilotRoutes(deps: DecopilotDeps) {
+ app.post("/:org/decopilot/connect-studio", async (c) => {
+ const ctx = c.get("meshContext");
+ const organization = ensureOrganization(c);
+ const userId = ctx.auth?.user?.id;
+ if (!userId) {
+ throw new HTTPException(401, { message: "Authentication required" });
</file context>
| const userId = ctx.auth?.user?.id; | |
| const userId = getUserId(ctx); |
|
|
||
| app.get("/:org/decopilot/connect-studio/status", async (c) => { | ||
| const ctx = c.get("meshContext"); | ||
| if (!ctx.auth?.user?.id) { |
There was a problem hiding this comment.
P1: Use getUserId(ctx) instead of ctx.auth?.user?.id — this will incorrectly return 401 for requests authenticated via API key. The DELETE endpoint already uses getUserId(ctx) correctly.
(Based on your team's feedback about using getUserId(ctx) for user-based or API-key authentication.)
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/api/routes/decopilot/routes.ts, line 327:
<comment>Use `getUserId(ctx)` instead of `ctx.auth?.user?.id` — this will incorrectly return 401 for requests authenticated via API key. The DELETE endpoint already uses `getUserId(ctx)` correctly.
(Based on your team's feedback about using getUserId(ctx) for user-based or API-key authentication.) </comment>
<file context>
@@ -192,6 +192,349 @@ export function createDecopilotRoutes(deps: DecopilotDeps) {
+
+ app.get("/:org/decopilot/connect-studio/status", async (c) => {
+ const ctx = c.get("meshContext");
+ if (!ctx.auth?.user?.id) {
+ throw new HTTPException(401, { message: "Authentication required" });
+ }
</file context>
| if (!ctx.auth?.user?.id) { | |
| if (!getUserId(ctx)) { |
| return ( | ||
| typeof window !== "undefined" && | ||
| (window.location.hostname === "localhost" || | ||
| window.location.hostname === "127.0.0.1") |
There was a problem hiding this comment.
P3: Local environment detection misses IPv6 loopback (::1), which can hide the Connect action during local development.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/components/connect-studio/connect-studio-modal.tsx, line 43:
<comment>Local environment detection misses IPv6 loopback (`::1`), which can hide the Connect action during local development.</comment>
<file context>
@@ -0,0 +1,379 @@
+ return (
+ typeof window !== "undefined" &&
+ (window.location.hostname === "localhost" ||
+ window.location.hostname === "127.0.0.1")
+ );
+}
</file context>
685f855 to
01fbe89
Compare
Add a "Connect Studio" sidebar button that opens a modal allowing users to connect their Deco Studio as an MCP server to Claude Code, Cursor, or Codex. Supports one-click auto-configuration when running locally and copyable config snippets for hosted deployments. Each connection creates a per-user API key with full access to the studio's management MCP endpoint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
01fbe89 to
0daa3db
Compare
Replace placeholder values with actual origin/org-id in config snippets. Add "Generate API Key" button that creates a personal token and injects it into the snippet so users can copy a ready-to-use config. Support token-only mode in the backend for all targets. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
~/.cursor/mcp.json), and Codex (writes~/.codex/config.toml)Files Changed
apps/mesh/src/api/routes/decopilot/routes.ts— Connect Studio backend routes (GET status, POST connect, DELETE disconnect)apps/mesh/src/web/components/connect-studio/connect-studio-modal.tsx— New modal component with IDE tabsapps/mesh/src/web/components/sidebar/footer/inbox.tsx— Sidebar button triggerapps/mesh/src/web/lib/query-keys.ts— Query key for status cachingTest plan
bun run devclaude mcp get deco-studioworks~/.cursor/mcp.json~/.codex/config.toml🤖 Generated with Claude Code
Summary by cubic
Adds a Connect Studio modal and backend routes to connect Deco Studio as an MCP server in Claude Code, Cursor, and Codex. Enables one-click local setup, per-user API tokens, live connection status (with Claude auth), and ready-to-paste config with real origin/org values.
connect-studio-status.GET /:org/decopilot/connect-studio/status,POST /:org/decopilot/connect-studio,DELETE /:org/decopilot/connect-studio(auth required; status reports IDE connection and Claude auth; disconnect removes IDE config).claude mcp add-json --scope userafter removing any existing entry; Cursor merges~/.cursor/mcp.json; Codex replaces the section in~/.codex/config.toml. Falls back to copyable config if CLI/write fails.Authorization,x-org-id, and for Claude Codex-mesh-client.Written for commit 3326034. Summary will update on new commits.