Skip to main content
AI agents edit files using // ... existing code ... markers instead of sending full files. Morph merges server-side at 10,500 tokens/s. Why this matters: Traditional search-replace uses 40% more tokens and takes more turns. Fast Apply is instant.

Installation

npm install @morphllm/morphsdk

Quick Start

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

const morph = new MorphClient({ apiKey: "YOUR_API_KEY" });
const anthropic = new Anthropic();

// Tool inherits API key from MorphClient
const tool = morph.anthropic.createEditFileTool();

const response = await anthropic.messages.create({
  model: "claude-sonnet-4-5-20250929",
  max_tokens: 12000,
  tools: [tool],
  messages: [{ 
    role: "user", 
    content: "Add error handling to src/auth.ts" 
  }]
});
The instructions parameter provides crucial context for ambiguous edits, helping the apply model make correct decisions and achieve near perfect accuracy. Have the parent model generate the instructions.

How It Works

1

Add an edit_file tool to your agent

Add the edit_file tool to your agent. Use one of the formats below.
When editing files, use the edit_file tool with these parameters:
- target_filepath: Path of the file to modify
- instructions: Brief first-person description of what you're changing
- code_edit: Only the changed lines with // ... existing code ... markers

Use "// ... existing code ..." to represent unchanged code blocks. Include
just enough surrounding context to locate each edit precisely.

Example format:
// ... existing code ...
FIRST_EDIT
// ... existing code ...
SECOND_EDIT
// ... existing code ...

Rules:
- ALWAYS use "// ... existing code ..." for unchanged sections (omitting
  this marker will cause deletions)
- Include minimal context around edits only when needed for disambiguation
- Preserve exact indentation
- For deletions: show context before and after, omit the deleted lines
- Batch multiple edits to the same file in one call
Parameters:
ParameterTypeRequiredDescription
target_filepathstringyesPath of the file to modify
instructionsstringyesBrief first-person description of what you’re changing (helps disambiguate uncertainty in the edit)
code_editstringyesOnly the changed lines with // ... existing code ... markers for unchanged sections
The instructions param should be generated by the model, not hardcoded. Example: “I am adding error handling to the user auth and removing the old auth functions”
The instructions parameter provides crucial context for ambiguous edits, helping the apply model make correct decisions and achieve near 100% accuracy even in edge cases.
2

Merge with Morph Fast Apply

When the agent calls your tool, send the original file + the edit snippet to Morph’s API. It returns the merged file. Write it to disk.
When editing code, use the edit_file tool. Output only the changed sections and use
`// ... existing code ...` markers to skip over unchanged code. Do not reread a file
before editing. The edit is applied semantically, so you do not need the file's exact
current contents to make a correct edit.
import OpenAI from "openai";

const openai = new OpenAI({
  apiKey: "YOUR_API_KEY",
  baseURL: "https://api.morphllm.com/v1",
});

const originalCode = await fs.readFile(toolCall.target_filepath, "utf-8");

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

const mergedCode = response.choices[0].message.content;
3

Handle the Response

The merged code is in response.choices[0].message.content. Write it to the target file.
const finalCode = response.choices[0].message.content;
await fs.writeFile(toolCall.target_filepath, finalCode);
4

Verifying Edits (Optional but Recommended)

Pass the diff back to the agent so it can verify the changes match its intent. To save tokens, you can limit this to cases where the linter reports errors.
import { createTwoFilesPatch } from 'diff';

const udiff = createTwoFilesPatch(
  toolCall.target_filepath,
  toolCall.target_filepath,
  originalCode,
  mergedCode,
  '',
  ''
);

// Send back to agent for verification
console.log("Changes applied:", udiff);
This catches unexpected changes before they hit disk.

Direct Usage

Use without an agent:
const result = await morph.fastApply.execute({
  target_filepath: 'src/auth.ts',
  instructions: 'I will add null check',
  code_edit: '// ... existing code ...\nif (!user) throw new Error("Not found");\n// ... existing code ...'
});

console.log(result.success); // true
console.log(`+${result.changes.linesAdded} -${result.changes.linesRemoved}`);

Code-in/Code-out (Sandbox Support)

Use applyEdit when you manage your own filesystem or work in sandboxes like E2B, Modal, or Daytona:
import { applyEdit } from '@morphllm/morphsdk';

// Read file yourself (from sandbox, memory, etc.)
const originalCode = await sandbox.readFile('src/auth.ts');

const result = await applyEdit({
  originalCode,
  codeEdit: '// ... existing code ...\nif (!user) throw new Error("Not found");\n// ... existing code ...',
  instructions: 'Add null check',
});

if (result.success) {
  // Write file yourself
  await sandbox.writeFile('src/auth.ts', result.mergedCode);
  console.log(result.udiff);  // View the diff
}
applyEdit returns mergedCode instead of writing to disk—perfect for sandbox environments where you control file I/O.

Configuration

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

const morph = new MorphClient({ apiKey: "YOUR_API_KEY" });

const tool = morph.openai.createEditFileTool({
  baseDir: './src',       // Default: process.cwd()
  autoWrite: true,        // Auto-write files (default: true)
  generateUdiff: true     // Return diff (default: true)
});

API

Input (EditFileInput):
{
  target_filepath: string,  // Relative to baseDir
  instructions: string,     // What the model is changing
  code_edit: string         // Code with // ... existing code ...
}
Returns (EditFileResult):
{
  success: boolean,
  filepath: string,
  changes: { linesAdded, linesRemoved, linesModified },
  udiff?: string,
  error?: string
}
All types are exported from the SDK root:
import type { 
  EditFileInput, 
  EditFileResult, 
  ApplyEditInput, 
  ApplyEditResult,
  EditChanges 
} from '@morphllm/morphsdk';

Edge / Cloudflare Workers

Use @morphllm/morphsdk/edge for edge environments (Cloudflare Workers, Vercel Edge, Deno):
import { applyEdit } from '@morphllm/morphsdk/edge';

export default {
  async fetch(request: Request, env: Env) {
    const { originalCode, codeEdit, instructions } = await request.json();

    const result = await applyEdit({
      originalCode,
      codeEdit,
      instructions,
    }, {
      morphApiKey: env.MORPH_API_KEY
    });

    return Response.json({
      success: result.success,
      mergedCode: result.mergedCode,
      udiff: result.udiff
    });
  }
};
The edge entry point has zero Node.js dependencies. It exports applyEdit, generateUdiff, countChanges, and callMorphAPI.

Error Handling

if (!result.success) {
  console.error(result.error);
  // "File not found" | "Invalid filepath" | "API error"
}