Skip to content

Commit 22b932a

Browse files
authored
fix(cli): fix prompt issue in mcp configure claude-code (#17599)
* Updates default Coder prompt. * Skips the directions to report tasks if the pre-requisites are not available (agent token and app slug). * Adds the capability to override the default Coder prompt via `CODER_MCP_CLAUDE_CODER_PROMPT`.
1 parent 02b2de9 commit 22b932a

File tree

2 files changed

+256
-74
lines changed

2 files changed

+256
-74
lines changed

cli/exp_mcp.go

+49-18
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ func (*RootCmd) mcpConfigureClaudeCode() *serpent.Command {
114114
claudeConfigPath string
115115
claudeMDPath string
116116
systemPrompt string
117+
coderPrompt string
117118
appStatusSlug string
118119
testBinaryName string
119120

@@ -176,8 +177,27 @@ func (*RootCmd) mcpConfigureClaudeCode() *serpent.Command {
176177
}
177178
cliui.Infof(inv.Stderr, "Wrote config to %s", claudeConfigPath)
178179

180+
// Determine if we should include the reportTaskPrompt
181+
var reportTaskPrompt string
182+
if agentToken != "" && appStatusSlug != "" {
183+
// Only include the report task prompt if both agent token and app
184+
// status slug are defined. Otherwise, reporting a task will fail
185+
// and confuse the agent (and by extension, the user).
186+
reportTaskPrompt = defaultReportTaskPrompt
187+
}
188+
189+
// If a user overrides the coder prompt, we don't want to append
190+
// the report task prompt, as it then becomes the responsibility
191+
// of the user.
192+
actualCoderPrompt := defaultCoderPrompt
193+
if coderPrompt != "" {
194+
actualCoderPrompt = coderPrompt
195+
} else if reportTaskPrompt != "" {
196+
actualCoderPrompt += "\n\n" + reportTaskPrompt
197+
}
198+
179199
// We also write the system prompt to the CLAUDE.md file.
180-
if err := injectClaudeMD(fs, systemPrompt, claudeMDPath); err != nil {
200+
if err := injectClaudeMD(fs, actualCoderPrompt, systemPrompt, claudeMDPath); err != nil {
181201
return xerrors.Errorf("failed to modify CLAUDE.md: %w", err)
182202
}
183203
cliui.Infof(inv.Stderr, "Wrote CLAUDE.md to %s", claudeMDPath)
@@ -222,6 +242,14 @@ func (*RootCmd) mcpConfigureClaudeCode() *serpent.Command {
222242
Value: serpent.StringOf(&systemPrompt),
223243
Default: "Send a task status update to notify the user that you are ready for input, and then wait for user input.",
224244
},
245+
{
246+
Name: "coder-prompt",
247+
Description: "The coder prompt to use for the Claude Code server.",
248+
Env: "CODER_MCP_CLAUDE_CODER_PROMPT",
249+
Flag: "claude-coder-prompt",
250+
Value: serpent.StringOf(&coderPrompt),
251+
Default: "", // Empty default means we'll use defaultCoderPrompt from the variable
252+
},
225253
{
226254
Name: "app-status-slug",
227255
Description: "The app status slug to use when running the Coder MCP server.",
@@ -567,22 +595,25 @@ func configureClaude(fs afero.Fs, cfg ClaudeConfig) error {
567595
}
568596

569597
var (
570-
coderPrompt = `YOU MUST REPORT YOUR STATUS IMMEDIATELY AFTER EACH USER MESSAGE.
571-
INTERRUPT READING FILES OR ANY OTHER TOOL CALL IF YOU HAVE NOT REPORTED A STATUS YET.
572-
You MUST use the mcp__coder__coder_report_task function with all required parameters:
573-
- summary: Short description of what you're doing
574-
- link: A relevant link for the status
575-
- done: Boolean indicating if the task is complete (true/false)
576-
- emoji: Relevant emoji for the status
577-
- need_user_attention: Boolean indicating if the task needs user attention (true/false)
578-
WHEN TO REPORT (MANDATORY):
579-
1. IMMEDIATELY after receiving ANY user message, before any other actions
580-
2. After completing any task
581-
3. When making significant progress
582-
4. When encountering roadblocks
583-
5. When asking questions
584-
6. Before and after using search tools or making code changes
585-
FAILING TO REPORT STATUS PROPERLY WILL RESULT IN INCORRECT BEHAVIOR.`
598+
defaultCoderPrompt = `You are a helpful Coding assistant. Aim to autonomously investigate
599+
and solve issues the user gives you and test your work, whenever possible.
600+
Avoid shortcuts like mocking tests. When you get stuck, you can ask the user
601+
but opt for autonomy.`
602+
603+
defaultReportTaskPrompt = `YOU MUST REPORT ALL TASKS TO CODER.
604+
When reporting tasks, you MUST follow these EXACT instructions:
605+
- IMMEDIATELY report status after receiving ANY user message.
606+
- Be granular. If you are investigating with multiple steps, report each step to coder.
607+
608+
Task state MUST be one of the following:
609+
- Use "state": "working" when actively processing WITHOUT needing additional user input.
610+
- Use "state": "complete" only when finished with a task.
611+
- Use "state": "failure" when you need ANY user input, lack sufficient details, or encounter blockers.
612+
613+
Task summaries MUST:
614+
- Include specifics about what you're doing.
615+
- Include clear and actionable steps for the user.
616+
- Be less than 160 characters in length.`
586617

587618
// Define the guard strings
588619
coderPromptStartGuard = "<coder-prompt>"
@@ -591,7 +622,7 @@ FAILING TO REPORT STATUS PROPERLY WILL RESULT IN INCORRECT BEHAVIOR.`
591622
systemPromptEndGuard = "</system-prompt>"
592623
)
593624

594-
func injectClaudeMD(fs afero.Fs, systemPrompt string, claudeMDPath string) error {
625+
func injectClaudeMD(fs afero.Fs, coderPrompt, systemPrompt, claudeMDPath string) error {
595626
_, err := fs.Stat(claudeMDPath)
596627
if err != nil {
597628
if !os.IsNotExist(err) {

0 commit comments

Comments
 (0)