Skip to content
64 changes: 49 additions & 15 deletions resources/mcp-bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,20 @@ const TOOLS = [
{
name: 'create_worktree',
description:
"Create a new git worktree in a Harness-managed repo. Harness will open a new Claude chat tab inside the new worktree automatically. Defaults to the caller's current repo when repoRoot is omitted.",
"Create a new git worktree in a Harness-managed repo. Either create a brand-new branch (set branchName) OR check out an existing GitHub PR for review (set prNumber). Harness will open a new agent chat tab inside the new worktree automatically. Defaults to the caller's current repo when repoRoot is omitted.",
inputSchema: {
type: 'object',
properties: {
branchName: {
type: 'string',
description: 'Name of the new branch to create for the worktree.'
description:
'Name of the new branch to create for the worktree. Required when not creating from a PR.'
},
prNumber: {
type: 'integer',
minimum: 1,
description:
'GitHub PR number to check out for review. When set, Harness fetches refs/pull/<n>/head into a local branch named after the PR head (or `<headBranch>-pr-<n>` if taken locally) and opens a worktree against it. Useful for "review this PR" workflows.'
},
repoRoot: {
type: 'string',
Expand All @@ -91,15 +98,25 @@ const TOOLS = [
baseBranch: {
type: 'string',
description:
"Branch to fork the new worktree from. Defaults to the repo's configured base."
"Branch to fork the new worktree from. Defaults to the repo's configured base. Ignored when prNumber is provided."
},
initialPrompt: {
type: 'string',
description:
'A prompt to automatically send to the Claude chat tab when it opens in the new worktree.'
'A prompt to automatically send to the agent chat tab when it opens in the new worktree. Useful for "review this PR for X" or "implement feature Y" prompts. When prNumber is set and this is omitted, Harness uses the configured PR review prompt (Settings → Worktrees → PR review prompt). Pass an empty string to explicitly suppress any kickoff prompt on the PR path.'
},
agentKind: {
type: 'string',
enum: ['claude', 'codex'],
description:
"Which CLI agent to spawn in the new worktree's first tab. Defaults to the user's configured default agent (Settings → Agent)."
},
model: {
type: 'string',
description:
"Model string to pass to the agent CLI's --model flag for this worktree's first tab (e.g. 'opus', 'sonnet-4-5', 'gpt-5'). Pinned per-tab — survives reloads, doesn't affect other worktrees. Omit to use the global default (Settings → Agent)."
}
},
required: ['branchName']
}
}
},
{
Expand Down Expand Up @@ -438,21 +455,38 @@ function filterToolsByPerms(tools, perms) {

async function handleToolCall(name, args) {
if (name === 'create_worktree') {
if (!args || !args.branchName) throw new Error('branchName is required')
const prNumber = args && args.prNumber
if (!args || (!args.branchName && !prNumber)) {
throw new Error('branchName or prNumber is required')
}
if (prNumber !== undefined && prNumber !== null) {
if (!Number.isInteger(prNumber) || prNumber <= 0) {
throw new Error('prNumber must be a positive integer')
}
}
if (
args.agentKind !== undefined &&
args.agentKind !== null &&
args.agentKind !== 'claude' &&
args.agentKind !== 'codex'
) {
throw new Error('agentKind must be "claude" or "codex"')
}
const r = await callControl('POST', '/worktrees', {
terminalId: TERMINAL_ID,
repoRoot: args.repoRoot,
branchName: args.branchName,
prNumber: prNumber,
baseBranch: args.baseBranch,
initialPrompt: args.initialPrompt
initialPrompt: args.initialPrompt,
agentKind: args.agentKind,
model: args.model
})
return (
'Created worktree ' +
r.path +
' on branch ' +
r.branch +
'. Harness will open a new Claude chat tab in it.'
)
const agentLabel = args.agentKind === 'codex' ? 'Codex' : 'Claude'
const modelSuffix = args.model ? ` (model: ${args.model})` : ''
return prNumber
? `Created worktree ${r.path} on branch ${r.branch} for PR #${prNumber}. Harness will open a new ${agentLabel} chat tab in it${modelSuffix}.`
: `Created worktree ${r.path} on branch ${r.branch}. Harness will open a new ${agentLabel} chat tab in it${modelSuffix}.`
}
if (name === 'list_worktrees') {
const q =
Expand Down
Loading
Loading