Morph Python SDK
One typed client for Morph's specialized agent models: merge code edits with Fast Apply at ~10,500 tok/s, search a repo with WarpGrep, compress context with the compactor, route between models, and run browser tasks. Synchronous and async, Python 3.9+.
pip install morphsdk
Quickstart
from morphsdk import Morph
morph = Morph(api_key="sk-...") # or set MORPH_API_KEY
result = morph.edit.file(
path="src/app.py",
instruction="Add a retry decorator to fetch_user",
code_edit="# ... existing code ...\n@retry(max_attempts=3)\ndef fetch_user(user_id):",
)
print(result.changes) # lines added / removed / modified
The API key is read from MORPH_API_KEY if you do not pass api_key=. Get one at morphllm.com.
Fast Apply: merge edits onto a file
edit.file reads the file, sends the original plus your edit snippet to the merge API, and writes the result back. Use auto_write=False to get the merged text without touching disk.
result = morph.edit.file(
path="src/app.py",
instruction="Rename the handler to on_request",
code_edit="# ... existing code ...\ndef on_request(req):\n # ... existing code ...",
)
# Code-in, code-out, no file I/O:
merged = morph.edit.code(
instruction="Add type hints",
original_code="def add(a, b):\n return a + b",
code_edit="def add(a: int, b: int) -> int:\n # ... existing code ...",
)
WarpGrep: search a codebase
grep.search runs the WarpGrep agent loop over a local repo. Pass stream=True to iterate per-turn steps before the final result. search_github does the same against a public repo.
result = morph.grep.search(
query="where is the auth middleware registered?",
repo_root="/path/to/repo",
)
for step in morph.grep.search(query="rate limiter", repo_root="/path/to/repo", stream=True):
print(step)
result = morph.grep.search_github(
query="how does the router pick a model?",
github="morphllm/landing",
)
Explore: multi-turn codebase Q&A
explore.run answers a natural-language question about a repository and returns a summary plus the contexts it found. thoroughness is quick, medium, or thorough.
result = morph.explore.run(
query="how does the WarpGrep agent loop call the model each turn?",
repo_root="/path/to/repo",
thoroughness="quick",
)
print(result.summary)
for ctx in result.contexts:
print(ctx)
Compact: compress context
result = morph.compact(
input="...long transcript or code...",
query="what matters for the next step",
compression_ratio=0.5,
)
print(result)
Router: pick a model for a prompt
choice = morph.router.select_model(input="Explain quicksort")
print(choice)
More resources
The same client exposes morph.search (semantic codebase search by repo_id), morph.browser (browser.run(task=..., url=...)), morph.git, morph.github, morph.mobile, and morph.reflex (per-turn classifiers, OpenAI-fine-tuning-compatible). See the docs for the full surface.
Async
AsyncMorph mirrors Morph with every method as async def; streaming methods return an AsyncIterator.
import asyncio
from morphsdk import AsyncMorph
async def main():
async with AsyncMorph(api_key="sk-...") as morph:
result = await morph.edit.file(
path="src/app.py",
instruction="Fix the off-by-one",
code_edit="# ... existing code ...",
)
print(result.changes)
asyncio.run(main())
Framework adapters
Install the extra for your agent framework to get ready-made tool definitions.
pip install "morphsdk[openai]" # OpenAI tool schemas
pip install "morphsdk[anthropic]" # Anthropic tool schemas
pip install "morphsdk[langchain]" # LangChain tools
pip install "morphsdk[otel]" # OpenTelemetry tracing
pip install "morphsdk[all]" # everything above
from morphsdk.adapters.openai import edit_file_tool_def
tools = [edit_file_tool_def()]
Errors
Every failure raises a subclass of MorphError, so you can catch one type or branch on specifics.
from morphsdk import (
MorphError,
AuthenticationError,
RateLimitError,
ValidationError,
NotFoundError,
PermissionDeniedError,
APIConnectionError,
APITimeoutError,
)
try:
morph.edit.file(path="src/app.py", instruction="...", code_edit="...")
except RateLimitError:
... # back off and retry
except MorphError as err:
... # everything else
Configuration
Morph(...) and AsyncMorph(...) accept:
| Argument | Default | Purpose |
|---|---|---|
api_key |
MORPH_API_KEY |
API key. Required. |
timeout |
30.0 |
Per-request timeout in seconds. |
max_retries |
3 |
Retries on transient failures. |
debug |
False |
Log requests to stderr (MORPH_DEBUG=1). |
License
MIT
Metadata
Release files for morphsdk 0.2.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| morphsdk-0.2.6.tar.gz | 106.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| morphsdk-0.2.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 215.5 kB
Release files / morphsdk-0.2.6.tar.gz
| Download URL | morphsdk-0.2.6.tar.gz |
|---|---|
| Size | 106.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
74ce7b16669424204bbc22a0e45dd23e1ed1349e3130bf7c8689d9964da74a0d
|
|
BLAKE2b-256 checksum How to use checksums |
5bacab72dbdbafe9066ef2ff7eb7fe47aa02cc44f2bec3179178086dc38609d3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 26, 2026.
Transparency logRelease files / morphsdk-0.2.6-py3-none-any.whl
| Download URL | morphsdk-0.2.6-py3-none-any.whl |
|---|---|
| Size | 108.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c2801c133c951c049418f57ade413e132bcaf1bf66cb1c2519f50aa79c8a72bf
|
|
BLAKE2b-256 checksum How to use checksums |
d6363017885dfba76e4355c34220f41456140b1ebf57ad5ca81c6ad760d82d42
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 26, 2026.
Transparency logSecurity for morphsdk 0.2.6
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for morphsdk-0.2.6.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 26, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.