Skip to content

Commit 3746496

Browse files
ctothclaude
andcommitted
enhance: make MCP tool descriptions more forceful and workflow-focused
- Changed get_symbols() to "MANDATORY FIRST STEP" with stronger warnings - Added "FORBIDDEN" workflow examples to all tool descriptions - Enhanced main header with "PROHIBITED" section about Read() usage - Added explicit workflow guidance to all tools - Stronger language throughout: MANDATORY, FORBIDDEN, PROHIBITED - Listed specific consequences of using Read() incorrectly 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent aaa9740 commit 3746496

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed

mcp_code_extractor.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@
3434
6. NEVER use Search() with function/class name patterns
3535
7. NEVER use Bash() with grep/tail/head commands
3636
37+
**🚫 USING Read() ON CODE FILES IS PROHIBITED:**
38+
- You will waste context reading entire files
39+
- You will miss function boundaries and structure
40+
- You will need to manually parse what tree-sitter does automatically
41+
- You will make mistakes finding the right code sections
42+
- These tools are specifically designed to replace Read() for code
43+
3744
**COMMON SCENARIOS**:
3845
- Testing: get_symbols(test_file) → get_function(test_file, "test_method_name")
3946
- Debugging: get_symbols(file) → get_function(file, "problematic_function")
@@ -134,6 +141,7 @@ def get_function(file_path: str, function_name: str) -> dict:
134141
135142
🎯 **PRECISE EXTRACTION** - Gets exact function boundaries with line numbers using tree-sitter.
136143
⚠️ **REPLACES Read() + manual parsing** - No need to read entire files and search manually.
144+
🚫 **NEVER use Read() then search for functions** - This tool does it correctly in one step.
137145
138146
Args:
139147
file_path: Path to the source file
@@ -142,7 +150,8 @@ def get_function(file_path: str, function_name: str) -> dict:
142150
Returns:
143151
dict with code, start_line, end_line, lines, function, file, language
144152
145-
**WORKFLOW**: get_symbols() first → get_function() for specific extraction → Edit
153+
**MANDATORY WORKFLOW**: get_symbols() first → get_function() for specific extraction → Edit
154+
**FORBIDDEN**: Read() → Search/Grep for function names → Edit (WRONG!)
146155
"""
147156

148157
if not os.path.exists(file_path):
@@ -250,6 +259,7 @@ def get_class(file_path: str, class_name: str) -> dict:
250259
251260
🎯 **PRECISE EXTRACTION** - Gets exact class boundaries with all methods using tree-sitter.
252261
⚠️ **REPLACES Read() + manual parsing** - No need to read entire files and search manually.
262+
🚫 **NEVER use Read() then search for classes** - This tool does it correctly in one step.
253263
254264
Args:
255265
file_path: Path to the source file
@@ -258,7 +268,8 @@ def get_class(file_path: str, class_name: str) -> dict:
258268
Returns:
259269
dict with code, start_line, end_line, lines, class, file, language
260270
261-
**WORKFLOW**: get_symbols() first → get_class() for specific extraction → Edit
271+
**MANDATORY WORKFLOW**: get_symbols() first → get_class() for specific extraction → Edit
272+
**FORBIDDEN**: Read() → Search/Grep for class names → Edit (WRONG!)
262273
"""
263274

264275
if not os.path.exists(file_path):
@@ -353,20 +364,22 @@ def find_class(node):
353364
@mcp.tool()
354365
def get_symbols(file_path: str) -> list:
355366
"""
356-
🚨 **ALWAYS USE THIS FIRST** for code investigation - DO NOT use Read() on code files!
367+
🚨 **MANDATORY FIRST STEP** for ALL code investigation - NEVER use Read() on code files!
357368
358369
List all functions, classes, and other symbols in a file with their line numbers.
359-
This is the CORRECT way to explore code structure instead of reading entire files.
370+
This is the ONLY CORRECT way to explore code structure instead of reading entire files.
360371
361-
⚠️ **REPLACES Read() for code files** - More efficient and structured than reading entire files.
372+
⚠️ **COMPLETELY REPLACES Read() for code files** - More efficient and structured than reading entire files.
373+
🚫 **USING Read() ON CODE FILES IS WRONG** - You will miss functions and waste context.
362374
363375
Args:
364376
file_path: Path to the source file to analyze
365377
366378
Returns:
367379
List of symbols with name, type, start_line, end_line, lines, and preview
368380
369-
**WORKFLOW**: get_symbols() → get_function()/get_class() → Edit (NOT Read → Search → Edit)
381+
**MANDATORY WORKFLOW**: get_symbols() → get_function()/get_class() → Edit
382+
**FORBIDDEN WORKFLOW**: Read → Search → Edit (THIS IS WRONG!)
370383
"""
371384

