Integration guide for Morph's WarpGrep (fast agentic code search) and Fast Apply (10,500 tok/s code editing)...
Morph provides two tools that significantly improve coding agent performance:
export MORPH_API_KEY="your-api-key"
bun add @morphllm/morphsdk
# or
npm install @morphllm/morphsdk
ripgrep is installed (required for local search):# macOS
brew install ripgrep
# Ubuntu/Debian
sudo apt install ripgrep
# Verify installation
rg --version
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
======================================================================
grep/rg is free and fast enough)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');
}
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
}
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';
}
}
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);
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 on the letta-code repository (~300 TypeScript files) using SDK v0.2.103:
| Query | Result | Time | Files Found |
|---|---|---|---|
| "Find authentication logic" | ā | 4.2s | src/auth/oauth.ts, src/auth/setup.ts, +2 |
| "Find the main CLI entry point" | ā | 5.8s | src/index.ts, src/cli/App.tsx |
| "Find where models are configured" | ā | 3.1s | src/agent/model.ts, src/models.json, +1 |
| "Find how memory blocks work" | ā | 3.9s | src/agent/memory.ts, src/agent/memoryFilesystem.ts, +1 |
| "Find the settings manager" | ā | 2.9s | src/settings-manager.ts, src/settings.ts |
5/5 tests passed
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:
| Tool | Description | Implementation |
|---|---|---|
grep |
Regex search across files | Uses ripgrep (rg) |
read |
Read file contents | Local filesystem |
list_dir |
Show directory structure | Local filesystem |
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā 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) ā
āāāāāāāāāāāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāāāāāāāā
From Morph's SWE-bench evaluation with Claude 4.5 Opus:
| Metric | Without WarpGrep | With WarpGrep | Improvement |
|---|---|---|---|
| Input Tokens | 14K | 9K | 39% fewer |
| Agent Turns | 35.0 | 26.0 | 26% fewer |
| Tasks Solved | 74.4% | 81.9% | 10% more |
Source: Morph WarpGrep Benchmarks
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
}
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);
}
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.
# Install ripgrep
brew install ripgrep # macOS
sudo apt install ripgrep # Ubuntu/Debian
# Verify
rg --version
# 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"}]}'
Ensure you're using the latest SDK:
bun add @morphllm/morphsdk@latest
# or
npm install @morphllm/morphsdk@latest