Skip to content
This repository was archived by the owner on Jun 1, 2026. It is now read-only.

feat(cron): per-task MCP server toggle in web UI#36

Closed
devinoldenburg wants to merge 1 commit into
mainfrom
feature/cron-mcp-server-toggle
Closed

feat(cron): per-task MCP server toggle in web UI#36
devinoldenburg wants to merge 1 commit into
mainfrom
feature/cron-mcp-server-toggle

Conversation

@devinoldenburg
Copy link
Copy Markdown
Collaborator

Summary

Makes it possible in the web UI to turn individual MCP servers on or off per automated (cron) task. Each task gets its own set of MCP server switches in the editor dialog. By default, all MCP servers are off for new tasks. When enabled servers are set, only those MCP tools are available to the task's agent runs.

Changes

Backend

  • packages/codeplane/src/cron/cron.sql.ts — Added mcp_servers JSON text column to cron_task table
  • packages/codeplane/src/cron/cron.ts — Added mcpServers: string[] field to Task, CreateInput, and UpdateInput schemas; updated taskFromRow, create(), and update() to store/retrieve the field
  • packages/codeplane/src/cron/scheduler.ts — Passes task's mcpServers to session metadata as enabledMcpServers when creating a cron run session
  • packages/codeplane/src/session/prompt.ts — Filters MCP tools in resolveTools based on session metadata enabledMcpServers (null/missing = all servers available, preserving backward compatibility)
  • packages/codeplane/src/session/session.ts — Added metadata to the Session.create() interface and CreateInput schema
  • packages/codeplane/src/server/routes/cron.ts — Added mcpServers to the create input validation zod schema
  • packages/codeplane/migration/ — Generated ALTER TABLE migration to add the mcp_servers column

Web UI

  • packages/app/src/pages/cron.tsx — Added MCP server toggle list with Switch components in the cron editor dialog, populated from globalSync.data.config.mcp
  • packages/app/src/utils/cron-client.ts — Added mcpServers to CronTask, CronCreateInput, and CronUpdateInput types
  • packages/app/src/i18n/en.ts — Added cron.field.mcpServers, cron.field.mcpServers.empty, and cron.field.mcpServers.help translations

Verification

  • bun turbo typecheck — passes (codeplane has only pre-existing pty.node.ts error, app passes cleanly)
  • bun lint — 0 errors

Each scheduled task now has its own list of MCP servers that can be
toggled on or off independently in the web UI editor dialog. Default
is all off. When enabled servers are set, only those MCP tools are
available to the task's runs. When null/empty (existing tasks), all
MCP servers remain available for backward compatibility.

- Add mcp_servers JSON column to cron_task table
- Add mcpServers field to Cron Task/CreateInput/UpdateInput schemas
- Pass enabled MCP servers to session metadata in the cron scheduler
- Filter MCP tools in prompt.ts based on session metadata
- Add MCP server toggle list with switches in cron editor dialog
- Add i18n translations for new MCP servers section

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 1, 2026 13:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds per-cron-task MCP server allowlisting so cron runs can be constrained to a selected subset of MCP tools, with storage in the cron task DB row and UI switches in the cron task editor.

Changes:

  • Persist mcp_servers on cron_task (schema + migration) and plumb through cron create/update.
  • Attach task MCP allowlist to cron run session metadata and filter MCP tools during prompt tool resolution.
  • Add UI for per-task MCP server selection and client/types/i18n wiring.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/codeplane/src/session/session.ts Extends session creation interface to accept metadata.
packages/codeplane/src/session/prompt.ts Filters MCP tools based on session.metadata.enabledMcpServers.
packages/codeplane/src/server/routes/cron.ts Accepts mcpServers on cron task creation requests.
packages/codeplane/src/cron/scheduler.ts Passes cron task MCP selection into session metadata for cron runs.
packages/codeplane/src/cron/cron.ts Adds mcpServers to cron task schemas and stores/loads mcp_servers.
packages/codeplane/src/cron/cron.sql.ts Adds mcp_servers JSON text column to the cron task table schema.
packages/codeplane/migration/20260601130626_add_mcp_servers_to_cron_tasks/snapshot.json Updates migration snapshot to include the new column.
packages/codeplane/migration/20260601130626_add_mcp_servers_to_cron_tasks/migration.sql Migration adding mcp_servers column.
packages/app/src/utils/cron-client.ts Adds mcpServers to cron task/create/update types.
packages/app/src/pages/cron.tsx Adds MCP server toggles to the cron editor and submits selection.
packages/app/src/i18n/en.ts Adds translations for MCP server selection UI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +654 to +662
const sanitizeMcp = (s: string) => s.replace(/[^a-zA-Z0-9_-]/g, "_")
const enabledMcpServers = input.session.metadata?.enabledMcpServers as string[] | undefined
const mcpTools = enabledMcpServers?.length
? Object.fromEntries(
Object.entries(allMcpTools).filter(([key]) =>
enabledMcpServers.some((name) => key.startsWith(sanitizeMcp(name) + "_")),
),
)
: allMcpTools
Comment on lines +654 to +656
const sanitizeMcp = (s: string) => s.replace(/[^a-zA-Z0-9_-]/g, "_")
const enabledMcpServers = input.session.metadata?.enabledMcpServers as string[] | undefined
const mcpTools = enabledMcpServers?.length
Comment on lines +155 to +157
metadata: task.mcpServers?.length
? { enabledMcpServers: task.mcpServers }
: undefined,
Comment on lines 448 to 452
last_run_status: null,
last_error: null,
next_run_at: nextRun,
mcp_servers: input.mcpServers ?? null,
time_created: now,
Comment on lines 574 to 578
agent: store.agent.trim() || null,
model: store.model.trim() || null,
status: store.status,
mcpServers: store.mcpServers.length > 0 ? store.mcpServers : null,
}
Comment on lines 589 to 593
agent: store.agent.trim() || undefined,
model: store.model.trim() || undefined,
status: store.status,
mcpServers: store.mcpServers.length > 0 ? store.mcpServers : undefined,
}
@devinoldenburg
Copy link
Copy Markdown
Collaborator Author

Review: per-task MCP server toggle

Status: Superseded by PR #37

All CI checks are green and the implementation is sound. However, PR #37 contains identical changes to all 11 files in this PR plus the additional LLM prompt cache stability fix. These two PRs cannot be merged independently due to critical conflicts on the migration file, schema changes, prompt filtering, session metadata, and UI code.

Closing this PR in favor of #37, which is the complete package. If you want to keep these separate, rebase #37 onto #36 and remove the duplicate MCP toggle files (keeping only llm.ts).

@devinoldenburg
Copy link
Copy Markdown
Collaborator Author

Closing as superseded by PR #37, which contains all the MCP server toggle changes from this PR plus the additional LLM prompt cache stability fix. The two PRs cannot be merged independently due to critical conflicts on 11 shared files.

If you prefer to keep them separate, rebase #37 onto this branch and remove the duplicate MCP toggle files (keeping only llm.ts changes).

devinoldenburg pushed a commit that referenced this pull request Jun 1, 2026
…ystem message layout

Includes the complete MCP server toggle feature (superseding PR #36)
plus the 2-part system message compaction for prompt cache stability.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants