Skip to content

MCP Search Patterns - Comprehensive Guide ​

Purpose ​

This document provides concrete examples of correct and incorrect MCP tool usage patterns to prevent common mistakes like premature tool abandonment and non-existent project name guessing.

Table of Contents ​

  1. Quick Reference
  2. Session Initialization
  3. Correct Search Patterns
  4. Incorrect Patterns (Anti-Patterns)
  5. Search Strategy Decision Matrix
  6. Troubleshooting Failed Searches
  7. Real-World Scenarios

Quick Reference ​

Mandatory First Step (Every Session) ​

python
# ALWAYS run this at the start of each session
list_collections()

Indexed Collections (example output) ​

The collections present depend on what has been indexed in your environment. Always run list_collections() to see the live list and counts. The vector counts below are illustrative example output, not current state:

  • wdg_framework - Wikit framework (e.g. ~1546 vectors)
  • platform - Platform core (e.g. ~3382 vectors)
  • project_demo_project - Demo project (e.g. ~750 vectors)
  • project_test_project - Test project (e.g. ~750 vectors)

Collection Name Format ​

  • Framework: wdg_framework
  • Platform: platform
  • Projects: project_{project-name} (e.g., project_demo_project)

Tool Priority Order ​

  1. MCP Tools (ALWAYS FIRST - minimum 3 attempts)

    Discovery & scoping

    • list_collections()
    • get_project_info()
    • search_recent_changes()

    Core search

    • search_codebase()
    • search_all_collections() (when you don't know which collection holds the code)
    • search_functions()
    • search_classes()

    Relationship / structural search

    • search_code_patterns() (extends / implements / calls_function)
    • search_function_callers()
    • search_function_calls()

    WordPress & Wikit

    • search_wordpress_hooks() (registrations: add_action / add_filter)
    • search_hook_invocations() (invocations: do_action / apply_filters)
    • search_acf_fields() / search_acf_field_usages()
    • search_wikit_blocks() / get_block_schema()
    • wordpress_docs()

    Efficiency & persistence

    • batch_search() (run several searches in parallel)
    • save_search() / get_saved_search() / list_saved_searches() / delete_saved_search()
    • get_search_history()
  2. Traditional Tools (ONLY after exhausting MCP)

    • Glob() for file patterns
    • Grep() for content search
    • Read() for specific files

Session Initialization ​

✅ CORRECT: Start Every Session ​

python
# First thing in any new session
collections = list_collections()

# Output (example only — counts vary by environment):
# {
#   "collections": [
#     {"name": "wdg_framework", "vectors_count": 1546},
#     {"name": "platform", "vectors_count": 3382},
#     {"name": "project_demo_project", "vectors_count": 750},
#     {"name": "project_test_project", "vectors_count": 750}
#   ]
# }

# Now you know:
# - Available collections
# - Their sizes (indication of content)
# - Correct naming format

❌ INCORRECT: Skipping Initialization ​

python
# WRONG - Assuming what exists
search_codebase("feature", project="client-site")
# Result: Error - collection doesn't exist

# WRONG - Not checking first
search_codebase("code", project="my-project")
# Result: Error - project not indexed

Correct Search Patterns ​

✅ CORRECT ​

python
# Start with broad semantic search (NO project parameter)
results = search_codebase("payment gateway integration")
# Returns results from ALL indexed collections

# Then narrow if needed
results = search_codebase("Stripe payment API")
# Still broad but more specific

# Then project-specific if needed
results = search_codebase("payment processing", project="demo-project")
# Only after confirming demo-project exists

❌ INCORRECT ​

python
# WRONG - Starting too narrow
results = search_codebase("process_stripe_payment_gateway_checkout_v2")
# Too specific, might miss relevant code

# WRONG - Guessing project name
results = search_codebase("payment", project="ecommerce-site")
# Project doesn't exist, will fail

✅ CORRECT ​

python
# Search without project first
results = search_functions("render_block")
# Finds all render_block functions across all projects

# Search with language filter
results = search_functions("handleSubmit", language="javascript")
# Finds JavaScript functions only

# Search in specific project (after confirmation)
results = search_functions("wdg_render_block", project="demo-project")
# Searches only demo-project

❌ INCORRECT ​

python
# WRONG - Too specific immediately
results = search_functions("wdg_render_advanced_query_facet_filter_block")
# Overly specific, might not match

# WRONG - Unverified project
results = search_functions("my_function", project="new-client-site")
# Project not indexed

✅ CORRECT ​

python
# Search all hooks with partial name
results = search_wordpress_hooks("init")
# Finds all init-related hooks

# Search specific hook type
results = search_wordpress_hooks("woocommerce_checkout", hook_type="action")
# Only action hooks

# Broad then narrow
results = search_wordpress_hooks("payment")  # Broad
results = search_wordpress_hooks("payment_complete")  # Narrow

❌ INCORRECT ​

python
# WRONG - Immediately project-specific without checking
results = search_wordpress_hooks("custom_hook", project="fantasy-project")
# Project doesn't exist

# WRONG - Too specific
results = search_wordpress_hooks("woocommerce_before_calculate_totals_in_cart_with_coupons")
# Unlikely exact match

✅ CORRECT ​

python
# Broad class search
results = search_classes("PostType")
# Finds all PostType classes

# Namespace search
results = search_classes("WDG\\Core\\")
# Finds classes in WDG\Core namespace

# Specific class after broad search
results = search_classes("PaymentGateway", project="demo-project")

❌ INCORRECT ​

python
# WRONG - Guessing fully qualified name
results = search_classes("\\MyCompany\\Plugins\\WooCommerce\\Gateways\\Stripe\\V2\\PaymentProcessor")
# Too specific

# WRONG - Nonexistent project
results = search_classes("MyClass", project="imaginary-client")

Pattern 5: Multi-Strategy Approach ​

python
# User asks: "Find the user authentication code"

# Strategy 1: Broad semantic
search_codebase("user authentication")
# Found 3 results

# Strategy 2: Function search
search_functions("authenticate")
# Found 5 functions

# Strategy 3: Hook search
search_wordpress_hooks("authenticate", hook_type="filter")
# Found 2 WordPress auth hooks

# Strategy 4: Class search
search_classes("Auth")
# Found 1 authentication class

# Strategy 5: Recent changes
search_recent_changes(limit=20)
# Check if recent auth work

# NOW you have exhausted MCP strategies
# May use Grep/Read for specific files identified

❌ INCORRECT: Single-Attempt Abandonment ​

python
# WRONG - One attempt then quit
search_codebase("authentication", project="client-portal")
# Fails because project doesn't exist

# Then immediately:
Grep("authenticate", path="/var/repos")  # ❌ TOO SOON!

# Should have tried:
# - Broad search without project
# - Function search
# - Hook search
# - Class search
# - Recent changes

Incorrect Patterns (Anti-Patterns) ​

Anti-Pattern 1: Immediate Abandonment ​

❌ PROBLEM ​

python
# Attempt 1
search_codebase("feature", project="client-site")  # Fails

# Immediate fallback (WRONG!)
Grep("feature", glob="**/*.php")

✅ SOLUTION ​

python
# Attempt 1
search_codebase("feature", project="client-site")  # Fails

# Attempt 2
search_codebase("feature")  # Broad search

# Attempt 3
search_functions("feature")

# Attempt 4
search_classes("Feature")

# THEN if all fail:
Grep("feature", glob="**/*.php")  # Now appropriate

Anti-Pattern 2: Project Name Guessing ​

❌ PROBLEM ​

python
# Assuming project names without checking
search_codebase("code", project="wordpress-site")  # ❌
search_codebase("code", project="client-website")  # ❌
search_codebase("code", project="production")  # ❌

✅ SOLUTION ​

python
# Step 1: Check what exists
list_collections()
# Shows: project_demo_project, project_test_project

# Step 2: Use ACTUAL names
search_codebase("code", project="demo-project")  # ✅
search_codebase("code", project="test-project")  # ✅

Anti-Pattern 3: Too Narrow Too Soon ​

❌ PROBLEM ​

python
# Starting with ultra-specific search
search_codebase("WooCommerce_Payment_Gateway_Stripe_Checkout_Process_V2_Handler")
# No results - too specific

✅ SOLUTION ​

python
# Progressive narrowing
search_codebase("payment")  # Very broad
search_codebase("payment gateway")  # Narrower
search_codebase("stripe payment")  # More specific
search_functions("process_payment")  # Specific function

Anti-Pattern 4: Wrong Collection Format ​

❌ PROBLEM ​

python
# WRONG naming conventions
search_codebase("feature", project="demo_project")  # ❌ underscore
search_codebase("feature", project="DemoProject")  # ❌ capitalization
search_codebase("feature", project="project-demo-project")  # ❌ extra prefix

✅ SOLUTION ​

python
# CORRECT naming conventions
search_codebase("feature", project="demo-project")  # ✅ kebab-case
search_codebase("feature", project="test-project")  # ✅ matches collection name

# Note: Collection is "project_demo_project" but parameter is "demo-project"

Search Strategy Decision Matrix ​

User RequestFirst StrategySecond StrategyThird StrategyFourth Strategy
"Find feature X code"search_codebase("feature X")search_functions("feature_x")search_classes("FeatureX")search_recent_changes()
"Where is function Y?"search_functions("Y")search_codebase("Y")Grep("function Y")Read(file.php)
"Find WordPress hook Z"search_wordpress_hooks("Z")search_codebase("Z hook")wordpress_docs("Z")Grep("do_action.*Z")
"Find Wikit block ABC"search_wikit_blocks("ABC")search_codebase("wdg/ABC block")Glob("**/blocks/*ABC*")Read(blocks/ABC/)
"Find recent payment work"search_recent_changes()search_codebase("payment")search_functions("payment")Grep("payment")
"Find class definition"search_classes("ClassName")search_codebase("class ClassName")Glob("**/*ClassName*.php")Read(src/ClassName.php)

Troubleshooting Failed Searches ​

Problem: "No results found" ​

Diagnosis Steps ​

python
# 1. Verify collection exists
list_collections()
# Check if project is actually indexed

# 2. Try broader search
# Instead of: search_codebase("very_specific_function_name_v2")
# Try: search_codebase("function name")

# 3. Try different search type
search_functions("function_name")  # Instead of semantic search
search_classes("ClassName")  # Instead of function search

# 4. Check recent indexing
search_recent_changes(limit=20)
# See if content was recently added

# 5. Verify content is indexed
get_project_info("project-name")
# Check indexing status

Problem: "Collection/project not found" ​

Solution ​

python
# ALWAYS check what exists first
list_collections()

# Use correct format:
# Collection name: "project_demo_project"
# Parameter format: "demo-project" (kebab-case, no "project_" prefix)

# Correct usage:
search_codebase("query", project="demo-project")  # ✅

Problem: "Getting irrelevant results" ​

Solution ​

python
# 1. Be more specific
search_codebase("WordPress payment gateway Stripe")  # Instead of just "payment"

# 2. Use function search for exact names
search_functions("process_stripe_payment")  # Instead of semantic search

# 3. Filter by file type
search_codebase("feature", file_types=["php"])  # Exclude JS/CSS

# 4. Limit results for clarity
search_codebase("feature", limit=5)  # Top 5 results only

Real-World Scenarios ​

Scenario 1: Finding Payment Integration ​

Request: "Where is the WooCommerce payment gateway integration?"

❌ WRONG Approach ​

python
# Single attempt with guessed project name
search_codebase("payment gateway", project="ecommerce-site")
# Fails - project doesn't exist

# Immediate fallback to grep
Grep("payment_gateway", glob="**/*.php")  # ❌ TOO SOON

✅ CORRECT Approach ​

python
# Step 1: Verify collections
list_collections()
# Output: wdg_framework, platform, project_demo_project, project_test_project

# Step 2: Broad semantic search
results = search_codebase("WooCommerce payment gateway integration")
# Found 4 results across platform and demo-project

# Step 3: Function search
results = search_functions("process_payment")
# Found 2 functions: process_payment(), process_payment_gateway()

# Step 4: WordPress hooks
results = search_wordpress_hooks("woocommerce_payment", hook_type="action")
# Found: woocommerce_payment_complete, woocommerce_payment_token_created

# Step 5: Class search
results = search_classes("PaymentGateway")
# Found: WC_Payment_Gateway, Custom_Payment_Gateway

# Step 6: Check recent work
results = search_recent_changes(project="demo-project", limit=10)
# See recent payment-related commits

# Step 7: Read specific identified files
Read("/path/to/Custom_Payment_Gateway.php")  # ✅ Now justified

Scenario 2: Finding Custom Post Type ​

Request: "Show me the Products custom post type"

❌ WRONG Approach ​

python
# Overly specific immediate search
search_codebase("Products custom post type registration with meta fields and taxonomies")
# No results - too specific

✅ CORRECT Approach ​

python
# Step 1: Class search
results = search_classes("Products")
# Found: WDG\App\PostType\Products

# Step 2: Semantic search
results = search_codebase("product post type")
# Found relevant files

# Step 3: Function search
results = search_functions("register_product")
# Found registration function

# Step 4: Read identified files
Read("/path/to/PostType/Products.php")  # ✅

Scenario 3: Finding Recent Feature Work ​

Request: "What was the last feature added to the authentication system?"

❌ WRONG Approach ​

python
# Searching random terms
search_codebase("last feature added authentication")
# Vague results

✅ CORRECT Approach ​

python
# Step 1: Recent changes
results = search_recent_changes(limit=20)
# See all recent work

# Step 2: Filter for auth-related
results = search_recent_changes(project="demo-project", limit=10)
# Project-specific recent changes

# Step 3: Semantic search for auth
results = search_codebase("authentication system")
# Find auth-related code

# Step 4: Compare timestamps
# Cross-reference recent changes with auth code locations

Scenario 4: Finding Wikit Block Implementation ​

Request: "How does the wdg/card block work?"

❌ WRONG Approach ​

python
# Guessing file location
Read("/blocks/card/block.json")  # Might not exist at this path

✅ CORRECT Approach ​

python
# Step 1: Wikit block search
results = search_wikit_blocks("card")
# Found: wdg/card, wdg/card-slider, wdg/card-dynamic

# Step 2: Semantic search
results = search_codebase("wdg card block implementation")
# Found implementation files

# Step 3: Function search
results = search_functions("render_card")
# Found rendering functions

# Step 4: Read identified files
Read("/wikit-theme/block-editor/blocks/card/")  # ✅ Correct path

Scenario 5: Finding Hook Usage ​

Request: "Where do we hook into WordPress init?"

❌ WRONG Approach ​

python
# Basic grep immediately
Grep("add_action.*init", glob="**/*.php")  # ❌ Skipped MCP

✅ CORRECT Approach ​

python
# Step 1: Hook search
results = search_wordpress_hooks("init", hook_type="action")
# Found all init action hooks

# Step 2: Broad semantic
results = search_codebase("init action hook")
# Found files using init

# Step 3: Function search
results = search_functions("init")
# Found init methods

# Step 4: Then grep if needed
Grep("add_action.*init", glob="**/*.php")  # ✅ After MCP attempts

Success Checklist ​

Before using Grep/Read, verify you have:

  • [ ] Run list_collections() this session
  • [ ] Noted actual collection names
  • [ ] Tried broad semantic search with search_codebase()
  • [ ] Tried function search with search_functions()
  • [ ] Tried class search with search_classes()
  • [ ] Tried hook search with search_wordpress_hooks() (if applicable)
  • [ ] Tried recent changes with search_recent_changes()
  • [ ] Attempted at least 3 different MCP strategies
  • [ ] Documented why each strategy failed
  • [ ] Confirmed no other MCP approach would work

Only after checking all boxes above, proceed with Grep/Read.


Quick Commands Reference ​

python
# Session start (MANDATORY)
list_collections()

# General searches
search_codebase(query, project=None, file_types=None, component_type=None,
                exclude_patterns=None, include_context=False, context_lines=5, limit=20)
search_all_collections(query, file_types=None, component_type=None, limit=20)
search_functions(function_name, project=None, language="php", fuzzy_match=True)
search_classes(class_name, project=None, fuzzy_match=True)

# Structural / relationship searches
search_code_patterns(pattern_type, pattern_value, project=None, limit=20)  # extends|implements|calls_function
search_function_callers(function_name, project=None, limit=20)
search_function_calls(function_name, project=None)

# WordPress & Wikit
search_wordpress_hooks(hook_name, hook_type=None, project=None)            # registrations
search_hook_invocations(hook_name, invocation_type=None, project=None)     # do_action/apply_filters
search_acf_fields(field_name=None, field_type=None, group_name=None, project=None)
search_acf_field_usages(field_name, project=None)
search_wikit_blocks(block_name=None, has_attribute=None, supports=None, category=None)
get_block_schema(block_name, project=None)

# Recent work & project info
search_recent_changes(project=None, limit=10)
get_project_info(project_name)

# Batch, saved searches & history
batch_search(searches, parallel=True, fail_fast=False)
save_search(label, query, filters=None, description=None)
get_saved_search(label, execute=False)
list_saved_searches(sort_by="last_used", limit=20)
delete_saved_search(label)
get_search_history(limit=50, query_filter=None)

# WordPress documentation
wordpress_docs(query, type="all", get_details=False, limit=5)             # type: all|function|hook|class|method

# Traditional tools (AFTER MCP)
Glob(pattern, path=None)
Grep(pattern, path=None, glob=None, output_mode="files_with_matches")
Read(file_path)

Remember ​

MCP tools are your PRIMARY interface to the codebase. Traditional tools (grep/find/Read) are SECONDARY, used only after exhausting MCP options.

The pattern is simple:

  1. ✅ MCP FIRST (minimum 3 strategies)
  2. ✅ Document attempts (what you tried, why it failed)
  3. ✅ Then traditional tools (if really necessary)

This workflow ensures you leverage the intelligent, semantic search capabilities of the MCP system before falling back to basic text matching.