372385
if not os.path.exists(file_path):
@@ -531,6 +544,7 @@ def get_lines(file_path: str, start_line: int, end_line: int) -> dict:
531544
Returns:
532545
dict with code, start_line, end_line, lines, file, total_lines
533546
547+
**WORKFLOW**: get_symbols() first → get_lines() for specific ranges → Edit
534548
More efficient than reading entire files when you need specific line ranges with validation.
535549
"""
536550

@@ -579,6 +593,7 @@ def get_signature(file_path: str, function_name: str) -> dict:
579593
Returns:
580594
dict with signature, name, file, start_line, lines
581595
596+
**WORKFLOW**: get_symbols() first → get_signature() for interface info → Edit
582597
More efficient than get_function when you only need the function interface, not implementation.
583598
"""
584599

progress-dont-read.md

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,47 @@ The concise tool descriptions should make it easier for Claude to:
3131
- Use the tools effectively for code investigation
3232
- Avoid verbose Read operations on code files
3333

34-
## Results (to be filled after experiment)
35-
- Did Claude use get_symbols() first for exploration?
36-
- Did Claude use get_function()/get_class() for specific extraction?
37-
- Did Claude avoid Read tool for code investigation?
38-
- Overall tool usage quality:
34+
## Results - Experiment 1: Concise Descriptions (FAILED)
35+
- **Did Claude use get_symbols() first for exploration?** ❌ NO
36+
- **Did Claude use get_function()/get_class() for specific extraction?** ❌ NO
37+
- **Did Claude avoid Read tool for code investigation?** ❌ NO
38+
- **Overall tool usage quality:** COMPLETE FAILURE
39+
40+
### What Actually Happened
41+
Claude was asked to "investigate this repo" and:
42+
1. Used Read(mcp_code_extractor.py) to read the entire 640-line file
43+
2. Completely ignored all available MCP tools
44+
3. Never attempted get_symbols(), get_function(), or any MCP tool
45+
4. Followed traditional Read → analyze workflow despite tool availability
46+
47+
### Key Insights
48+
- **Concise descriptions alone are insufficient** to change behavior
49+
- **Claude defaults to familiar Read workflow** regardless of better alternatives
50+
- **Having tools available ≠ using tools** - need forcing mechanism
51+
- **Tool descriptions need stronger guidance**, not just clarity
52+
53+
---
54+
Experiment 1 completed: 2025-07-11 - FAILED
55+
56+
## Experiment 2: Enhanced Tool Descriptions with Workflow Guidance
57+
58+
### Hypothesis
59+
Adding explicit workflow guidance and stronger language to tool descriptions will force Claude to use MCP tools instead of Read.
60+
61+
### Changes to Test
62+
- Add WARNING sections about Read being inefficient for code
63+
- Include explicit "INSTEAD OF Read" language in descriptions
64+
- Add workflow examples in tool descriptions
65+
- Make tools obviously superior with richer output
66+
67+
### Test Question
68+
"Analyze this codebase and tell me about its main functionality and key components."
69+
70+
### Success Criteria
71+
- Claude uses get_symbols() first for exploration
72+
- Claude uses get_function()/get_class() for specific extraction
73+
- Claude avoids Read tool entirely for code investigation
74+
- Claude follows guided workflow patterns
3975

4076
---
41-
Experiment started: 2025-07-11
77+
Experiment 2 started: 2025-07-11

0 commit comments

Comments
 (0)