Content
# opencode-morph-fast-apply
[](https://github.com/JRedeker/opencode-morph-fast-apply/actions/workflows/ci.yml)
[](https://github.com/JRedeker/opencode-morph-fast-apply/releases/latest)
[](LICENSE)
OpenCode plugin for [Morph Fast Apply](https://morphllm.com) - 10x faster code editing with lazy edit markers.
## Features
- **10,500+ tokens/sec** code editing via Morph's Fast Apply API
- **Lazy edit markers** (`// ... existing code ...`) - no exact string matching needed
- **98% accuracy** with intelligent code merging
- **Pre-flight validation** - prevents accidental file deletions when markers are missing
- **Unified diff output** with context for easy review
- **Custom TUI display** - branded titles like `Morph: src/file.ts +15/-3 (450ms)`
- **Graceful fallback** - suggests native `edit` tool on API failure
> **Note:** This is an OpenCode plugin that wraps Morph's Fast Apply API. For the official Morph MCP server (which includes WarpGrep search), see [@morphllm/morphmcp](https://www.npmjs.com/package/@morphllm/morphmcp). This plugin uses `morph_edit` as the tool name to avoid conflicts if you have both installed.
## Installation
### 1. Add the plugin and always-on instruction to your OpenCode config
Preferred when your setup syncs packaged instructions into `~/.config/opencode/instructions/`:
Add to your global config (`~/.config/opencode/opencode.json`):
```json
{
"instructions": [
"~/.config/opencode/instructions/morph-tools.md"
],
"plugin": [
"github:JRedeker/opencode-morph-fast-apply"
]
}
```
Or pin to a specific version:
```json
{
"instructions": [
"~/.config/opencode/instructions/morph-tools.md"
],
"plugin": [
"github:JRedeker/opencode-morph-fast-apply#v1.9.0"
]
}
```
Recommended setup summary:
- Prefer the stable synced instruction path: `~/.config/opencode/instructions/morph-tools.md`
- Use the packaged `node_modules/.../morph-tools.md` path only when your setup does not sync instructions
- Keep the routing policy in the OpenCode `instructions` array, not a skill
If you are installing the plugin directly and do not sync packaged instructions into
`~/.config/opencode/instructions/`, you can point OpenCode at the packaged file
instead:
```json
{
"instructions": [
"~/.config/opencode/node_modules/opencode-morph-fast-apply/instructions/morph-tools.md"
],
"plugin": [
"github:JRedeker/opencode-morph-fast-apply"
]
}
```
The `morph_edit` tool description remains self-contained, but for more reliable
tool selection you should also load the packaged always-on instruction file
shown above. This avoids agents defaulting to native `edit` when `morph_edit`
is the better fit for large, scattered, or whitespace-sensitive edits.
Important: the active agent must also expose `morph_edit` in its tool manifest.
If an agent profile marks `morph_edit: false`, the model cannot choose Morph
even when the plugin is installed and the always-on instruction is present.
### 2. Set your Morph API key
Get an API key at [morphllm.com/dashboard](https://morphllm.com/dashboard/api-keys), then add to your shell profile:
```bash
export MORPH_API_KEY="sk-your-key-here"
```
### 3. Restart OpenCode
The `morph_edit` tool will now be available.
## Usage
The LLM uses `morph_edit` for efficient partial file edits:
```
morph_edit({
target_filepath: "src/auth.ts",
instructions: "I am adding error handling for invalid tokens",
code_edit: `// ... existing code ...
function validateToken(token) {
if (!token) {
throw new Error("Token is required");
}
// ... existing code ...
}
// ... existing code ...`
})
```
### When to use `morph_edit` vs `edit`
| Situation | Tool | Reason |
|-----------|------|--------|
| Small, exact replacement | `edit` | Fast, no API call |
| Large file (500+ lines) | `morph_edit` | Handles partial snippets |
| Multiple scattered changes | `morph_edit` | Batch efficiently |
| Whitespace-sensitive | `morph_edit` | Forgiving with formatting |
## Configuration
| Variable | Default | Description |
|----------|---------|-------------|
| `MORPH_API_KEY` | (required) | Your Morph API key |
| `MORPH_API_URL` | `https://api.morphllm.com` | API endpoint |
| `MORPH_MODEL` | `morph-v3-fast` | Model to use (see below) |
| `MORPH_TIMEOUT` | `30000` | Request timeout in ms |
### Available Models
| Model | Speed | Accuracy | Best For |
|-------|-------|----------|----------|
| `morph-v3-fast` | 10,500+ tok/sec | 96% | Real-time applications, quick edits |
| `morph-v3-large` | 5,000+ tok/sec | 98% | Complex changes, highest accuracy |
| `auto` | 5,000-10,500 tok/sec | ~98% | Recommended - automatically selects optimal model |
## How It Works
1. Reads the original file content
2. Sends to Morph API:
- `<instruction>` - Your intent description
- `<code>` - The complete original file
- `<update>` - Your partial edit with markers
3. Morph intelligently merges the lazy edit markers with original code
4. Writes the merged result back to the file
5. Returns a unified diff showing what changed
## Troubleshooting
### "MORPH_API_KEY not configured"
Ensure the environment variable is set and exported:
```bash
echo $MORPH_API_KEY # Should show your key
```
### Timeout errors
Increase the timeout for large files:
```bash
export MORPH_TIMEOUT=60000 # 60 seconds
```
### Unexpected deletions
If code is being deleted unexpectedly, ensure your `code_edit` includes `// ... existing code ...` markers at the start and end. Omitting these markers tells Morph to replace the entire file.
### Safety guards
The plugin blocks unsafe Morph responses before writing files:
- **Marker leakage guard**: If merged output contains `// ... existing code ...` but the original file did not, the write is aborted.
- **Catastrophic truncation guard**: If merged output loses more than 60% of characters **and** more than 50% of lines (for marker-based edits), the write is aborted.
- **Dropped imports guard**: If top-level import identifiers present in the original file are missing from the merged output, the write is aborted. This catches silent import loss that can occur when edits fall outside the anchoring context.
- **Path confinement**: All target paths are resolved and confined to the project root. Symlinks are followed and validated; paths that resolve outside the root are rejected.
- **Secret scrubbing**: API error messages are automatically scrubbed to prevent leaking your `MORPH_API_KEY` or Bearer tokens in tool output.
In all guard cases, `morph_edit` returns a detailed error with recovery options (retry with tighter anchors, use native `edit`, or split into smaller edits).
### Markdown-fenced `code_edit` input
If an AI agent wraps `code_edit` in markdown fences (for example, ```` ```typescript ... ``` ````), `morph_edit` strips the outer fence before sending content to Morph.
### Wrong edit location
If edits are applied to the wrong location, add more unique context around your changes and make your `instructions` more specific about which function/section you're modifying.
### Tool blocked in plan/explore mode
The `morph_edit` tool is disabled in readonly agent modes (`plan`, `explore`). Switch to a build/code mode to make edits.
## Changelog
### v1.8.2
- **Tool exposure requirement docs** — `instructions/morph-tools.md` now documents that agent profiles must expose `morph_edit: true` in their tool manifest for the routing policy to take effect
- **README alignment** — Installation section notes the tool manifest requirement alongside the always-on instruction
- **Test coverage** — Tests verify the tool exposure section exists in the instruction file and README
### v1.8.1
- **Stable instruction path guidance** - README now prefers `~/.config/opencode/instructions/morph-tools.md` and keeps the packaged `node_modules/...` path as a fallback for direct installs
- **Canonical routing policy wording** - `instructions/morph-tools.md` now explicitly says morph routing belongs in always-on instructions, not a skill
- **Docs/test alignment** - Tests now verify the stable instruction path and canonical policy wording
### v1.8.0
- **Packaged always-on instruction** - `instructions/morph-tools.md` now ships with the plugin so OpenCode can load reliable `morph_edit` selection guidance through the `instructions` array
- **Packaging coverage** - package metadata now includes the `instructions/` directory, and tests verify that the shipped instruction path is documented
- **Installation docs updated** - README now recommends adding the packaged always-on instruction to global OpenCode config for more reliable `morph_edit` selection
### v1.7.0
- **Self-contained tool description** — Core `morph_edit` guidance still lives in the tool description so the tool is usable even without extra setup.
- **Packaged always-on instruction** — `instructions/morph-tools.md` can be added to your OpenCode `instructions` array so agents choose `morph_edit` more reliably.
- **Removed skill pattern** — Deleted `skills/morph/SKILL.md` and `MORPH_INSTRUCTIONS.md`. The skill added a round-trip and split-brain problem where guidance lived in multiple places.
- **Removed `MORPH_SKILL_LOAD_HINT`** — Agents no longer need to load a skill before using `morph_edit`.
### v1.6.0
- **Post-merge safety guards** - Blocks unsafe Morph output before writing to disk:
- **Marker leakage guard** - Detects when merge model treats `// ... existing code ...` as literal text
- **Truncation guard** - Dual-metric validation (>60% char + >50% line loss) prevents silent data loss
- **Input normalization** - Strips markdown fences from `code_edit` to prevent merge confusion
- **TUI guard titles** - Shows `Morph: blocked (marker leakage)` or `Morph: blocked (truncation)` on guard failures
- **32 test cases** - Comprehensive coverage of normalization, leakage detection, and truncation edge cases
### v1.5.0
- **Custom TUI display** - Tool output shows branded titles like `Morph: src/file.ts +15/-3 (450ms)`
- **API timing** - Response time tracked and displayed in tool title
- **Structured metadata** - Provider, version, model info included for future TUI enhancements
### v1.4.0
- **Fixed stdout pollution** - Replaced `console.log`/`console.warn` with `client.app.log()` SDK method
- **Readonly agent protection** - Blocks `morph_edit` in `plan` and `explore` modes to prevent accidental edits
- **Stderr fallback** - Graceful logging if SDK method unavailable
### v1.3.0
- **Pre-flight validation prevents accidental deletions** - Tool now returns an error if `code_edit` is missing markers for files >10 lines, preventing catastrophic code loss
- **Improved code_edit parameter description** - Changed from "Only the changed lines" to "The code changes wrapped with markers" to emphasize wrapping
- **Added explicit wrapping rule** - Tool description now includes "ALWAYS wrap your changes with markers at the start AND end"
- **Restored comprehensive examples** - `MORPH_INSTRUCTIONS.md` now includes all key examples (adding functions, modifying code, deletions)
- **Added Quick Reference** - Aligned with Morph's official agent instructions format
- **Added fetch timeout example** - From official Morph documentation
### v1.2.0
- **Tool schema aligned with Morph official spec** - Tool description now matches [Morph's recommended format](https://docs.morphllm.com/quickstart)
- **Concise AI agent instructions** - `MORPH_INSTRUCTIONS.md` reduced by 72% (237→67 lines) while keeping critical guidance
- **Added marker validation warning** - Server logs warn when `code_edit` is missing markers (helps debug unexpected deletions)
- **Documentation improvements** - Added troubleshooting section, model comparison table, updated config paths
### v1.1.0
- Initial public release
- Morph Fast Apply integration with lazy edit markers
- Unified diff output
- Graceful fallback suggestions
## Contributing
Contributions welcome! This plugin could potentially be integrated into OpenCode core.
This project uses Bun. The `bun.lock` lockfile is tracked in git; `pnpm-lock.yaml` and `package-lock.json` are ignored.
## License
[MIT](LICENSE)
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
hf-mcp-server
Hugging Face MCP Server
smart-tree
Smart Tree is a fast directory visualization tool, 10-24x quicker than...
hf-mcp-server
Connect your LLM to Hugging Face Hub with the official MCP Server.