Skip to main content
Use Warp Grep as a tool in your AI agent workflows. The SDK provides adapters for Anthropic, OpenAI, Google Gemini, and Vercel AI SDK.

Quick Start

import Anthropic from '@anthropic-ai/sdk';
import { createWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/anthropic';

const anthropic = new Anthropic();
const grepTool = createWarpGrepTool({ 
  repoRoot: '.',
  morphApiKey: process.env.MORPH_API_KEY 
});

const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 12000,
  tools: [grepTool],
  messages: [{ role: 'user', content: 'Find authentication middleware' }]
});

// Execute tool call
const toolUse = response.content.find(c => c.type === 'tool_use');
if (toolUse) {
  const result = await grepTool.execute(toolUse.input);
  console.log(grepTool.formatResult(result));
}

Remote Execution

When your code lives in a remote sandbox (E2B, Modal, Daytona, Docker, SSH), use the remoteCommands option. You provide three simple functions that return raw stdout — the SDK handles all parsing. The remoteCommands option works with all SDK adapters:
import Anthropic from '@anthropic-ai/sdk';
import { createWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/anthropic';

const anthropic = new Anthropic();

const grepTool = createWarpGrepTool({
  repoRoot: '/home/user/repo',
  morphApiKey: process.env.MORPH_API_KEY,
  remoteCommands: {
    grep: async (pattern, path, glob) => {
      const r = await sandbox.run(`rg --no-heading '${pattern}' '${path}'`);
      return r.stdout;
    },
    read: async (path, start, end) => {
      const r = await sandbox.run(`sed -n '${start},${end}p' '${path}'`);
      return r.stdout;
    },
    listDir: async (path, maxDepth) => {
      const r = await sandbox.run(`find '${path}' -maxdepth ${maxDepth}`);
      return r.stdout;
    },
  },
});

const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 4096,
  tools: [grepTool],
  messages: [{ role: 'user', content: 'Find authentication middleware' }]
});

// Execute tool call
const toolUse = response.content.find(c => c.type === 'tool_use');
if (toolUse) {
  const result = await grepTool.execute(toolUse.input);
  console.log(grepTool.formatResult(result));
}
The SDK parses the raw output for you:
  • grep → expects ripgrep format (path:line:content)
  • read → expects raw file content (SDK adds line numbers)
  • listDir → expects one path per line (from find command)

Platform Examples

import { Sandbox } from "@e2b/code-interpreter";
import { createWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/anthropic';

const sandbox = await Sandbox.create();
const repoDir = "/home/user/repo";

// Clone repo and install ripgrep
await sandbox.commands.run(`git clone --depth 1 https://github.com/example/repo ${repoDir}`);
await sandbox.commands.run("apt-get update && apt-get install -y ripgrep");

const grepTool = createWarpGrepTool({
  repoRoot: repoDir,
  morphApiKey: process.env.MORPH_API_KEY,
  remoteCommands: {
    grep: async (pattern, path) => {
      const r = await sandbox.commands.run(
        `rg --no-heading --line-number '${pattern}' '${path}'`,
        { cwd: repoDir }
      );
      return r.stdout || '';
    },
    read: async (path, start, end) => {
      const r = await sandbox.commands.run(`sed -n '${start},${end}p' '${path}'`);
      return r.stdout || '';
    },
    listDir: async (path, maxDepth) => {
      const r = await sandbox.commands.run(
        `find '${path}' -maxdepth ${maxDepth} -not -path '*/node_modules/*'`
      );
      return r.stdout || '';
    },
  },
});

// Now use grepTool with Anthropic, OpenAI, Gemini, or Vercel AI SDK
Your sandbox needs ripgrep (rg) installed for the grep function. Most sandbox providers support installing it via apt-get install ripgrep.

Customize Tool Name and Description

Override the default tool name and description:
const grepTool = createWarpGrepTool({
  repoRoot: '.',
  morphApiKey: process.env.MORPH_API_KEY,
  name: 'code_search',
  description: 'Search for code patterns in the repository'
});
OptionDefaultDescription
namewarpgrep_codebase_searchTool name exposed to the LLM
description(see SDK)Tool description for the LLM

Response Types

Both direct usage and tool usage return the same structure:
interface WarpGrepResult {
  success: boolean;
  contexts?: Array<{
    file: string;    // File path relative to repo root
    content: string; // Relevant code section
  }>;
  summary?: string;  // Summary of findings
  error?: string;    // Error message if failed
}

Handling Results

const result = await grepTool.execute({ query: 'Find auth middleware' });

if (result.success) {
  console.log(`Found ${result.contexts.length} relevant sections`);
  
  for (const ctx of result.contexts) {
    console.log(`\n--- ${ctx.file} ---`);
    console.log(ctx.content);
  }
} else {
  console.error(`Search failed: ${result.error}`);
}

Type Exports

import type { 
  WarpGrepResult, 
  WarpGrepContext,
  WarpGrepToolConfig,
  RemoteCommands,
  
  // For custom provider implementations
  WarpGrepProvider,
  GrepResult,
  ReadResult,
  ListDirectoryEntry,
} from '@morphllm/morphsdk/tools/warp-grep';

Advanced: Custom Provider

For maximum control, implement the full WarpGrepProvider interface:
import type { WarpGrepProvider } from '@morphllm/morphsdk/tools/warp-grep';
import { runWarpGrep } from '@morphllm/morphsdk/tools/warp-grep';

const provider: WarpGrepProvider = {
  grep: async ({ pattern, path, glob }) => {
    // Return { lines: ['path:line:content', ...] }
    return { lines: [...] };
  },
  read: async ({ path, start, end }) => {
    // Return { lines: ['1|content', '2|content', ...] }
    return { lines: [...] };
  },
  listDirectory: async ({ path, maxDepth }) => {
    // Return array of entries
    return [{ name: 'file.ts', path: 'src/file.ts', type: 'file', depth: 1 }];
  },
};

const result = await runWarpGrep({
  query: 'Find authentication middleware',
  repoRoot: '/path/to/repo',
  provider,
  morphApiKey: process.env.MORPH_API_KEY,
});
Most users should use remoteCommands instead. Only use WarpGrepProvider if you need to customize the output format or add caching/batching logic.