# Morph SDK

Production-ready tools for AI coding agents: WarpGrep (intelligent code search), Fast Apply (10,500 tokens/s), GitHub integration, and Browser automation.

[![npm version](https://img.shields.io/npm/v/@morphllm/morphsdk.svg)](https://www.npmjs.com/package/@morphllm/morphsdk)

## Install

```bash
npm install @morphllm/morphsdk
```

Get your API key: [morphllm.com/dashboard/api-keys](https://morphllm.com/dashboard/api-keys)

```bash
export MORPH_API_KEY="sk-your-key-here"
```

## Features

- **🔍 WarpGrep** - Intelligent code search agent that explores your codebase with parallel grep/read operations
- **⚡ Fast Apply** - 98% 1st pass accuracy, AI-powered code editing at 10,500 tokens/s
- **🐙 GitHub** - Access PR context, post comments, manage check runs through your connected GitHub account
- **🌐 Browser** - AI-powered browser automation for testing and interaction
- **📦 Repo Storage** - Agent native git with automatic code indexing and agent metadata
- **🤖 Agent Tools** - Ready-to-use tools for Anthropic, OpenAI, Gemini, and Vercel AI SDK

## Quick Start

### WarpGrep - Intelligent Code Search

WarpGrep is a search subagent that explores your codebase using parallel grep and file read operations. It understands natural language queries and returns relevant code with line numbers.

```typescript
import { WarpGrepClient } from '@morphllm/morphsdk/tools/warp-grep';

const client = new WarpGrepClient({ morphApiKey: process.env.MORPH_API_KEY });

const result = await client.execute({
  query: 'Find where authentication requests are handled',
  repoRoot: './my-project'
});

// Returns relevant files with specific line ranges
result.files.forEach(file => {
  console.log(`${file.path}: lines ${file.lines}`);
});
```

### As Agent Tool

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

const client = new Anthropic();
const tool = createWarpGrepTool({ repoRoot: './my-project' });

const response = await client.messages.create({
  model: "claude-sonnet-4-5-20250929",
  tools: [tool],
  messages: [{ role: "user", content: "Find the error handling logic" }]
});
```

### Remote Sandbox Support

WarpGrep works in remote sandboxes (E2B, Modal, Daytona) by providing custom command implementations:

```typescript
import { createWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/anthropic';

const tool = createWarpGrepTool({
  repoRoot: '/home/repo',
  remoteCommands: {
    grep: async (pattern, path) => (await sandbox.run(`rg '${pattern}' '${path}'`)).stdout,
    read: async (path, start, end) => (await sandbox.run(`sed -n '${start},${end}p' '${path}'`)).stdout,
    listDir: async (path, maxDepth) => (await sandbox.run(`find '${path}' -maxdepth ${maxDepth}`)).stdout,
  },
});
```

## GitHub Integration

Access your GitHub repositories, pull requests, and deployments through your connected Morph account.

### Setup

Connect your GitHub account in the [Morph Dashboard](https://morphllm.com/dashboard/integrations/github), then use the SDK:

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

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

// List your GitHub installations
const installations = await morph.github.installations.list();
console.log(installations);
// [{ id: "12345", accountLogin: "acme", accountType: "Organization" }]
```

### List Repositories

```typescript
// List repos for an installation
const repos = await morph.github.repos.list({
  installationId: "12345"
});
// [{ id: 123, name: "app", fullName: "acme/app", private: true }]
```

### Get Pull Request Context

```typescript
// Get PR with full context (title, body, diff, files)
const pr = await morph.github.pullRequests.get({
  owner: "acme",
  repo: "app",
  number: 42
});

console.log(pr.title);    // "Add user authentication"
console.log(pr.diff);     // Full unified diff
console.log(pr.files);    // [{ filename, status, additions, deletions, patch }]
```

### Find Preview Deployments

```typescript
// Get deployments for a PR's head SHA
const deployments = await morph.github.deployments.list({
  owner: "acme",
  repo: "app",
  sha: pr.headSha
});

const preview = deployments.find(d => d.environment === "preview");
console.log(preview?.url); // "https://app-pr-42.vercel.app"
```

### Post PR Comments

```typescript
// Post a comment to a PR
const comment = await morph.github.comments.create({
  owner: "acme",
  repo: "app",
  pr: 42,
  body: "## Test Results\n\n✅ All tests passed!"
});

// Update the comment
await morph.github.comments.update({
  owner: "acme",
  repo: "app",
  commentId: comment.id,
  body: "## Test Results\n\n✅ All tests passed!\n\nUpdated at: " + new Date()
});
```

### Manage Check Runs (CI Status)

```typescript
// Create a check run
const checkRun = await morph.github.checkRuns.create({
  owner: "acme",
  repo: "app",
  sha: pr.headSha,
  name: "Preview Test",
  status: "in_progress",
  title: "Testing preview deployment...",
  summary: "Running automated browser tests"
});

// Update with results
await morph.github.checkRuns.update({
  owner: "acme",
  repo: "app",
  checkRunId: checkRun.id,
  conclusion: "success",
  title: "✅ Preview test passed",
  summary: "All tests completed successfully"
});
```

### Full Example: PR Preview Testing

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

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

async function testPRPreview(owner: string, repo: string, prNumber: number) {
  // 1. Get PR context
  const pr = await morph.github.pullRequests.get({ owner, repo, number: prNumber });

  // 2. Find preview deployment
  const deployments = await morph.github.deployments.list({ owner, repo, sha: pr.headSha });
  const preview = deployments.find(d => d.state === "success" && d.url);

  if (!preview) {
    console.log("No preview deployment found");
    return;
  }

  // 3. Run browser test with PR context
  const task = await morph.browser.createTask({
    url: preview.url,
    diff: pr.diff,
    task: "Test the changes in this PR"
  });

  // 4. Wait for results
  const recording = await morph.browser.waitForRecording(task.recordingId);

  // 5. Post results to PR
  await morph.github.comments.create({
    owner, repo, pr: prNumber,
    body: `## 🤖 Preview Test Results\n\n${recording.result || "Test completed"}`
  });
}
```

## Fast Apply

AI-powered code editing at 10,500 tokens/s with 98% first-pass accuracy.

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

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

await morph.fastApply.execute({
  target_filepath: 'src/app.ts',
  instructions: 'Add error handling to the API call',
  code_edit: `
    // ... existing code ...
    try {
      const response = await fetch(url);
      // ... existing code ...
    } catch (e) {
      console.error('API call failed:', e);
      throw e;
    }
  `
});
```

See [tools/fastapply/README.md](./tools/fastapply/README.md) for details.

## Repo Storage

Git built for AI agents with automatic code indexing.

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

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

// Initialize repo
await morph.git.init({ repoId: 'my-project', dir: './my-project' });

// Stage and commit with agent metadata
await morph.git.add({ dir: './my-project', filepath: '.' });
await morph.git.commit({
  dir: './my-project',
  message: 'Add authentication',
  chatHistory: [
    { role: 'user', content: 'Add OAuth login' },
    { role: 'assistant', content: 'Adding Google OAuth...' }
  ]
});

// Push
await morph.git.push({ dir: './my-project' });

// Clone, branch, checkout
await morph.git.clone({ repoId: 'my-project', dir: './local-copy' });
await morph.git.branch({ dir: './my-project', name: 'feature' });
await morph.git.checkout({ dir: './my-project', ref: 'main' });
```

## Agent Tools

Ready-to-use tools for popular AI frameworks:

| Framework | Import Path |
|-----------|-------------|
| Anthropic SDK | `@morphllm/morphsdk/tools/warp-grep/anthropic` |
| OpenAI SDK | `@morphllm/morphsdk/tools/warp-grep/openai` |
| Gemini SDK | `@morphllm/morphsdk/tools/warp-grep/gemini` |
| Vercel AI SDK | `@morphllm/morphsdk/tools/warp-grep/vercel` |

Available tools:
- `createWarpGrepTool` - Intelligent code search
- `createFastApplyTool` - AI-powered code editing
- `createBrowserTool` - Browser automation

## Documentation

Full docs: [docs.morphllm.com](https://docs.morphllm.com)

**Key Pages:**
- [WarpGrep](https://docs.morphllm.com/sdk/components/warp-grep) - Intelligent code search
- [Fast Apply](https://docs.morphllm.com/sdk/components/fast-apply) - AI-powered code editing
- [GitHub](https://docs.morphllm.com/sdk/components/github) - GitHub integration for PR context and automation
- [Browser](https://docs.morphllm.com/sdk/components/browser) - AI-powered browser automation
- [Repo Storage](https://docs.morphllm.com/sdk/components/git) - Git operations and agent metadata
