Skip to main content
Copy-paste examples for real-world AI agent use cases. All code is tested and production-ready.

Cursor Clone

Build a code editor with AI assistance that searches and edits autonomously.
import Anthropic from '@anthropic-ai/sdk';
import { MorphClient } from '@morphllm/morphsdk';
import { createEditFileTool } from '@morphllm/morphsdk/tools/fastapply/anthropic';
import { createCodebaseSearchTool } from '@morphllm/morphsdk/tools/codebase-search/anthropic';

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

// Create tools from MorphClient namespaces
const searchTool = createCodebaseSearchTool({ 
  client: morph.codebaseSearch, 
  repoId: 'my-project' 
});
const editTool = createEditFileTool(morph.fastApply);

async function codeWithAI(instruction: string) {
  const messages = [{ role: "user", content: instruction }];
  let maxTurns = 10;
  
  while (maxTurns-- > 0) {
    const response = await anthropic.messages.create({
      model: "claude-sonnet-4-20250514",
      max_tokens: 4096,
      tools: [searchTool, editTool],
      messages
    });
    
    if (response.stop_reason === 'end_turn') break;
    
    // Handle tool calls
    messages.push({ role: 'assistant', content: response.content });
    
    const toolResults = [];
    for (const block of response.content) {
      if (block.type === 'tool_use') {
        const tool = block.name === 'edit_file' ? editTool : searchTool;
        const result = await tool.execute(block.input);
        toolResults.push({
          type: 'tool_result',
          tool_use_id: block.id,
          content: tool.formatResult(result)
        });
      }
    }
    
    messages.push({ role: 'user', content: toolResults });
  }
}

// Usage examples
await codeWithAI("Add logging to all database queries");
await codeWithAI("Refactor auth code to use middleware");
await codeWithAI("Add TypeScript types to all API routes");
What it does: Agent searches codebase → makes edits → verifies → repeats until done. No manual intervention needed.

PR Review Bot

Automated code review with full codebase context. Catches security issues, performance problems, and suggests improvements.
import Anthropic from '@anthropic-ai/sdk';
import { createCodebaseSearchTool } from '@morphllm/morphsdk/tools/codebase-search/anthropic';

async function reviewPR(repoId: string, prDiff: string, changedFiles: string[]) {
  const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
  
  const response = await client.messages.create({
    model: "claude-sonnet-4-5-20250514",
    tools: [createCodebaseSearchTool({ repoId })],
    messages: [{
      role: "user", 
      content: `Review this pull request:

Files: ${changedFiles.join(', ')}

${prDiff}

Provide:
1. Security issues
2. Performance concerns  
3. Code quality feedback
4. Suggestions

Search the codebase for context if needed.`
    }]
  });
  
  return response.content;
}

// GitHub Actions workflow
const diff = process.env.PR_DIFF;
const files = process.env.PR_FILES?.split(',') || [];
const review = await reviewPR('my-repo', diff, files);

// Post as PR comment
await octokit.issues.createComment({
  owner: 'your-org',
  repo: 'your-repo',
  issue_number: prNumber,
  body: review
});
name: AI Code Review
on: pull_request

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
      - run: npm install @morphllm/morphsdk @anthropic-ai/sdk
      - run: node review.js
        env:
          MORPH_API_KEY: ${{ secrets.MORPH_API_KEY }}
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

Self-Healing Agent

Autonomous bug fixing: agent finds the issue, patches code, and verifies the fix with browser tests.
import Anthropic from '@anthropic-ai/sdk';
import { MorphClient } from '@morphllm/morphsdk';
import { createEditFileTool } from '@morphllm/morphsdk/tools/fastapply/anthropic';
import { createCodebaseSearchTool } from '@morphllm/morphsdk/tools/codebase-search/anthropic';
import { createBrowserTool } from '@morphllm/morphsdk/tools/browser/anthropic';

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

async function selfHeal(bugReport: string, testUrl: string) {
  const response = await anthropic.messages.create({
    model: "claude-sonnet-4-20250514",
    tools: [
      createCodebaseSearchTool({ client: morph.codebaseSearch, repoId: 'my-app' }),
      createEditFileTool(morph.fastApply),
      createBrowserTool(morph.browser)
    ],
    messages: [{
      role: "user",
      content: `Bug: ${bugReport}

1. Search for relevant code
2. Identify the issue  
3. Apply a fix
4. Test at ${testUrl}
5. Report results`
    }]
  });
  
  // Agent autonomously: searches → fixes → tests → reports
  return response;
}

// Examples
await selfHeal('Checkout button not responding', 'https://staging.myapp.com');
await selfHeal('Login fails with Google OAuth', 'https://3000-xyz.e2b.dev');
await selfHeal('Search results not displaying', 'https://preview.vercel.app');
How it works: Agent searches codebase for bug location → makes the fix → tests in browser → reports success/failure with video proof.

CI/CD E2E Testing

Natural language E2E tests that run on every PR. Get video recordings of failures automatically.
import { MorphClient } from '@morphllm/morphsdk';

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

async function runE2ETests(previewUrl: string, commitSha: string) {
  const tests = [
    "Test user can sign up with email and password",
    "Test user can login with valid credentials",
    "Test checkout flow with test credit card",
    "Test settings page loads and can update profile"
  ];
  
  const results = await Promise.all(
    tests.map(task => 
      morph.browser.execute({ 
        task, 
        url: previewUrl,
        max_steps: 15,
        record_video: true
      })
    )
  );
  
  const failed = results.filter(r => !r.success);
  
  if (failed.length > 0) {
    // Get recordings and embed videos in PR
    const failureReports = await Promise.all(
      failed.map(async (r, i) => {
        if (r.recording_id) {
          const rec = await morph.browser.getRecording(r.recording_id);
          return {
            test: tests[i],
            videoUrl: rec.video_url,
            error: r.error
          };
        }
        return { test: tests[i], error: r.error };
      })
    );
    
    // Post to GitHub PR with embedded videos
    const { Octokit } = require('@octokit/rest');
    const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
    
    const prBody = `## ❌ ${failed.length} Test${failed.length > 1 ? 's' : ''} Failed

${failureReports.map(f => `
### ${f.test}
${f.error ? `**Error:** ${f.error}` : ''}

${f.videoUrl ? `
<video src="${f.videoUrl}" controls width="100%">
  <a href="${f.videoUrl}">Watch video</a>
</video>` : ''}
`).join('\n---\n')}`;

    await octokit.issues.createComment({
      owner: process.env.GITHUB_REPOSITORY_OWNER,
      repo: process.env.GITHUB_REPOSITORY?.split('/')[1],
      issue_number: parseInt(process.env.PR_NUMBER),
      body: prBody
    });
      
    throw new Error(`${failed.length} tests failed - see PR comment for videos`);
  }
  
  console.log('✅ All tests passed!');
  return results;
}

// Vercel preview integration
await runE2ETests(
  process.env.VERCEL_URL,
  process.env.VERCEL_GIT_COMMIT_SHA
);
Cost: ~$0.10 per test suite run. Videos auto-delete after 7 days. Contact support for higher concurrency limits.
When tests fail, the video is embedded directly in the PR comment:
## ❌ 1 Test Failed

### Test checkout flow with test credit card
**Error:** Checkout button not found after 15 steps

<video src="https://morph-recordings.s3.amazonaws.com/..." controls width="100%">
  <a href="https://morph-recordings.s3.amazonaws.com/...">Watch video</a>
</video>
GitHub renders this as a playable video directly in the PR. No need to click links.

Test Debugging

When tests fail, get instant video replay with console errors and network logs.
import { MorphClient } from '@morphllm/morphsdk';

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

async function debugTest() {
  const result = await morph.browser.execute({
    task: "Complete checkout flow with test card",
    url: "https://staging.myapp.com",
    record_video: true,
    max_steps: 30
  });

  if (!result.success) {
    console.error('❌ Test failed:', result.error);
    
    if (result.recording_id) {
      const recording = await morph.browser.getRecording(result.recording_id);
      const errors = await morph.browser.getErrors(result.recording_id);
      
      console.log('Debug info:');
      console.log('  Video:', recording.video_url);
      console.log('  Console logs:', recording.console_url);
      console.log('  Network:', recording.network_url);
      console.log(`  ${errors.total_errors} errors found`);
      
      // Post to GitHub issue with embedded video
      const { Octokit } = require('@octokit/rest');
      const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
      
      await octokit.issues.createComment({
        owner: 'your-org',
        repo: 'your-repo',
        issue_number: process.env.ISSUE_NUMBER,
        body: `## Test Failed: Checkout Flow

**Error:** ${result.error}

### Video Replay
<video src="${recording.video_url}" controls width="100%">
  <a href="${recording.video_url}">Watch video</a>
</video>

### Console Errors
${errors.total_errors > 0 ? errors.errors.slice(0, 3).map(e => 
  `- **${e.type}:** ${e.message}`
).join('\n') : 'No console errors'}

[Full console logs](${recording.console_url}) | [Network logs](${recording.network_url})`
      });
    }
  }
}
Video embeds in GitHub: GitHub renders <video> tags natively, so your team sees failures instantly in issues/PRs.

Agentic GitHub App

