@@ -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
569597var (
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