# Create Git repository Source: https://docs.morphllm.com/api-reference/create-git-repository api-reference/openapi-git.json post /v1/repos Creates a new Git repository in Azure DevOps and the Morph database. Supports organization-scoped repositories. Most developers use `morphGit.init()` from the SDK instead of calling this directly. ## Overview This endpoint creates a new Git repository with: - Repository entry in Azure DevOps - Database record with user/org association - Remote URL configuration for git operations ## Typical Usage Most developers use the Morph SDK instead: ```typescript import { MorphGit } from 'morphsdk/git'; const morphGit = new MorphGit({ apiKey: process.env.MORPH_API_KEY }); await morphGit.init({ repoId: 'my-project', dir: './my-project' }); ``` ## Organization Support Repositories can be scoped to organizations. The `org_id` is automatically determined from your API key's association. # Apply API Source: https://docs.morphllm.com/api-reference/endpoint/apply POST /v1/chat/completions Apply changes from big models into your files. Find your [API key](https://morphllm.com/dashboard). ## Overview The Apply API enables lightning-fast code editing at **10,500+ tokens/second** with **98% accuracy**. This OpenAI-compatible endpoint intelligently merges code changes while preserving structure and formatting. ## Models Choose the model that best fits your use case: Model Speed Accuracy Best For morph-v3-fast 10,500+ tok/sec 96% Real-time applications, quick edits morph-v3-large 5000+ tok/sec 98% Complex changes, highest accuracy auto 5000-10,500tok/sec \~98% Recommended - automatically selects optimal model
## Message Format The Apply API uses a structured XML format within the message content: ``` Brief description of what you're changing Original code content Code snippet showing only the changes with // ... existing code ... markers ``` ### Format Guidelines * **``**: Optional but recommended. Use first-person, clear descriptions * **``**: The complete original code that needs modification * **``**: Show only what changes, using `// ... existing code ...` for unchanged sections ## Usage Examples ```typescript TypeScript highlight={13} theme={null} import OpenAI from "openai"; const openai = new OpenAI({ apiKey: process.env.MORPH_API_KEY, baseURL: "https://api.morphllm.com/v1", }); const instruction = "I will add error handling to prevent division by zero"; const originalCode = "function divide(a, b) {\n return a / b;\n}"; const codeEdit = "function divide(a, b) {\n if (b === 0) {\n throw new Error('Cannot divide by zero');\n }\n return a / b;\n}"; const response = await openai.chat.completions.create({ model: "morph-v3-fast", messages: [ { role: "user", content: `${instruction}\n${originalCode}\n${codeEdit}`, }, ], }); const mergedCode = response.choices[0].message.content; ``` ```python Python highlight={14} theme={null} import os from openai import OpenAI client = OpenAI( api_key=os.getenv("MORPH_API_KEY"), base_url="https://api.morphllm.com/v1" ) instruction = "I will add error handling to prevent division by zero" original_code = "function divide(a, b) {\n return a / b;\n}" code_edit = "function divide(a, b) {\n if (b === 0) {\n throw new Error('Cannot divide by zero');\n }\n return a / b;\n}" response = client.chat.completions.create( model="morph-v3-fast", messages=[ { "role": "user", "content": f"{instruction}\n{original_code}\n{code_edit}" } ] ) merged_code = response.choices[0].message.content ``` ```bash cURL highlight={9} theme={null} 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": "I will add error handling to prevent division by zero\nfunction divide(a, b) {\n return a / b;\n}\nfunction divide(a, b) {\n if (b === 0) {\n throw new Error(\"Cannot divide by zero\");\n }\n return a / b;\n}" } ] }' ``` ## Error Codes HTTP Status Description 200 Success - chat completion response 400 Bad request - malformed request or parameters 401 Authentication error - invalid API key
Build AI agent tools with Morph Apply See more implementation patterns # Embedding API Source: https://docs.morphllm.com/api-reference/endpoint/embedding POST /v1/embeddings Generate embeddings for code ## Overview Morph provides an OpenAI-compatible API for generating embeddings from code and text. State of the art on code retrieval tasks with our latest `morph-embedding-v3` model. ## Example Request ```typescript embedding.ts theme={null} import { OpenAI } from 'openai'; const client = new OpenAI({ apiKey: 'your-morph-api-key', baseURL: 'https://api.morphllm.com/v1' }); async function generateEmbeddings() { const response = await client.embeddings.create({ model: "morph-embedding-v3", input: "function calculateSum(a, b) { return a + b; }" }); return response.data[0].embedding; } ``` ```python embedding.py theme={null} import openai client = openai.OpenAI( api_key="your-morph-api-key", base_url="https://api.morphllm.com/v1" ) def generate_embeddings(): response = client.embeddings.create( model="morph-embedding-v3", input="function calculateSum(a, b) { return a + b; }" ) return response.data[0].embedding ``` ## Model Selection We recommend using `morph-embedding-v3` for the best performance on code retrieval tasks. This model offers: * **State-of-the-Art Performance**: Achieves SoTA results across all coding benchmarks for accuracy:speed ratio * **1024 Dimensions**: Optimal dimensionality for rich semantic representation while maintaining efficiency * **Unmatched Speed**: Fastest inference in the market - no embedding model comes close on accuracy:speed * **Enhanced Context**: Superior handling of longer code snippets and complex codebases For backward compatibility, `morph-embedding-v3` remains available. ## Input Format The request accepts the following parameters: | Parameter | Type | Required | Description | | ----------------- | --------------- | -------- | -------------------------------------------------------------------------------------------------------- | | `model` | string | Yes | The model ID to use for embedding generation. Use `morph-embedding-v3` (latest) or `morph-embedding-v3`. | | `input` | string or array | Yes | The text to generate embeddings for. Can be a string or an array of strings. | | `encoding_format` | string | No | The format in which the embeddings are returned. Options are `float` and `base64`. Default is `float`. | ## Batch Processing Example ```python theme={null} from openai import OpenAI client = OpenAI( api_key="your-morph-api-key", base_url="https://api.morphllm.com/v1" ) # Example with batch inputs code_snippets = [ "function add(a, b) { return a + b; }", "class User { constructor(name) { this.name = name; } }", "import pandas as pd\ndf = pd.read_csv('data.csv')" ] response = client.embeddings.create( model="morph-embedding-v3", input=code_snippets ) # Access embeddings for each input for i, embedding_data in enumerate(response.data): embedding = embedding_data.embedding print(f"Embedding for snippet {i+1}: {len(embedding)} dimensions") ``` ## Response Format ```json theme={null} { "object": "list", "data": [ { "object": "embedding", "embedding": [0.0023064255, -0.009327292, ...], "index": 0 } ], "model": "morph-embedding-v3", "usage": { "prompt_tokens": 8, "total_tokens": 8 } } ``` When multiple inputs are provided, the response includes embeddings for each input: ```json theme={null} { "object": "list", "data": [ { "object": "embedding", "embedding": [0.0023064255, -0.009327292, ...], "index": 0 }, { "object": "embedding", "embedding": [0.0103662554, -0.007650322, ...], "index": 1 }, { "object": "embedding", "embedding": [0.0183664255, -0.002327742, ...], "index": 2 } ], "model": "morph-embedding-v3", "usage": { "prompt_tokens": 24, "total_tokens": 24 } } ``` ## Usage with Vector Databases Embeddings can be stored in vector databases for efficient similarity searching: ```python theme={null} # Example with Pinecone import pinecone from openai import OpenAI # Initialize clients openai_client = OpenAI( api_key="your-morph-api-key", base_url="https://api.morphllm.com/v1" ) pinecone.init(api_key="your-pinecone-api-key", environment="your-environment") index = pinecone.Index("code-embeddings") # Generate embedding for a code snippet code_snippet = "def calculate_factorial(n):\n if n == 0:\n return 1\n else:\n return n * calculate_factorial(n-1)" response = openai_client.embeddings.create( model="morph-embedding-v3", input=code_snippet ) embedding = response.data[0].embedding # Store in Pinecone index.upsert([ ("snippet-1", embedding, {"snippet": code_snippet}) ]) # Search for similar code results = index.query( vector=embedding, top_k=5, include_metadata=True ) ``` # MCP Integration Source: https://docs.morphllm.com/api-reference/endpoint/mcp Connect to Morph's blazing-fast file editing via Model Context Protocol ## Overview Connect to Morph's 10,500+ tok/s file editing via Model Context Protocol. Works with Claude, Cursor, VS Code, and other MCP clients. **Two modes:** * **Default** (recommended): `edit_file` via `ENABLED_TOOLS="edit_file"` * **Full filesystem**: All 16 tools (including the above) via `ENABLED_TOOLS="all"` ## Installation Add to your Cursor MCP by clicking this button: Install MCP Server OR add to your Cursor MCP config file: **Location**: `~/.cursor/mcp.json` ```json theme={null} { "mcpServers": { "morph-mcp": { "env": { "MORPH_API_KEY": "your-api-key-here" }, "command": "npx -y @morphllm/morphmcp", "args": [] } } } ``` **Global Config**: This configuration works across all your projects automatically. The MCP server detects workspace boundaries via `.git`, `package.json`, and other project indicators. **One-liner Installation (Recommended)**: ```bash theme={null} claude mcp add filesystem-with-morph -e MORPH_API_KEY=your-api-key-here -- npx -y @morphllm/morphmcp ``` **Configure Claude to prefer Morph**: Add this to your Claude instructions to ensure Claude uses Morph for all code edits: ```bash theme={null} echo "IMPORTANT: ALWAYS use mcp__filesystem-with-morph__edit_file tool to make any code edits. Do not use the default edit tool." > .claude/CLAUDE.md ``` **Manual Config File Method**: Create or edit `.claude.json` in your workspace: ```json theme={null} { "mcpServers": { "filesystem-with-morph": { "env": { "MORPH_API_KEY": "your-api-key-here" }, "command": "npx -y @morphllm/morphmcp", "args": [] } } } ``` **CLI Installation (Recommended)**: ```bash theme={null} # Add Morph MCP server to Codex codex mcp add filesystem-with-morph -e MORPH_API_KEY=your-api-key-here -- npx -y @morphllm/morphmcp ``` **Manual Config File**: Add to `~/.codex/config.toml`: ```toml theme={null} [mcp_servers.filesystem-with-morph] env = { "MORPH_API_KEY" = "your-api-key-here" } command = "npx -y @morphllm/morphmcp" args = [] # Optional: adjust timeouts startup_timeout_sec = 10 tool_timeout_sec = 60 ``` **CLI Management**: Use `codex mcp list` to see configured servers and `codex mcp remove filesystem-with-morph` to remove. Add to your Claude Desktop config file: **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`\ **Windows**: `%APPDATA%/Claude/claude_desktop_config.json` ```json theme={null} { "mcpServers": { "filesystem-with-morph": { "env": { "MORPH_API_KEY": "your-api-key-here" }, "command": "npx -y @morphllm/morphmcp", "args": [] } } } ``` **Restart Required**: Completely quit and restart Claude Desktop to load the new configuration. Add to your workspace's `.vscode/mcp.json` file: ```json theme={null} { "mcpServers": { "filesystem-with-morph": { "env": { "MORPH_API_KEY": "your-api-key-here" }, "command": "npx -y @morphllm/morphmcp", "args": [] } } } ``` Run the MCP server directly: ```bash theme={null} export MORPH_API_KEY="your-api-key-here" export ENABLED_TOOLS="edit_file" # or "all" for full filesystem access npx -y @morphllm/morphmcp ``` Get your API key from the [dashboard](https://morphllm.com/dashboard/api-keys) and replace `your-api-key-here` in your configuration. **Claude**: Type `/mcp` and `/tools` to see Morph's `edit_file` tool\ **Cursor/VS Code**: Make any code edit request - should use Morph automatically\ **Codex**: Run `codex mcp list` to verify server is configured, then make edit requests\ **Manual**: Check server logs show "MCP Server started successfully" ## Configuration | Variable | Default | Description | | ---------------- | ------------- | -------------------------------------------------------------------- | | `MORPH_API_KEY` | Required | Your API key | | `ENABLED_TOOLS` | `"edit_file"` | Comma-separated list of tools, or `"all"` for full filesystem access | | `WORKSPACE_MODE` | `"true"` | Auto workspace detection | | `DEBUG` | `"false"` | Debug logging | ## Available Tools ### Morph-Powered Tools (Default) **`edit_file`** - 10,500+ tokens/sec code editing via Morph Apply ### Additional Tools (when ENABLED\_TOOLS: "all") You get 15 additional filesystem tools: `read_file`, `read_multiple_files`, `write_file`, `tiny_edit_file`, `list_directory`, `list_directory_with_sizes`, `directory_tree`, `create_directory`, `search_files`, `move_file`, `get_file_info`, `list_allowed_directories` ## Troubleshooting **Server won't start**: Check API key, Node.js 16+, run `npm cache clean --force`\ **Tools missing**: Restart client, validate JSON config\ **Workspace issues**: Add `.git` or `package.json`, or set `WORKSPACE_MODE="false"`\ **Slow performance**: Use `edit_file` over `write_file`, check network to api.morphllm.com ## Performance Optimization ### Best Practices 1. **Use `edit_file` for modifications**: Much faster than reading + writing entire files 2. **Minimize edit scope**: Include only the sections that need changes 3. **Batch related edits**: Make multiple changes in a single `edit_file` call 4. **Enable edit-only mode**: Use `ALL_TOOLS: "false"` when you only need editing capabilities ### Performance Comparison | Method | Speed | Use Case | | ---------------------- | ------------ | --------------------------- | | `edit_file` (Morph) | \~11 seconds | Code modifications, updates | | Search & replace | \~20 seconds | Simple text substitutions | | Traditional read/write | \~60 seconds | Full file rewrites | # Rerank API Source: https://docs.morphllm.com/api-reference/endpoint/rerank POST /v1/rerank Rerank search results by relevance ## Overview Morph's Rerank API improves search quality by reordering candidate results based on their relevance to a query. Our latest `morph-rerank-v3` model achieves state-of-the-art performance across all coding benchmarks for accuracy:speed ratio - no rerank model comes close. Unlike the Apply and Embedding endpoints, the Rerank API uses a custom endpoint specifically designed for reranking tasks. ## API Endpoint ``` POST https://api.morphllm.com/v1/rerank ``` ## Model Versions The latest version is `morph-rerank-v3` with state-of-the-art performance across all code benchmarks for its speed-accuracy ratio. `morph-rerank-v2` with dims 1536 remains available for backward compatibility. ## Example Request ```typescript theme={null} async function rerankResults( query: string, documents: string[], topN: number = 5 ) { const response = await fetch("https://api.morphllm.com/v1/rerank", { method: "POST", headers: { Authorization: "Bearer your-morph-api-key", "Content-Type": "application/json", }, body: JSON.stringify({ model: "morph-rerank-v3", query: query, documents: documents, top_n: topN, }), }); return await response.json(); } ``` Note that the `top_n` request parameter is optional and will default to the length of the `documents` field. Result documents will be sorted by relevance, and the `index` property can be used to determine original order. ## Input Format The request accepts the following parameters: | Parameter | Type | Required | Description | | --------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------- | | `model` | string | Yes | The model ID to use for reranking. Use `morph-rerank-v3` (latest) or `morph-rerank-v3`. | | `query` | string | Yes | The search query to compare documents against. | | `documents` | array | No\* | An array of document strings to be reranked. Required if `embedding_ids` is not provided. | | `embedding_ids` | array | No\* | An array of embedding IDs to rerank. Required if `documents` is not provided. Remote content storage must be enabled. | | `top_n` | integer | No | Number of top results to return. Default is all documents. | \* Either `documents` or `embedding_ids` must be provided. ## Using Document Content ```python theme={null} import requests def rerank_results(query, documents, top_n=5): response = requests.post( "https://api.morphllm.com/v1/rerank", headers={ "Authorization": f"Bearer your-morph-api-key", "Content-Type": "application/json" }, json={ "model": "morph-rerank-v3", "query": query, "documents": documents, "top_n": top_n } ) return response.json() # Example usage with code documentation query = "How to implement JWT authentication in Express" documents = [ """const jwt = require('jsonwebtoken'); const express = require('express'); function authenticateToken(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (token == null) return res.sendStatus(401); jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => { if (err) return res.sendStatus(403); req.user = user; next(); }); }""", """const express = require('express'); const app = express(); const port = 3000; app.use(express.json()); app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(port, () => { console.log(`App listening at http://localhost:${port}`); });""", """const jwt = require('jsonwebtoken'); const user = { id: 123, username: 'john_doe' }; const accessToken = jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '15m' }); const refreshToken = jwt.sign(user, process.env.REFRESH_TOKEN_SECRET); console.log('Access Token:', accessToken);""", """const express = require('express'); const router = express.Router(); router.get('/users', (req, res) => { res.json([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]); }); router.post('/users', (req, res) => { const { name } = req.body; res.json({ id: 3, name }); }); module.exports = router;""", """const passport = require('passport'); const GoogleStrategy = require('passport-google-oauth20').Strategy; passport.use(new GoogleStrategy({ clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL: "/auth/google/callback" }, (accessToken, refreshToken, profile, done) => { return done(null, profile); }));""", """const express = require('express'); const passport = require('passport'); const JwtStrategy = require('passport-jwt').Strategy; const ExtractJwt = require('passport-jwt').ExtractJwt; passport.use(new JwtStrategy({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: process.env.JWT_SECRET }, (payload, done) => { User.findById(payload.sub, (err, user) => { if (err) return done(err, false); if (user) return done(null, user); return done(null, false); }); }));""" ] results = rerank_results(query, documents, top_n=3) print(results) ``` ## Using Embedding IDs When you have previously generated embeddings and enabled remote content storage, you can rerank using embedding IDs: ```javascript theme={null} async function rerankWithEmbeddingIds(query, embeddingIds, topN = 5) { const response = await fetch("https://api.morphllm.com/v1/rerank", { method: "POST", headers: { Authorization: "Bearer your-morph-api-key", "Content-Type": "application/json", }, body: JSON.stringify({ model: "morph-rerank-v3", // Use the latest model version query: query, embedding_ids: embeddingIds, top_n: topN, }), }); return await response.json(); } // Example with embedding IDs const query = "React state management patterns"; const embeddingIds = [ "emb_123456789", "emb_987654321", "emb_456789123", "emb_789123456", "emb_321654987", ]; rerankWithEmbeddingIds(query, embeddingIds, 3).then((results) => console.log(results) ); ``` ## cURL Examples ### With Document Content ```bash theme={null} curl --request POST \ --url https://api.morphllm.com/v1/rerank \ --header 'Authorization: Bearer your-morph-api-key' \ --header 'Content-Type: application/json' \ --data '{ "model": "morph-rerank-v3", "query": "How to implement JWT authentication in Express", "documents": [ "const jwt = require(\"jsonwebtoken\");\nconst express = require(\"express\");\n\nfunction authenticateToken(req, res, next) {\n const authHeader = req.headers[\"authorization\"];\n const token = authHeader && authHeader.split(\" \")[1];\n \n if (token == null) return res.sendStatus(401);\n \n jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {\n if (err) return res.sendStatus(403);\n req.user = user;\n next();\n });\n}", "const express = require(\"express\");\nconst app = express();\nconst port = 3000;\n\napp.use(express.json());\n\napp.get(\"/\", (req, res) => {\n res.send(\"Hello World!\");\n});\n\napp.listen(port, () => {\n console.log(`App listening at http://localhost:${port}`);\n});", "const jwt = require(\"jsonwebtoken\");\n\nconst user = { id: 123, username: \"john_doe\" };\nconst accessToken = jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, { expiresIn: \"15m\" });\nconst refreshToken = jwt.sign(user, process.env.REFRESH_TOKEN_SECRET);\n\nconsole.log(\"Access Token:\", accessToken);", "const express = require(\"express\");\nconst router = express.Router();\n\nrouter.get(\"/users\", (req, res) => {\n res.json([{ id: 1, name: \"John\" }, { id: 2, name: \"Jane\" }]);\n});\n\nrouter.post(\"/users\", (req, res) => {\n const { name } = req.body;\n res.json({ id: 3, name });\n});\n\nmodule.exports = router;", "const passport = require(\"passport\");\nconst GoogleStrategy = require(\"passport-google-oauth20\").Strategy;\n\npassport.use(new GoogleStrategy({\n clientID: process.env.GOOGLE_CLIENT_ID,\n clientSecret: process.env.GOOGLE_CLIENT_SECRET,\n callbackURL: \"/auth/google/callback\"\n}, (accessToken, refreshToken, profile, done) => {\n return done(null, profile);\n}));", "const express = require(\"express\");\nconst passport = require(\"passport\");\nconst JwtStrategy = require(\"passport-jwt\").Strategy;\nconst ExtractJwt = require(\"passport-jwt\").ExtractJwt;\n\npassport.use(new JwtStrategy({\n jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),\n secretOrKey: process.env.JWT_SECRET\n}, (payload, done) => {\n User.findById(payload.sub, (err, user) => {\n if (err) return done(err, false);\n if (user) return done(null, user);\n return done(null, false);\n });\n}));" ], "top_n": 3 }' ``` ### With Embedding IDs ```bash theme={null} curl --request POST \ --url https://api.morphllm.com/v1/rerank \ --header 'Authorization: Bearer your-morph-api-key' \ --header 'Content-Type: application/json' \ --data '{ "model": "morph-rerank-v3", "query": "React state management patterns", "embedding_ids": [ "emb_123456789", "emb_987654321", "emb_456789123", "emb_789123456", "emb_321654987" ], "top_n": 3 }' ``` ## Response Format ```json theme={null} { "id": "rerank-26b29083d49a4c1e82032a95549a8633", "model": "morph-rerank-v3", "usage": { "total_tokens": 21 }, "results": [ { "index": 0, "document": { "text": "const jwt = require('jsonwebtoken');\nconst express = require('express');\n\nfunction authenticateToken(req, res, next) {\n const authHeader = req.headers['authorization'];\n const token = authHeader && authHeader.split(' ')[1];\n \n if (token == null) return res.sendStatus(401);\n \n jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {\n if (err) return res.sendStatus(403);\n req.user = user;\n next();\n });\n}" }, "relevance_score": 0.92 }, { "index": 5, "document": { "text": "const express = require('express');\nconst passport = require('passport');\nconst JwtStrategy = require('passport-jwt').Strategy;\nconst ExtractJwt = require('passport-jwt').ExtractJwt;\n\npassport.use(new JwtStrategy({\n jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),\n secretOrKey: process.env.JWT_SECRET\n}, (payload, done) => {\n User.findById(payload.sub, (err, user) => {\n if (err) return done(err, false);\n if (user) return done(null, user);\n return done(null, false);\n });\n}));" }, "relevance_score": 0.87 }, { "index": 2, "document": { "text": "const jwt = require('jsonwebtoken');\n\nconst user = { id: 123, username: 'john_doe' };\nconst accessToken = jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '15m' });\nconst refreshToken = jwt.sign(user, process.env.REFRESH_TOKEN_SECRET);\n\nconsole.log('Access Token:', accessToken);" }, "relevance_score": 0.75 } ] } ``` When using embedding IDs, the response will include the document content if available ## Remote Content Storage To use embedding IDs for reranking, you must enable remote content storage in your account settings. This allows Morph to retrieve the content associated with each embedding ID for reranking purposes. Without remote content storage enabled, you'll need to pass in the document content directly. Benefits of using embedding IDs: * Reduced payload size for large document collections * Improved security as content is stored in your account's secure storage * Ability to rerank content that was previously embedded ## Integration with Search Systems The Rerank API is typically used as a second-pass ranking system in a multi-stage retrieval pipeline: ```javascript theme={null} import { OpenAI } from 'openai'; import fetch from 'node-fetch'; // Initialize OpenAI client for embeddings const openaiClient = new OpenAI({ apiKey: 'your-morph-api-key', baseURL: 'https://api.morphllm.com/v1' }); // Example search pipeline async function semanticSearch(query, codebase) { // 1. Generate embedding for the query const embeddingResponse = await openaiClient.embeddings.create({ model: "morph-embedding-v3", input: query }); const queryEmbedding = embeddingResponse.data[0].embedding; // 2. Retrieve initial candidates using vector similarity // (Simplified example - in practice, you would use a vector database) const candidateDocuments = retrieveSimilarDocuments(queryEmbedding, codebase); // 3. Rerank candidates for more accurate results // Example search pipeline with embedding IDs async function semanticSearchWithEmbeddingIds(query, embeddingIds) { // Rerank candidates for more accurate results const rerankedResults = await fetch('https://api.morphllm.com/v1/rerank', { method: 'POST', headers: { 'Authorization': 'Bearer your-morph-api-key', 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'morph-rerank-v3', query: query, embedding_ids: embeddingIds, top_n: 5 }) }).then(res => res.json()); return rerankedResults; } // Helper function to simulate vector similarity search function retrieveSimilarDocuments(queryEmbedding, codebase) { // In practice, this would be a call to a vector database return codebase.slice(0, 20); // Return first 20 documents as candidates } ``` This two-stage approach combines the efficiency of initial retrieval methods with the accuracy of deep neural reranking models. # Get Git references (git protocol) Source: https://docs.morphllm.com/api-reference/get-git-references-git-protocol api-reference/openapi-git.json get /v1/repos/{repo_id}/info/refs Git protocol endpoint that returns repository references (branches, tags). Called automatically by git clients during clone/fetch operations. Typically not invoked directly by developers. ## Git Protocol Endpoint This endpoint implements the Git smart HTTP protocol's reference discovery phase. It's called automatically by: - `git clone` - `git fetch` - `git pull` - `morphGit.clone()` - `morphGit.pull()` ## Authentication Flow The git-proxy validates your Morph API key and translates it to Azure DevOps authentication automatically. ## When to Use You typically won't call this endpoint directly. It's used under the hood by git clients and the Morph SDK. # Git fetch/clone operation Source: https://docs.morphllm.com/api-reference/git-fetchclone-operation api-reference/openapi-git.json post /v1/repos/{repo_id}/git-upload-pack Git protocol endpoint for fetching repository data. Used automatically by git clone, git fetch, and morphGit.clone(). Proxies requests to Azure DevOps with authentication translation. ## Git Protocol Endpoint This endpoint implements the Git smart HTTP protocol's upload-pack phase, which transfers repository objects during fetch/clone operations. ## Automatic Usage Called automatically by: ```bash # Standard git git clone https://repos.morphllm.com/v1/repos/my-project git fetch origin # Or via SDK import { MorphGit } from 'morphsdk/git'; const morphGit = new MorphGit({ apiKey: 'sk-...' }); await morphGit.clone({ repoId: 'my-project', dir: './my-project' }); ``` ## Architecture ``` Git Client β†’ git-proxy (repos.morphllm.com) β†’ Azure DevOps ↓ Auth translation Morph API key β†’ Azure PAT ``` # Git push operation Source: https://docs.morphllm.com/api-reference/git-push-operation api-reference/openapi-git.json post /v1/repos/{repo_id}/git-receive-pack Git protocol endpoint for pushing changes to the repository. Automatically triggers the embedding pipeline on successful push. Used by git push and morphGit.push(). ## Git Protocol + Embedding Pipeline This endpoint handles git push operations and triggers automatic code embedding for semantic search. ## Push Flow 1. **Git push initiated** - Client sends changes 2. **Authentication** - API key validated and translated 3. **Push to Azure DevOps** - Changes stored in git provider 4. **Branch detection** - Branch name parsed from git protocol 5. **Webhook trigger** - Embedding pipeline started asynchronously 6. **Code embedding** - Changed files processed and embedded ## Automatic Usage ```bash # Standard git git push origin main # Or via SDK import { MorphGit } from 'morphsdk/git'; const morphGit = new MorphGit({ apiKey: 'sk-...' }); await morphGit.push({ dir: './my-project', branch: 'main' }); ``` ## Embedding Pipeline After a successful push: - Waits 1.5s for Azure to process - Fetches commit info and changed files - Calls embedding service with `apiKeyId` for usage attribution - Processes files with `morph-embedding-v4` - Stores embeddings for semantic search ## Performance The embedding pipeline runs asynchronously - your push completes immediately without waiting for embeddings. # Agent Tools (edit_file) Source: https://docs.morphllm.com/guides/agent-tools Build precise AI agents that edit code fast without full file rewrites using Morph's edit_file tool ## Essential Supporting Tools Always read files before editing to understand the structure: ```json theme={null} { "name": "read_file", "description": "Read the contents of a file to understand its structure before making edits", "parameters": { "properties": { "target_file": { "type": "string", "description": "The path of the file to read" }, "start_line_one_indexed": { "type": "integer", "description": "Start line number (1-indexed)" }, "end_line_one_indexed_inclusive": { "type": "integer", "description": "End line number (1-indexed, inclusive)" }, "explanation": { "type": "string", "description": "Why you're reading this file" } }, "required": ["target_file", "explanation"] } } ``` **Best practice:** Read the relevant sections first, then edit with proper context. Semantic search to locate relevant code: ```json theme={null} { "name": "codebase_search", "description": "Find snippets of code from the codebase most relevant to the search query", "parameters": { "properties": { "query": { "type": "string", "description": "The search query to find relevant code" }, "target_directories": { "type": "array", "items": {"type": "string"}, "description": "Optional: limit search scope to specific directories" }, "explanation": { "type": "string", "description": "Why you're searching for this" } }, "required": ["query", "explanation"] } } ``` **Best practice:** Search first to understand the codebase, then read specific files. When you need exact text or pattern matches: ```json theme={null} { "name": "grep_search", "description": "Fast text-based regex search that finds exact pattern matches within files", "parameters": { "properties": { "query": { "type": "string", "description": "The regex pattern to search for" }, "include_pattern": { "type": "string", "description": "File types to include (e.g. '*.ts')" }, "explanation": { "type": "string", "description": "Why you're searching for this pattern" } }, "required": ["query", "explanation"] } } ``` **Best practice:** Use for finding function names, imports, or specific strings. Navigate and understand the codebase structure: ```json theme={null} { "name": "list_dir", "description": "List the contents of a directory to understand project structure", "parameters": { "properties": { "relative_workspace_path": { "type": "string", "description": "Path to list contents of, relative to the workspace root" }, "explanation": { "type": "string", "description": "Why you're listing this directory" } }, "required": ["relative_workspace_path", "explanation"] } } ``` **Best practice:** Use to explore unknown codebases or find related files before editing. ## Agent Workflow Effective agents follow this pattern: 1. **πŸ” Search**: Find relevant code with `codebase_search` or `grep_search` 2. **πŸ“– Read**: Get context with `read_file` before editing 3. **✏️ Edit**: Make precise changes with `edit_file` 4. **βœ… Verify**: Read again to confirm changes worked ## Common Patterns **Delete a section in between:** ```javascript theme={null} // ... existing code ... function keepThis() { return "stay"; } function alsoKeepThis() { return "also stay"; } // ... existing code ... ``` **Add imports:** ```javascript theme={null} import { useState, useEffect } from "react"; import { calculateTax } from "./utils"; // New import // ... existing code ... ``` **Update configuration:** ```json theme={null} { "name": "my-app", "version": "2.0.0", "scripts": { "dev": "next dev", "build": "next build", "test": "jest" } } ``` **Add error handling:** ```javascript theme={null} // ... existing code ... function divide(a, b) { if (b === 0) { throw new Error("Cannot divide by zero"); } return a / b; } // ... existing code ... ``` **Update function parameters:** ```javascript theme={null} // ... existing code ... function authenticateUser(email, password) { const result = await verifyUser(email, password); if (result) { return "Authenticated"; } else { return "Unauthenticated"; } } // ... existing code ... ``` **Add new methods to a class:** ```javascript theme={null} // ... existing code ... class UserService { async getUser(id) { return await this.db.findUser(id); } async updateUser(id, data) { return await this.db.updateUser(id, data); } } // ... existing code ... ``` ## Error Handling Morph is trained to be robust to poor quality update snippets, but you should still follow these steps to ensure the best quality. When tools fail, follow these steps: 1. **Check file permissions**: Ensure the target file is writable 2. **Verify file path**: Confirm the file exists and path is correct 3. **Review syntax**: Check that your edit snippet follows the `// ... existing code ...` pattern 4. **Retry with context**: Read the file again and provide more context around your changes 5. **Simplify changes**: Break complex edits into smaller, focused changes **Common Error Patterns:** ```javascript theme={null} // ❌ Wrong - missing context function newFunction() { return "hello"; } // βœ… Correct - with context // ... existing code ... function newFunction() { return "hello"; } // ... existing code ... ``` ## Next Steps Ready to start building with Morph? Here's what to do next: Learn about the Apply API endpoints, models, and message formats for production use Step-by-step guide to configure your agent with the edit\_file tool and integrate with Morph's Fast Apply API For complex refactoring across multiple files, consider using multiple `edit_file` calls in sequence. For failed edits, read the file again and provide more context around your changes. # Vercel AI SDK Source: https://docs.morphllm.com/guides/ai-sdk Stream fast code edits with Morph using the Vercel AI SDK # Morph + Vercel AI SDK Stream code edits at 10,500+ tokens/second using the Vercel AI SDK with Morph's fast apply model. Use Vercel's AI Gateway for unified billing, rate limits, and failover across 100+ AI models. ## Setup ### Option 1: AI Gateway (Recommended) 1. Get an [AI Gateway API key](https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys%3Futm_source%3Dai_sdk_code_generator_modal\&title=Get+an+AI+Gateway+API+Key) from Vercel 2. Add it to your environment variables as `OPENAI_API_KEY` 3. Install the AI SDK: ```bash theme={null} npm install ai@beta ``` ### Option 2: Direct API 1. Get a Morph API key from the [Morph dashboard](https://morphllm.com) 2. Add it to your environment variables as `MORPH_API_KEY` 3. Install the AI SDK: ```bash theme={null} npm install ai@beta ``` ## Implementation ```typescript AI Gateway theme={null} import { streamText } from 'ai' import { createOpenAI } from '@ai-sdk/openai' const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY!, baseURL: 'https://gateway.ai.vercel.com/v1', headers: { 'X-Vercel-AI-Provider': 'morph', }, }) export async function POST(req: Request) { const { editInstructions, originalCode, update } = await req.json() // Get the morph model through AI Gateway const model = openai('morph-v3-fast') // Call the language model with the prompt const result = streamText({ model, messages: [ { role: 'user', content: `${editInstructions}\n${originalCode}\n${update}` } ], topP: 1, }) // Respond with a streaming response return result.toAIStreamResponse() } ``` ```typescript Direct API theme={null} import { streamText } from 'ai' import { createOpenAICompatible } from '@ai-sdk/openai-compatible' const morph = createOpenAICompatible({ apiKey: process.env.MORPH_API_KEY!, name: 'morph', baseURL: 'https://api.morphllm.com/v1' }) export async function POST(req: Request) { const { editInstructions, originalCode, update } = await req.json() // Get a language model const model = morph('morph-v3-fast') // Call the language model with the prompt const result = streamText({ model.chat(), messages: [ { role: 'user', content: `${editInstructions}\n${originalCode}\n${update}` } ], topP: 1, }) // Respond with a streaming response return result.toAIStreamResponse() } ``` ```` ```typescript components/CodeEditor.tsx 'use client' import { useCompletion } from 'ai/react' import { useState } from 'react' export function CodeEditor() { const [originalCode, setOriginalCode] = useState('') const [editInstructions, setEditInstructions] = useState('') const { completion, isLoading, complete } = useCompletion({ api: '/api/morph', }) const handleApplyEdit = async () => { await complete('', { body: { originalCode, editInstructions }, }) } return (