Autonomous GitHub bot that resolves issues, creates PRs, and explains changes.
import { Octokit } from '@octokit/rest';
import { MorphClient } from '@morphllm/morphsdk';
import Anthropic from '@anthropic-ai/sdk';
import { createEditFileTool } from '@morphllm/morphsdk/tools/fastapply/anthropic';
import { createCodebaseSearchTool } from '@morphllm/morphsdk/tools/codebase-search/anthropic';

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

async function handleIssue(issue: { number: number; title: string; body: string }) {
  const branchName = `fix-${issue.number}`;
  
  // Clone and create branch
  await morph.git.clone({ 
    url: 'https://github.com/your-org/your-repo',
    dir: './temp' 
  });
  await morph.git.checkout({ 
    dir: './temp', 
    branch: branchName,
    create: true 
  });
  
  // Agent autonomously fixes the issue
  let messages = [{
    role: "user" as const,
    content: `Fix issue #${issue.number}: ${issue.title}\n\n${issue.body}\n\nSearch codebase, apply fix, explain changes.`
  }];
  
  for (let i = 0; i < 10; i++) {
    const response = await anthropic.messages.create({
      model: "claude-sonnet-4-20250514",
      max_tokens: 4096,
      tools: [
        createCodebaseSearchTool({ client: morph.codebaseSearch, repoId: 'main-repo' }),
        createEditFileTool(morph.fastApply)
      ],
      messages
    });
    
    if (response.stop_reason === 'end_turn') {
      // Extract explanation for PR body
      const explanation = response.content.find(c => c.type === 'text')?.text || '';
      break;
    }
    
    // Handle tool calls and continue...
  }
  
  // Commit and push
  await morph.git.add({ dir: './temp', files: ['.'] });
  await morph.git.commit({ 
    dir: './temp', 
    message: `Fix #${issue.number}: ${issue.title}` 
  });
  await morph.git.push({ 
    dir: './temp',
    remote: 'origin',
    branch: branchName
  });
  
  // Create PR
  const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
  const pr = await octokit.pulls.create({
    owner: 'your-org',
    repo: 'your-repo',
    title: `Fix: ${issue.title}`,
    head: branchName,
    base: 'main',
    body: `Fixes #${issue.number}\n\n## Changes\n\n${explanation}`
  });
  
  console.log(`Created PR #${pr.data.number}`);
}
  1. Create GitHub App with repo access
  2. Deploy this code to Vercel/Railway/Fly
  3. Set webhook URL to your deployment
  4. Add MORPH_API_KEY, ANTHROPIC_API_KEY, GITHUB_TOKEN to env
  5. Bot automatically handles new issues
What to add:
  • Human approval workflow before merging
  • Tests run on PR before merge
  • Fallback to request help if agent is stuck

Code Migration

Migrate entire codebases between frameworks with consistent patterns.
import { MorphClient } from '@morphllm/morphsdk';
import Anthropic from '@anthropic-ai/sdk';
import { createEditFileTool } from '@morphllm/morphsdk/tools/fastapply/anthropic';
import { createCodebaseSearchTool } from '@morphllm/morphsdk/tools/codebase-search/anthropic';
import { glob } from 'glob';

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

async function migrateFramework(from: string, to: string) {
  const files = await glob('src/**/*.{js,jsx,ts,tsx}');
  console.log(`Found ${files.length} files to migrate`);
  
  const searchTool = createCodebaseSearchTool({ 
    client: morph.codebaseSearch, 
    repoId: 'my-app' 
  });
  const editTool = createEditFileTool(morph.fastApply);
  
  let migrated = 0;
  for (const file of files) {
    try {
      const response = await anthropic.messages.create({
        model: "claude-sonnet-4-20250514",
        max_tokens: 4096,
        tools: [searchTool, editTool],
        messages: [{
          role: "user",
          content: `Migrate ${file} from ${from} to ${to}.
          
Search for migration patterns in other files to stay consistent.`
        }]
      });
      
      // Handle tool calls in loop until complete
      // ... (tool handling logic)
      
      migrated++;
      console.log(`✅ ${migrated}/${files.length} - ${file}`);
    } catch (error) {
      console.error(`❌ Failed: ${file}`, error);
    }
  }
  
  console.log(`\n✅ Migrated ${migrated}/${files.length} files`);
}

// Migrate React to Solid.js
await migrateFramework('React', 'Solid.js');
Use cases: React → Vue, JavaScript → TypeScript, Class components → Hooks, REST → GraphQL

More Examples

Documentation Bot

Auto-generate docs from code

Security Auditor

Scan for vulnerabilities

Refactoring Agent

Large-scale code cleanup

Test Generator

Generate unit & E2E tests

Need Help?