Skip to content

refactor(cli): route the MCP server through @agent-relay/sdk thin clients#1096

Merged
willwashburn merged 7 commits into
mainfrom
refactor/mcp-through-sdk
Jul 13, 2026
Merged

refactor(cli): route the MCP server through @agent-relay/sdk thin clients#1096
willwashburn merged 7 commits into
mainfrom
refactor/mcp-through-sdk

Conversation

@willwashburn

Copy link
Copy Markdown
Member

Summary

The MCP server (packages/cli/src/cli/agent-relay-mcp.ts) violated the dogfood rule by importing RelayCast/AgentClient/WsClient from @relaycast/sdk and constructing raw clients at every call site. A previous pass judged the migration infeasible because @agent-relay/sdk lacked an equivalent thin-client surface. This PR builds that surface, then migrates.

Audit: what the MCP needs from raw @relaycast/sdk

30 distinct methods / constructions across ~15 client-construction call sites:

  • Static: RelayCast.createWorkspace
  • Workspace-key client (4): agents.registerOrRotate, agents.list, agents.spawn, agents.release
  • Agent-token client (23): send, messages, reply, thread, dm, dms.{conversations,messages,createGroup,sendMessage}, channels.{create,list,join,leave,invite,setTopic,archive}, react, unreact, search, inbox, markRead, readers, actions.invoke
  • Realtime: new WsClient + on('*')/connect/disconnect
  • Constant: SDK_VERSION

SDK addition: thin raw pass-through clients

New packages/sdk/src/messaging/thin-client.ts (a new file layered on the existing contracts — normalize.ts deliberately untouched to avoid conflicts with the concurrent messaging-internals refactor):

  • createWorkspaceClient({workspaceKey, baseUrl})RelayWorkspaceThinClient
  • createAgentClient({agentToken, baseUrl, autoHeartbeatMs})RelayAgentThinClient (heartbeats disabled by default)
  • createRealtimeClient({agentToken, baseUrl})RelayRealtimeThinClient
  • createWorkspace(name, {baseUrl}) → raw workspace payload
  • RELAYCAST_SDK_VERSION re-export

Input types reuse the RelayMessagingClient vocabulary from messaging/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, and RelaycastMessagingClient normalizes every response (normalizeMessage etc.), which would change tool output strings. The thin clients return the raw client object behind a narrowed typed interface, so payloads, errors (isInvalidAgentTokenError detection), 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/sdk removed from packages/cli dependencies 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/sdk to source), resolved via the workspace's hoisted copy.
  • cli/lib/relaycast-telemetry.ts deleted (its only consumer was the MCP; the SDK has the identical resolution logic).

Verification

  • npm run build:core — clean
  • packages/sdk: npm test 117 passed (incl. 11 new thin-client tests), npm run check and npm run test:types clean
  • packages/cli: full suite 343 passed / 5 skipped, including agent-relay-mcp.startup.test.ts unchanged (the oracle: it asserts raw client configs, .as(token, {autoHeartbeatMs: false}), telemetry headers, and tool outputs)
  • Root vitest run: 810 passed / 5 skipped
  • npx knip output identical to the origin/main baseline
  • New SDK unit tests cover factory config construction, env + explicit telemetry resolution, method pass-through with raw-payload fidelity, and unchanged error propagation (same Error instance)

🤖 Generated with Claude Code

…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>
@willwashburn willwashburn requested a review from khaliqgant as a code owner June 11, 2026 17:34
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 61e8bc72-9cbe-4479-8e34-3812cff828e6

📥 Commits

Reviewing files that changed from the base of the PR and between db80c6f and d523aa4.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • packages/sdk/src/messaging/thin-client.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/messaging/thin-client.ts

📝 Walkthrough

Walkthrough

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

Changes

MCP thin-client migration

Layer / File(s) Summary
SDK thin-client contracts and factories
packages/sdk/src/messaging/thin-client.ts, packages/sdk/src/messaging/index.ts
Defines typed workspace, agent, and realtime clients, factory functions, telemetry configuration, workspace creation, and public exports.
Thin-client behavior validation
packages/sdk/src/__tests__/thin-client.test.ts, packages/sdk/package.json
Tests configuration, telemetry, passthrough methods, error propagation, heartbeat behavior, realtime events, and workspace creation.
CLI MCP client integration
packages/cli/src/cli/agent-relay-mcp.ts, packages/cli/src/cli/mcp/*
Routes MCP operations through thin-client factories and updates related type contracts.
Dependency and completion records
packages/cli/package.json, CHANGELOG.md, .agentworkforce/trajectories/completed/2026-07/traj_660tzjekxbgn/*
Updates CLI dependencies, records the unreleased migration, and documents rebase decisions and verification results.

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
Loading

Possibly related PRs

Suggested labels: size:XL

Suggested reviewers: khaliqgant, actions-user

Poem

I’m a rabbit with clients thin and bright,
Carrying messages cleanly through the night.
Workspace hops, agent ears gleam,
Realtime flows like a silver stream.
Tests thump softly: all paths are right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: migrating the MCP server to @agent-relay/sdk thin clients.
Description check ✅ Passed The description is detailed and well aligned with the PR, but it omits the template's Test Plan and Screenshots sections.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/mcp-through-sdk

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread CHANGELOG.md Outdated

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

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.

Suggested change
- `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
  1. 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)

Comment thread CHANGELOG.md Outdated

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

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.

Suggested change
- `@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
  1. 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)

claude and others added 4 commits July 13, 2026 16:14
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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8625a72 and db80c6f.

⛔ Files ignored due to path filters (1)
  • package-lock.json is 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.json
  • CHANGELOG.md
  • packages/cli/package.json
  • packages/cli/src/cli/agent-relay-mcp.ts
  • packages/cli/src/cli/lib/relaycast-telemetry.ts
  • packages/cli/src/cli/mcp/resources.ts
  • packages/cli/src/cli/mcp/types.ts
  • packages/cli/src/cli/mcp/workspace.ts
  • packages/sdk/package.json
  • packages/sdk/src/__tests__/thin-client.test.ts
  • packages/sdk/src/messaging/index.ts
  • packages/sdk/src/messaging/thin-client.ts
💤 Files with no reviewable changes (2)
  • packages/cli/package.json
  • packages/cli/src/cli/lib/relaycast-telemetry.ts

Comment thread CHANGELOG.md Outdated
Comment thread CHANGELOG.md Outdated

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Suggested change
- `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

Comment thread packages/sdk/src/messaging/thin-client.ts Outdated
claude and others added 2 commits July 13, 2026 18:33
…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
@willwashburn willwashburn merged commit c3c147b into main Jul 13, 2026
47 checks passed
@willwashburn willwashburn deleted the refactor/mcp-through-sdk branch July 13, 2026 18:45
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