Skip to content

feat(playground): add ACP (Cursor CLI) agent provider - #2622

Open
kantord wants to merge 4 commits into
mainfrom
try-acp
Open

kantord wants to merge 4 commits into
mainfrom
try-acp

Conversation

@kantord

@kantord kantord commented Aug 17, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds an ACP-based chat provider ("Cursor Agent") to the Playground that spawns the local Cursor CLI (agent acp) as an Agent Client Protocol server and streams it through the existing chat pipeline.
  • The model picker now separates plain "AI Models" providers from "AI Harnesses" (agents that run their own tool loop) — Cursor Agent lives in the latter section.
  • Hides/repurposes the in-chat "configure MCP tools" control for this provider (it runs its own tool loop, so per-tool toggles don't apply) — it now links to the MCP servers page instead.
  • The cursor client is registered automatically with ToolHive's default group the moment Cursor Agent is picked in the model picker (same mechanism "Manage Clients" uses), so ToolHive's MCP servers get wired into Cursor's own config. Provider Settings shows this as a live, read-only registration status.
  • Adds a per-thread working-directory picker for this provider (previously hardcoded to the main process's own cwd).

Test plan

  • pnpm run type-check
  • pnpm run lint
  • pnpm run test:nonInteractive (232 files / 2616 tests)
  • Manual verification of all flows in the running app

Fully or partially written by an AI agent.

kantord and others added 4 commits August 13, 2026 14:10
- show a "go to MCP servers page" link instead of tool toggles when an ACP provider is active, since ACP agents run their own tool loop
- replace the ACP "enable" text field with a real switch wired to ToolHive's client registration, so toggling it registers/unregisters the `cursor` client in the default group
- add a per-thread working-directory picker for ACP providers, replacing the hardcoded main-process cwd, via a new `acp_cwd` threads column and full reader/writer/service/IPC chain

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Daniel Kantor <kd@stacklok.com>
- register the `cursor` client with ToolHive's default group automatically the moment Cursor Agent is picked in the model selector, instead of requiring a separate manual toggle
- drop the now-unneeded "enable" switch from Provider Settings in favor of a live read-only registration status
- split the model picker into "AI Models" and "AI Harnesses" sections, and rename the provider from "ACP (Cursor Agent)" to "Cursor Agent" throughout the UI

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Daniel Kantor <kd@stacklok.com>
Cursor Agent was showing up in the model picker unconditionally, since
harness providers bypass the usual credential check. Only surface it
when ToolHive's discovery reports the `cursor` client as installed,
same signal Provider Settings and Manage Clients already use — picking
an uninstalled harness would just fail to spawn.

Also consolidates the harness-provider-id -> ToolHive-client-type
mapping (previously duplicated as local consts) into shared helpers in
lib/utils.ts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Daniel Kantor <kd@stacklok.com>
@kantord
kantord marked this pull request as ready for review August 18, 2026 10:26
Copilot AI lite review requested due to automatic review settings August 18, 2026 10:26

Copilot AI 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.

Pull request overview

This PR adds an ACP-based “Cursor Agent” provider to the Playground chat system, integrating a locally spawned Cursor CLI (agent acp) into the existing IPC chat pipeline while separating “AI Models” from “AI Harnesses” in the model picker and introducing per-thread working-directory selection for ACP.

Changes:

  • Introduces a new acp chat provider (“Cursor Agent”) in the main process and adds dependency/bundling support for @mcpc-tech/acp-ai-provider.
  • Updates the model picker/selector UX to separate harnesses from models and to auto-register the Cursor client into ToolHive’s default group.
  • Adds per-thread ACP working-directory persistence (IPC + DB migration) and surfaces it in the chat input via a directory picker.

Reviewed changes

Copilot reviewed 27 out of 28 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
renderer/src/route-tree.gen.ts Regenerated route tree output (ordering/route type entries).
renderer/src/features/clients/hooks/use-manage-clients.ts Invalidates chat provider-settings cache when client group membership changes.
renderer/src/features/chat/transport/electron-ipc-chat-transport.ts Adds optional cwd to IPC chat settings for ACP threads.
renderer/src/features/chat/lib/utils.ts Adds harness-provider helpers/constants for ACP and its backing client type.
renderer/src/features/chat/hooks/use-chat-settings.ts Adds useAcpCwd hook for per-thread ACP cwd storage via IPC.
renderer/src/features/chat/hooks/use-available-models.ts Adjusts available-provider gating for harness providers (ACP) using installed-client discovery.
renderer/src/features/chat/components/model-selector.tsx Auto-registers harness client on selection and persists sentinel settings for harness gating.
renderer/src/features/chat/components/model-picker.tsx Splits providers into “AI Models” vs “AI Harnesses” sections in the dropdown UI.
renderer/src/features/chat/components/mcp-server-selector.tsx Replaces tool toggles with a “manage MCP servers” link for ACP threads.
renderer/src/features/chat/components/dialog-provider-settings.tsx Displays read-only registration status for ACP/Cursor in Provider Settings.
renderer/src/features/chat/components/chat-input-prompt.tsx Conditionally renders ACP cwd picker and ACP-specific MCP-server UI.
renderer/src/features/chat/components/acp-cwd-picker.tsx New UI control to choose per-thread working directory for Cursor Agent.
preload/src/api/chat.ts Adds preload IPC API surface for getting/setting ACP cwd and includes cwd in stream options.
pnpm-lock.yaml Locks new dependency graph for ACP provider and transitive packages.
package.json Adds @mcpc-tech/acp-ai-provider dependency.
main/vite.main.config.ts Externalizes @mcpc-tech/acp-ai-provider to avoid bundling issues with import.meta.url.
main/src/ipc-handlers/chat/thread-settings.ts Adds IPC handlers for getting/setting per-thread ACP cwd.
main/src/db/writers/threads-writer.ts Persists acp_cwd to the threads table.
main/src/db/readers/threads-reader.ts Reads acp_cwd from the threads table.
main/src/db/migrator.ts Registers migration 008 for the new acp_cwd column.
main/src/db/migrations/008-thread-acp-cwd.ts Adds nullable acp_cwd column to threads.
main/src/chat/utils.ts Passes cwd through to provider model creation for API-key providers (ACP ignores key, uses cwd).
main/src/chat/types.ts Extends chat request/provider typing to include optional cwd.
main/src/chat/threads/threads-repository.ts Adds repository methods to read/write per-thread ACP cwd.
main/src/chat/thread-settings-storage.ts Adds sync wrappers to get/set ACP cwd via ThreadSettingsService.
main/src/chat/settings/thread-settings-service.ts Implements service methods for reading/writing ACP cwd.
main/src/chat/providers/providers-catalog.ts Adds the acp provider that spawns agent acp with a resolved cwd.
main/src/chat/constants.ts Adds provider metadata for the acp provider (“Cursor Agent”).
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +58 to +63
availableProviders.filter((provider) => {
if (provider.hasCredentials) return true
if (!isHarnessProvider(provider.id)) return false
const clientType = getHarnessClientType(provider.id)
return installedClients.some((c) => c.client_type === clientType)
}),
Comment on lines +56 to +60
setThreadAcpCwd: (threadId: string, cwd: string | null) =>
Effect.gen(function* () {
yield* ensureRow(threadId)
yield* repo.writeThreadAcpCwd(threadId, cwd || null)
}),
Comment on lines +186 to +190
trackEvent('Playground: navigate to MCP servers from ACP')
navigate({
to: '/group/$groupName',
params: { groupName: 'default' },
})
Comment on lines +473 to +477
export function useAcpCwd(threadId?: string | null) {
const queryClient = useQueryClient()

const { data: cwd, isLoading } = useQuery({
queryKey: threadId
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants