mcpField
M
morph-warpgrep

morph-warpgrep

github.com/letta-aiAgent workflows152174 installsUpdated 4w ago
Repository

About morph-warpgrep

Morph WarpGrep & Fast Apply is a coding-agent skill for semantic codebase search and applying generated edits. WarpGrep searches repository context through iterative local file tools, while Fast Apply merges edits into existing code.

Key features

  1. 01Search codebases with WarpGrep
  2. 02Refine searches through local file tools
  3. 03Return relevant code context
  4. 04Merge generated edits with Fast Apply
  5. 05Use as an MCP search tool

Use cases

  1. 01Trace logic across a large codebase
  2. 02Find code relevant to a bug
  3. 03Apply generated edits to existing files

MCP support

The README describes an MCP server installable for clients such as Claude Code and Cursor. It exposes the `warpgrep_codebase_search` tool.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/letta-ai/skills --skill morph-warpgrep

After installing, type/morph-warpgrepin Claude Code to confirm it loaded.

Bundled filesLICENSEscripts/test-warpgrep.ts

Details

From the project README

Morph WarpGrep & Fast Apply

Morph provides two tools that significantly improve coding agent performance:

  • WarpGrep: Agentic code search that's 5x faster than regular search, uses parallel tool calls, achieves 0.73 F1 in ~4 steps
  • Fast Apply: Merges AI edits into code at 10,500 tok/s with 98% accuracy (2x faster than search-replace)

Prerequisites

  1. Get a Morph API key from https://www.morphllm.com/dashboard
  2. Set environment variable:
export MORPH_API_KEY="your-api-key"
  1. Install the Morph SDK:
bun add @morphllm/morphsdk
# or
npm install @morphllm/morphsdk
  1. Ensure ripgrep is installed (required for local search):
# macOS
brew install ripgrep

# Ubuntu/Debian  
sudo apt install ripgrep

# Verify installation
rg --version

Quick Test

After setup, run the included test script on any local repository:

# Clone a test repo (or use any existing codebase)
git clone https://github.com/letta-ai/letta-code.git test-repo

# Install SDK
cd test-repo
bun add @morphllm/morphsdk

# Run test script
export MORPH_API_KEY="your-key"
bun ../scripts/test-warpgrep.ts .

Expected output:

======================================================================
MORPH WARPGREP TEST
======================================================================
Repo: .
SDK: @morphllm/morphsdk
======================================================================

| Query                              | Result | Time   | Files |
|------------------------------------|--------|--------|-------|
| Find the main entry point          | ✅     | 5.2s   | 2     |
| Find authentication logic          | ✅     | 4.1s   | 4     |
| Find where configuration is handled | ✅     | 3.8s   | 3     |
| Find error handling patterns       | ✅     | 4.5s   | 5     |

======================================================================
Results: 4 passed, 0 failed
======================================================================

When to Use

Use WarpGrep When:
  • Searching large codebases (1000+ files)
  • Deep logic queries: bug tracing, code paths, control flow analysis
  • Need to find relevant context without polluting the context window
  • Regular grep returns too many irrelevant results
Use Fast Apply When:
  • Applying AI-generated code edits to existing files
  • Need reliable edit merging (98% accuracy vs ~70% for search-replace)
  • Working with large files where diff formats fail
Don't Use When:
  • Simple exact-match searches (regular grep/rg is free and fast enough)
  • Surface-level queries where semantic search suffices
  • Cost is a major concern (Morph API has usage costs)

Quick Start: WarpGrep

Basic Usage
import { MorphClient } from '@morphllm/morphsdk';

const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });

const result = await morph.warpGrep.execute({
  query: 'Find authentication middleware',
  repoRoot: '.'
});

if (result.success) {
  for (const ctx of result.contexts) {
    console.log(`File: ${ctx.file}`);
    console.log(ctx.content);
  }
} else {
  console.error('Search failed');
}
Response Format
interface WarpGrepResult {
  success: boolean;
  contexts: Array<{
    file: string;    // File path relative to repo root
    content: string; // File content with relevant code
  }>;
  summary?: string;  // Human-readable summary
}
Using as an Agent Tool
import { MorphClient } from '@morphllm/morphsdk';
import Anthropic from '@anthropic-ai/sdk';

const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });
const anthropic = new Anthropic();

// Define WarpGrep as a tool
const tools = [{
  name: 'warpgrep_search',
  description: 'Search codebase for relevant code. Use for finding implementations, tracing bugs, or understanding code flow.',
  input_schema: {
    type: 'object',
    properties: {
      query: { type: 'string', description: 'What to search for' }
    },
    required: ['query']
  }
}];

// Handle tool calls
async function handleToolCall(name: string, input: { query: string }) {
  if (name === 'warpgrep_search') {
    const result = await morph.warpGrep.execute({
      query: input.query,
      repoRoot: process.cwd()
    });
    
    if (result.success) {
      return result.contexts.map(c => `## ${c.file}\n${c.content}`).join('\n\n');
    }
    return 'No results found';
  }
}

Quick Start: Fast Apply

Fast Apply merges AI-generated edits into existing code:

import { MorphClient } from '@morphllm/morphsdk';

const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });

const result = await morph.fastApply.apply({
  originalCode: `function divide(a, b) {
  return a / b;
}`,
  editSnippet: `function divide(a, b) {
  if (b === 0) throw new Error("Division by zero");
  return a / b;
}`
});

console.log(result.mergedCode);
Direct API (Alternative)
const response = await fetch('https://api.morphllm.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.MORPH_API_KEY}`
  },
  body: JSON.stringify({
    model: 'morph-v3-fast',  // or 'morph-v3-large' for complex edits
    messages: [{
      role: 'user',
      content: `<instruction>Add error handling</instruction>
<code>function divide(a, b) { return a / b; }</code>
<update>function divide(a, b) {
  if (b === 0) throw new Error("Division by zero");
  return a / b;
}</update>`
    }],
    temperature: 0
  })
});

const data = await response.json();
const mergedCode = data.choices[0].message.content;

Tested Results

Tested on the letta-code repository (~300 TypeScript files) using SDK v0.2.103:

QueryResultTimeFiles Found
"Find authentication logic"✅4.2ssrc/auth/oauth.ts, src/auth/setup.ts, +2
"Find the main CLI entry point"✅5.8ssrc/index.ts, src/cli/App.tsx
"Find where models are configured"✅3.1ssrc/agent/model.ts, src/models.json, +1
"Find how memory blocks work"✅3.9ssrc/agent/memory.ts, src/agent/memoryFilesystem.ts, +1
"Find the settings manager"✅2.9ssrc/settings-manager.ts, src/settings.ts

5/5 tests passed

Performance Summary
  • Average time: 4.0 seconds
  • Token efficiency: 39% fewer input tokens vs manual search
  • Accuracy: Finds relevant code in 2-4 turns

How WarpGrep Works

WarpGrep is an agentic search that runs up to 4 turns:

┌─────────────────────────────────────────────────────────────┐
│  Turn 1: Analyze query, map repo structure, initial search  │
├─────────────────────────────────────────────────────────────┤
│  Turn 2-3: Refine search, read specific files               │
├─────────────────────────────────────────────────────────────┤
│  Turn 4: Return all relevant code locations                 │
└─────────────────────────────────────────────────────────────┘

The SDK handles the multi-turn conversation automatically, executing local tools:

ToolDescriptionImplementation
grepRegex search across filesUses ripgrep (rg)
readRead file contentsLocal filesystem
list_dirShow directory structureLocal filesystem

Architecture

┌──────────────────────────────────────────────────────────────┐
│                    Your Code / Agent                         │
└──────────────────────────┬───────────────────────────────────┘
                           │
                           ▼
┌──────────────────────────────────────────────────────────────┐
│              @morphllm/morphsdk                              │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │ 1. Build repo structure                                 │ │
│  │ 2. Send query to Morph API                              │ │
│  │ 3. Execute local tools (grep, read, list_dir)           │ │
│  │ 4. Multi-turn refinement                                │ │
│  │ 5. Return relevant code contexts                        │ │
│  └─────────────────────────────────────────────────────────┘ │
└──────────────────────────┬───────────────────────────────────┘
                           │
            ┌──────────────┴──────────────┐
            ▼                             ▼
┌───────────────────────┐    ┌───────────────────────┐
│    Morph API          │    │   Local Filesystem    │
│  (morph-warp-grep-v1) │    │   (ripgrep, fs)       │
└───────────────────────┘    └───────────────────────┘

Morph's Benchmarks

From Morph's SWE-bench evaluation with Claude 4.5 Opus:

MetricWithout WarpGrepWith WarpGrepImprovement
Input Tokens14K9K39% fewer
Agent Turns35.026.026% fewer
Tasks Solved74.4%81.9%10% more

Source: Morph WarpGrep Benchmarks


Common Patterns

Reconnaissance-Then-Action
import { MorphClient } from '@morphllm/morphsdk';

const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });

// 1. Search for relevant code
const result = await morph.warpGrep.execute({
  query: 'Where is the payment processing logic?',
  repoRoot: '.'
});

// 2. Use found contexts to inform next steps
if (result.success) {
  const relevantFiles = result.contexts.map(c => c.file);
  console.log('Found relevant files:', relevantFiles);
  // Now read/edit these specific files
}
Combining WarpGrep + Fast Apply
import { MorphClient } from '@morphllm/morphsdk';

const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });

// 1. Find the code to modify
const search = await morph.warpGrep.execute({
  query: 'Find the user validation function',
  repoRoot: '.'
});

if (search.success && search.contexts.length > 0) {
  const targetFile = search.contexts[0];
  
  // 2. Apply an edit
  const result = await morph.fastApply.apply({
    originalCode: targetFile.content,
    editSnippet: '// Add your modified version here'
  });
  
  console.log(result.mergedCode);
}

MCP Integration

For personal use with Claude Code, Cursor, or other MCP clients:

# Install MCP server
claude mcp add morph --scope user -e MORPH_API_KEY=YOUR_API_KEY --npx -y @morphllm/morphmcp

This adds a warpgrep_codebase_search tool to your MCP client.


Troubleshooting

ripgrep Not Found
# Install ripgrep
brew install ripgrep  # macOS
sudo apt install ripgrep  # Ubuntu/Debian

# Verify
rg --version
API Key Issues
# Verify API key works
curl -X POST https://api.morphllm.com/v1/chat/completions \
  -H "Authorization: Bearer $MORPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"morph-v3-fast","messages":[{"role":"user","content":"test"}]}'
SDK Version Issues

Ensure you're using the latest SDK:

bun add @morphllm/morphsdk@latest
# or
npm install @morphllm/morphsdk@latest

Cost Considerations

  • WarpGrep uses 1-4 API calls per search (typically 2-3)
  • Fast Apply uses 1 API call per edit
  • Pricing: $0.80 per 1M tokens (input and output)
  • Monitor usage via Morph Dashboard
  • Use regular grep/ripgrep for simple exact-match searches (free)

Resources

Comments

Markdown supported