Skip to content

feat(connect-studio): Connect Studio modal for IDE MCP configuration#2765

Open
vibegui wants to merge 2 commits intomainfrom
feat/connect-studio
Open

feat(connect-studio): Connect Studio modal for IDE MCP configuration#2765
vibegui wants to merge 2 commits intomainfrom
feat/connect-studio

Conversation

@vibegui
Copy link
Contributor

@vibegui vibegui commented Mar 19, 2026

Summary

  • Adds a "Connect Studio" button in the sidebar footer that opens a modal with IDE configuration tabs
  • Supports Claude Code (auto-config via CLI), Cursor (writes ~/.cursor/mcp.json), and Codex (writes ~/.codex/config.toml)
  • One-click auto-configuration when running locally; copyable config snippets for hosted deployments
  • Creates per-user API keys with full studio access so connected IDEs authenticate automatically

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 tabs
  • apps/mesh/src/web/components/sidebar/footer/inbox.tsx — Sidebar button trigger
  • apps/mesh/src/web/lib/query-keys.ts — Query key for status caching

Test plan

  • Start dev server with bun run dev
  • Verify "Connect Studio" button appears in sidebar footer
  • Open modal and test Claude Code tab: click Connect, verify claude mcp get deco-studio works
  • Test Cursor tab: verify config is written to ~/.cursor/mcp.json
  • Test Codex tab: verify config is appended to ~/.codex/config.toml
  • Test Disconnect for each IDE
  • Verify config snippets are copyable in all tabs

🤖 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.

  • New Features
    • Sidebar “Connect Studio” button opens a modal with tabs for Claude Code, Cursor, and Codex, plus a refresh button and 10s status polling via connect-studio-status.
    • Endpoints: 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).
    • Local auto-config: Claude via claude mcp add-json --scope user after 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.
    • Generate Token: “Generate Token” creates a personal API key and injects it into the snippet. Backend supports token-only mode for all targets and returns the token. Snippets include actual origin and org ID with Authorization, x-org-id, and for Claude Code x-mesh-client.

Written for commit 3326034. Summary will update on new commits.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 19, 2026

Release Options

Should a new version be published when this PR is merged?

React with an emoji to vote on the release type:

Reaction Type Next Version
👍 Prerelease 2.187.1-alpha.1
🎉 Patch 2.187.1
❤️ Minor 2.188.0
🚀 Major 3.0.0

Current version: 2.187.0

Deployment

  • Deploy to production (triggers ArgoCD sync after Docker image is published)

@github-actions
Copy link
Contributor

🧪 Benchmark

Should we run the Virtual MCP strategy benchmark for this PR?

React with 👍 to run the benchmark.

Reaction Action
👍 Run quick benchmark (10 & 128 tools)

Benchmark will run on the next push after you react.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.)

View Feedback

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>
Suggested change
const userId = ctx.auth?.user?.id;
const userId = getUserId(ctx);
Fix with Cubic


app.get("/:org/decopilot/connect-studio/status", async (c) => {
const ctx = c.get("meshContext");
if (!ctx.auth?.user?.id) {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.)

View Feedback

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>
Suggested change
if (!ctx.auth?.user?.id) {
if (!getUserId(ctx)) {
Fix with Cubic

return (
typeof window !== "undefined" &&
(window.location.hostname === "localhost" ||
window.location.hostname === "127.0.0.1")
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Fix with Cubic

@vibegui vibegui force-pushed the feat/connect-studio branch 3 times, most recently from 685f855 to 01fbe89 Compare March 20, 2026 01:09
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>
@vibegui vibegui force-pushed the feat/connect-studio branch from 01fbe89 to 0daa3db Compare March 21, 2026 21:35
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant