refactor(cli): route the MCP server through @agent-relay/sdk thin clients#1096
Conversation
…ents Add raw pass-through Relaycast client factories to @agent-relay/sdk (createWorkspaceClient, createAgentClient, createRealtimeClient, createWorkspace) and migrate agent-relay-mcp.ts to consume them instead of constructing RelayCast/AgentClient/WsClient from @relaycast/sdk directly. The thin clients keep upstream payloads and errors untouched, so MCP tool schemas, output strings, and error handling are unchanged. - @relaycast/sdk is no longer a dependency of the agent-relay CLI package (the startup test still mocks the specifier, resolved via the workspace's hoisted copy from @agent-relay/sdk) - drop the now-unused cli/lib/relaycast-telemetry.ts; telemetry context is resolved inside the SDK factories from the same environment variables - unit-test the factories for config construction, telemetry resolution, method pass-through, and unchanged error propagation Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe SDK adds typed thin-client factories and tests for Relaycast pass-through behavior. The CLI MCP integration switches workspace, agent, realtime, resource, and provisioning paths to those factories, while dependency and trajectory records document the migration. ChangesMCP thin-client migration
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Session as MCP session
participant CLI as agent-relay MCP
participant SDK as agent-relay SDK
participant Relay as Relaycast engine
Session->>CLI: initialize MCP tools and resources
CLI->>SDK: create workspace, agent, and realtime clients
SDK->>Relay: forward MCP operations
Relay-->>SDK: return payloads, events, or errors
SDK-->>CLI: expose unchanged results
Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request removes the direct runtime dependency on @relaycast/sdk from the agent-relay CLI package, refactoring it to communicate with the hosted engine exclusively through new thin client factories (createWorkspaceClient, createAgentClient, createRealtimeClient, and createWorkspace) added to @agent-relay/sdk. These thin clients act as raw pass-throughs to preserve upstream payload shapes and errors. Unit tests have been added to verify their behavior, and the unused relaycast-telemetry.ts helper has been removed. Review feedback points out that the new changelog entries are too verbose and contain implementation backstory, violating the repository style guide's requirement for concise, impact-first entries.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
|
||
| ### Changed | ||
|
|
||
| - `agent-relay mcp` now talks to the hosted engine exclusively through `@agent-relay/sdk` thin clients instead of constructing raw `@relaycast/sdk` clients; `@relaycast/sdk` is no longer a runtime dependency of the `agent-relay` CLI package. Tool schemas, payloads, and error behavior are unchanged. |
There was a problem hiding this comment.
The changelog entry is quite verbose and contains implementation backstory (e.g., details about removing direct dependencies and unchanged behavior). According to the Repository Style Guide (under "Changelog"), entries should be concise and impact-first, dropping implementation backstory unless it clearly explains the shipped impact.
| - `agent-relay mcp` now talks to the hosted engine exclusively through `@agent-relay/sdk` thin clients instead of constructing raw `@relaycast/sdk` clients; `@relaycast/sdk` is no longer a runtime dependency of the `agent-relay` CLI package. Tool schemas, payloads, and error behavior are unchanged. | |
| - agent-relay mcp now routes all hosted engine traffic through @agent-relay/sdk thin clients. |
References
- Changelog entries should be concise and impact-first. Prefer one short bullet per user-visible change: name the command, API, schema, or package touched and the practical effect. Drop issue/PR links, internal review notes, implementation backstory, release-only entries, and "foundation for..." phrasing unless that text clearly explains the shipped impact. (link)
|
|
||
| ### Added | ||
|
|
||
| - `@agent-relay/sdk` adds thin Relaycast client factories — `createWorkspaceClient`, `createAgentClient`, `createRealtimeClient`, and `createWorkspace` — typed raw pass-throughs for workspace-key and agent-token operations (registration, spawn/release, messaging, channels, reactions, inbox, actions, realtime events) that keep upstream payloads and errors untouched. |
There was a problem hiding this comment.
This changelog entry is also quite verbose and lists many specific operations in parentheses. According to the Repository Style Guide (under "Changelog"), entries should be concise and impact-first. We can simplify this to focus on the primary user-visible impact.
| - `@agent-relay/sdk` adds thin Relaycast client factories — `createWorkspaceClient`, `createAgentClient`, `createRealtimeClient`, and `createWorkspace` — typed raw pass-throughs for workspace-key and agent-token operations (registration, spawn/release, messaging, channels, reactions, inbox, actions, realtime events) that keep upstream payloads and errors untouched. | |
| - @agent-relay/sdk adds thin client factories (createWorkspaceClient, createAgentClient, createRealtimeClient, and createWorkspace) for raw pass-through access to the hosted engine. |
References
- Changelog entries should be concise and impact-first. Prefer one short bullet per user-visible change: name the command, API, schema, or package touched and the practical effect. Drop issue/PR links, internal review notes, implementation backstory, release-only entries, and "foundation for..." phrasing unless that text clearly explains the shipped impact. (link)
Re-applies the thin-client migration onto main's modularized MCP server: - agent-relay-mcp.ts, mcp/types.ts, mcp/workspace.ts, mcp/resources.ts now use @agent-relay/sdk thin clients instead of raw @relaycast/sdk - keeps cli/lib/relaycast-telemetry.ts deleted (SDK owns the resolution) - @relaycast/sdk stays out of packages/cli dependencies - CHANGELOG keeps main's reconciled [Unreleased] plus this PR's two entries Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CPiq2gr1EK4BU7P6kFNdt
Main's MCP spawn tool forwards the model via spawn metadata (upstream SpawnAgentRequest has no top-level model field), so the thin client's RelaySpawnAgentInput now carries metadata instead of model. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CPiq2gr1EK4BU7P6kFNdt
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CPiq2gr1EK4BU7P6kFNdt
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CHANGELOG.md`:
- Line 13: Shorten the `@agent-relay/sdk` changelog entry by removing the
parenthetical operation enumeration while retaining the user-visible factory
names and the concise description of typed raw pass-throughs for workspace-key
and agent-token operations.
- Line 17: Trim the changelog bullet to state only the user-visible change:
`@relaycast/sdk` is no longer a runtime dependency of the agent-relay CLI package.
Remove the hosted-engine client implementation details and the reassurance about
unchanged schemas, payloads, and errors without splitting the entry.
In `@packages/sdk/src/messaging/thin-client.ts`:
- Around line 186-188: Update RelayCreateWorkspaceOptions so it no longer
exposes the unsupported originActor field inherited from
RelaycastTelemetryOptions, while retaining the telemetry options that
createWorkspace forwards, including agentRelayDistinctId. Keep createWorkspace
behavior unchanged and ensure its accepted options type matches the fields
actually passed to relaycastWorkspaceTelemetryOptions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 23cf3dd4-ad64-4105-b7a2-160182707533
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (13)
.agentworkforce/trajectories/completed/2026-07/traj_660tzjekxbgn/summary.md.agentworkforce/trajectories/completed/2026-07/traj_660tzjekxbgn/trajectory.jsonCHANGELOG.mdpackages/cli/package.jsonpackages/cli/src/cli/agent-relay-mcp.tspackages/cli/src/cli/lib/relaycast-telemetry.tspackages/cli/src/cli/mcp/resources.tspackages/cli/src/cli/mcp/types.tspackages/cli/src/cli/mcp/workspace.tspackages/sdk/package.jsonpackages/sdk/src/__tests__/thin-client.test.tspackages/sdk/src/messaging/index.tspackages/sdk/src/messaging/thin-client.ts
💤 Files with no reviewable changes (2)
- packages/cli/package.json
- packages/cli/src/cli/lib/relaycast-telemetry.ts
|
|
||
| ### Changed | ||
|
|
||
| - `agent-relay mcp` now talks to the hosted engine exclusively through `@agent-relay/sdk` thin clients instead of constructing raw `@relaycast/sdk` clients; `@relaycast/sdk` is no longer a runtime dependency of the `agent-relay` CLI package. Tool schemas, payloads, and error behavior are unchanged. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Remove internal notes and implementation details from the MCP changelog entry.
"Tool schemas, payloads, and error behavior are unchanged" is an internal reassurance note, and "talks to the hosted engine exclusively through @agent-relay/sdk thin clients instead of constructing raw @relaycast/sdk clients" is implementation detail. The user-visible change is the removal of @relaycast/sdk as a runtime dependency. Per coding guidelines, omit internal notes and implementation details.
Based on learnings, a single bullet representing one user-visible change should not be force-split; trim the excess rather than creating separate entries.
📝 Suggested revision
-- `agent-relay mcp` now talks to the hosted engine exclusively through `@agent-relay/sdk` thin clients instead of constructing raw `@relaycast/sdk` clients; `@relaycast/sdk` is no longer a runtime dependency of the `agent-relay` CLI package. Tool schemas, payloads, and error behavior are unchanged.
+- `agent-relay` CLI no longer depends on `@relaycast/sdk` at runtime; hosted-engine communication now goes through `@agent-relay/sdk`.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - `agent-relay mcp` now talks to the hosted engine exclusively through `@agent-relay/sdk` thin clients instead of constructing raw `@relaycast/sdk` clients; `@relaycast/sdk` is no longer a runtime dependency of the `agent-relay` CLI package. Tool schemas, payloads, and error behavior are unchanged. | |
| - `agent-relay` CLI no longer depends on `@relaycast/sdk` at runtime; hosted-engine communication now goes through `@agent-relay/sdk`. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@CHANGELOG.md` at line 17, Trim the changelog bullet to state only the
user-visible change: `@relaycast/sdk` is no longer a runtime dependency of the
agent-relay CLI package. Remove the hosted-engine client implementation details
and the reassurance about unchanged schemas, payloads, and errors without
splitting the entry.
Sources: Coding guidelines, Learnings
…Options; tighten changelog entries createWorkspace only forwards agentRelayDistinctId (workspace provisioning has no origin actor), so the options type no longer advertises a field the call silently drops. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CPiq2gr1EK4BU7P6kFNdt
Summary
The MCP server (
packages/cli/src/cli/agent-relay-mcp.ts) violated the dogfood rule by importingRelayCast/AgentClient/WsClientfrom@relaycast/sdkand constructing raw clients at every call site. A previous pass judged the migration infeasible because@agent-relay/sdklacked an equivalent thin-client surface. This PR builds that surface, then migrates.Audit: what the MCP needs from raw
@relaycast/sdk30 distinct methods / constructions across ~15 client-construction call sites:
RelayCast.createWorkspaceagents.registerOrRotate,agents.list,agents.spawn,agents.releasesend,messages,reply,thread,dm,dms.{conversations,messages,createGroup,sendMessage},channels.{create,list,join,leave,invite,setTopic,archive},react,unreact,search,inbox,markRead,readers,actions.invokenew WsClient+on('*')/connect/disconnectSDK_VERSIONSDK addition: thin raw pass-through clients
New
packages/sdk/src/messaging/thin-client.ts(a new file layered on the existing contracts —normalize.tsdeliberately untouched to avoid conflicts with the concurrent messaging-internals refactor):createWorkspaceClient({workspaceKey, baseUrl})→RelayWorkspaceThinClientcreateAgentClient({agentToken, baseUrl, autoHeartbeatMs})→RelayAgentThinClient(heartbeats disabled by default)createRealtimeClient({agentToken, baseUrl})→RelayRealtimeThinClientcreateWorkspace(name, {baseUrl})→ raw workspace payloadRELAYCAST_SDK_VERSIONre-exportInput types reuse the
RelayMessagingClientvocabulary frommessaging/types.ts(RelayRegisterAgentInput,RelayCreateChannelInput,RelayListAgentsOptions,RelayListChannelsOptions,RelayMessageListOptions,RelayMessageMode); spawn/release inputs are new (RelaySpawnAgentInput,RelayReleaseAgentInput) since the contract lacked worker lifecycle.Why raw pass-throughs rather than
RelaycastMessagingClient: the MCP serializes upstream payloads directly into tool results, andRelaycastMessagingClientnormalizes every response (normalizeMessageetc.), which would change tool output strings. The thin clients return the raw client object behind a narrowed typed interface, so payloads, errors (isInvalidAgentTokenErrordetection), and dotted realtime event types (message.created) are bit-identical. Telemetry context (originActor,agentRelayDistinctId) resolves inside the factories from the same env vars the CLI helper used.Migration: 15 → 0 raw call sites
All raw constructions in
agent-relay-mcp.ts(getRelay,getAgentClient, the WS bridge,createWorkspace,resolveStdioBootstrapOptions) now go through the SDK factories. Zero call sites remain on the raw import; nothing was left behind.@relaycast/sdkremoved frompackages/clidependencies entirely. The startup test still mocks the'@relaycast/sdk'specifier — that mock now intercepts the SDK's internal import (the vitest alias maps@agent-relay/sdkto source), resolved via the workspace's hoisted copy.cli/lib/relaycast-telemetry.tsdeleted (its only consumer was the MCP; the SDK has the identical resolution logic).Verification
npm run build:core— cleanpackages/sdk:npm test117 passed (incl. 11 new thin-client tests),npm run checkandnpm run test:typescleanpackages/cli: full suite 343 passed / 5 skipped, includingagent-relay-mcp.startup.test.tsunchanged (the oracle: it asserts raw client configs,.as(token, {autoHeartbeatMs: false}), telemetry headers, and tool outputs)vitest run: 810 passed / 5 skippednpx knipoutput identical to theorigin/mainbaselineErrorinstance)🤖 Generated with Claude Code