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()

Current Indexed Collections

Based on list_collections() output:

  • wdg_framework - Wikit framework (1546 vectors)
  • platform - Platform core (3382 vectors)
  • project_demo_project - Demo project (750 vectors)
  • project_test_project - Test project (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)

    • list_collections()
    • search_codebase()
    • search_functions()
    • search_classes()
    • search_wordpress_hooks()
    • search_wikit_blocks()
    • search_recent_changes()
    • get_project_info()
    • wordpress_docs()
  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 shows:
# {
#   "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, limit=20)
search_functions(function_name, project=None, language="php")
search_classes(class_name, project=None)
search_wordpress_hooks(hook_name, hook_type=None, project=None)
search_wikit_blocks(block_name=None)
search_recent_changes(project=None, limit=10)

# Project info
get_project_info(project_name)

# WordPress documentation
wordpress_docs(query, type="all", get_details=False)

# 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.

Released under the MIT License.