Skip to content

Add workspace key bootstrap and keyless startup#9

Merged
willwashburn merged 1 commit into
mainfrom
enable-workspace-registration-in-mcp
Feb 9, 2026
Merged

Add workspace key bootstrap and keyless startup#9
willwashburn merged 1 commit into
mainfrom
enable-workspace-registration-in-mcp

Conversation

@willwashburn
Copy link
Copy Markdown
Member

@willwashburn willwashburn commented Feb 9, 2026

Introduce workspace key support and keyless startup flow: session now stores workspaceKey and createInitialSession accepts an optional key. Add two new registration tools (create_workspace, set_workspace_key) to bootstrap or switch workspace keys; switching clears any existing agent identity. create_workspace calls the Relay API (via fetch) and stores the returned api_key in session.

Make MCP server tolerant of missing RELAY_API_KEY at startup: stdio no longer exits if env var missing, createRelayMcpServer accepts an optional apiKey and lazily constructs Relay clients using the session's workspaceKey or agentToken. getRelay now throws instructive error when workspace key is not configured, and agent websocket bridge handling is improved to reset/reinitialize when agent tokens change. Piggybacking skips include the new workspace tools. Update system prompt and README to document keyless flow. Tests updated/added to cover create_workspace, set_workspace_key, register behavior and keyless startup; tool count expectations adjusted.


Open with Devin

Introduce workspace key support and keyless startup flow: session now stores workspaceKey and createInitialSession accepts an optional key. Add two new registration tools (create_workspace, set_workspace_key) to bootstrap or switch workspace keys; switching clears any existing agent identity. create_workspace calls the Relay API (via fetch) and stores the returned api_key in session.

Make MCP server tolerant of missing RELAY_API_KEY at startup: stdio no longer exits if env var missing, createRelayMcpServer accepts an optional apiKey and lazily constructs Relay clients using the session's workspaceKey or agentToken. getRelay now throws instructive error when workspace key is not configured, and agent websocket bridge handling is improved to reset/reinitialize when agent tokens change. Piggybacking skips include the new workspace tools. Update system prompt and README to document keyless flow. Tests updated/added to cover create_workspace, set_workspace_key, register behavior and keyless startup; tool count expectations adjusted.
@willwashburn willwashburn requested review from Copilot and khaliqgant and removed request for khaliqgant February 9, 2026 19:13
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 6 additional findings in Devin Review.

Open in Devin Review

if (partial.agentToken && !session.wsBridge) {
const nextAgentToken =
partial.agentToken === undefined ? session.agentToken : partial.agentToken;
const nextAgentName = partial.agentName ?? session.agentName ?? null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 nextAgentName uses ?? instead of explicit null check, failing to clear agent name

On packages/mcp/src/server.ts:58, nextAgentName is computed using ??, which treats explicit null the same as undefined and falls through to the old session value. This is inconsistent with the nextAgentToken computation on line 56-57, which correctly distinguishes between undefined (not provided) and null (explicitly cleared).

Root Cause and Impact

When setSession({ workspaceKey: 'rk_new', agentToken: null, agentName: null }) is called (from create_workspace at packages/mcp/src/tools/registration.ts:74 or set_workspace_key at line 100), the intent is to clear the agent identity. However:

const nextAgentName = partial.agentName ?? session.agentName ?? null;
// partial.agentName is null → nullish → falls back to session.agentName
// Result: 'old-agent' instead of null

Compare with the correct pattern used for nextAgentToken:

const nextAgentToken =
  partial.agentToken === undefined ? session.agentToken : partial.agentToken;
// partial.agentToken is null → not undefined → uses null
// Result: null (correct)

nextAgentName is consumed by the telemetry event at line 89. In current call sites this telemetry line is only reached when nextAgentToken is truthy (bridge initialization), and all current callers that set agentName: null also set agentToken: null, so the stale value isn't emitted yet. However, the calculation is incorrect and any future call site that sets agentName: null with a truthy agentToken would log the wrong agent name.

Suggested change
const nextAgentName = partial.agentName ?? session.agentName ?? null;
const nextAgentName = partial.agentName === undefined ? (session.agentName ?? null) : partial.agentName;
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@khaliqgant khaliqgant self-assigned this Feb 9, 2026
@willwashburn willwashburn merged commit 8fe5ace into main Feb 9, 2026
4 of 7 checks passed
@willwashburn willwashburn deleted the enable-workspace-registration-in-mcp branch February 9, 2026 19:32
@willwashburn willwashburn review requested due to automatic review settings March 23, 2026 19:03
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.

2 participants