Quickstart - Morph Documentation

4 min read Original article ↗

Build an agent that edits files at 10,500 tok/s and searches codebases in 3.8 steps.

Fast Apply

Your agent outputs a lazy edit snippet (changed lines + // ... existing code ... markers). Morph merges it into the original file and returns the result. 98% accuracy, sub-second latency.

Install

npm install @morphllm/morphsdk

Get your API key from the dashboard.

Run it

Save as apply.ts and run:

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

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

const result = await morph.fastApply.execute({
  target_filepath: 'src/auth.ts',
  instructions: 'Add null check before session creation',
  code_edit: `
// ... existing code ...
if (!user) throw new Error("User not found");
// ... existing code ...
  `
});

console.log(result.diff);
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.MORPH_API_KEY,
  baseURL: "https://api.morphllm.com/v1",
});

const response = await client.chat.completions.create({
  model: "morph-v3-fast",
  messages: [
    {
      role: "user",
      content: `<instruction>${instructions}</instruction>\n<code>${originalCode}</code>\n<update>${codeEdit}</update>`,
    },
  ],
});

const mergedCode = response.choices[0].message.content;
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["MORPH_API_KEY"],
    base_url="https://api.morphllm.com/v1",
)

response = client.chat.completions.create(
    model="morph-v3-fast",
    messages=[{
        "role": "user",
        "content": f"<instruction>{instructions}</instruction>\n<code>{original_code}</code>\n<update>{code_edit}</update>"
    }],
)

merged_code = response.choices[0].message.content
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": "<instruction>Add error handling</instruction>\n<code>function login(email, password) {\n  const user = db.find(email);\n  const session = createSession(user);\n  return session;\n}</code>\n<update>function login(email, password) {\n  // ... existing code ...\n  if (!user) throw new Error(\"User not found\");\n  // ... existing code ...\n}</update>"
    }]
  }'

The instructions parameter must be generated by the model, not hardcoded. It provides context for ambiguous edits. Example: “Adding error handling to the user auth and removing the old auth functions.”

Add to your agent

The SDK provides tool factories for every major framework. One line gives your agent an edit_file tool:

import Anthropic from '@anthropic-ai/sdk';
import { MorphClient } from '@morphllm/morphsdk';

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

const response = await anthropic.messages.create({
  model: "claude-sonnet-4-5-20250929",
  max_tokens: 12000,
  tools: [morph.anthropic.createEditFileTool()],
  messages: [{ role: "user", content: "Add error handling to src/auth.ts" }]
});
import OpenAI from 'openai';
import { MorphClient } from '@morphllm/morphsdk';

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

const response = await openai.chat.completions.create({
  model: "gpt-5-high",
  tools: [morph.openai.createEditFileTool()],
  messages: [{ role: "user", content: "Add error handling to src/auth.ts" }]
});
import { generateText, stepCountIs } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { MorphClient } from '@morphllm/morphsdk';

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

const result = await generateText({
  model: anthropic('claude-sonnet-4-5-20250929'),
  tools: { editFile: morph.vercel.createEditFileTool() },
  prompt: "Add error handling to src/auth.ts",
  stopWhen: stepCountIs(5)
});

For tool definition schemas, system prompt instructions, and output-parsing mode, see the Fast Apply product page.


WarpGrep

Code search subagent. Searches your codebase in its own context window, finds relevant code in 3.8 steps, returns file/line-range spans. Your agent’s context stays clean.

Install

npm install @morphllm/morphsdk
brew install ripgrep  # also: apt-get install ripgrep, choco install ripgrep

Run it

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

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

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

if (result.success) {
  for (const ctx of result.contexts) {
    console.log(`${ctx.file}: ${ctx.content}`);
  }
}

Add to your agent

const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });
const warpGrepTool = morph.anthropic.createWarpGrepTool({ repoRoot: '.' });

const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-5-20250929',
  max_tokens: 12000,
  tools: [warpGrepTool],
  messages: [{ role: 'user', content: 'Find authentication middleware' }]
});
const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });
const warpGrepTool = morph.openai.createWarpGrepTool({ repoRoot: '.' });

const response = await openai.chat.completions.create({
  model: 'gpt-5-high',
  tools: [warpGrepTool],
  messages: [{ role: 'user', content: 'Find authentication middleware' }]
});
const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });

const result = await generateText({
  model: anthropic('claude-sonnet-4-5-20250929'),
  tools: { codebaseSearch: morph.vercel.createWarpGrepTool({ repoRoot: '.' }) },
  prompt: 'Find authentication middleware',
  stopWhen: stepCountIs(5)
});

For streaming, GitHub search, sandbox execution, and the raw API protocol, see the WarpGrep product page.

Next Steps

Fast Apply

Tool schemas, system prompts, and the lazy edit format

WarpGrep

Streaming, GitHub search, remote execution

MCP Integration

One command to add Morph to Claude Code, Cursor, or Codex

SDK Reference

Complete API documentation