Morph SDK - AI-powered code editing, search, browser automation, and more
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file morphsdk-0.2.5.tar.gz.
File metadata
- Download URL: morphsdk-0.2.5.tar.gz
- Upload date:
- Size: 104.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
78dd759c7b8178da6e24296b0030fab8d17f59cc16c69cf18939f5cabb96f440
|
|
| MD5 |
47e3420efdaa65ad2f1d8e9cc924b782
|
|
| BLAKE2b-256 |
104cd858727bb7a01c9c0f4d0044970fd82591bd6a852d553f35c4bb14c646f4
|
Provenance
The following attestation bundles were made for morphsdk-0.2.5.tar.gz:
Publisher:
morphcli-publish-python-sdk.yml on morphllm/landing
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
morphsdk-0.2.5.tar.gz -
Subject digest:
78dd759c7b8178da6e24296b0030fab8d17f59cc16c69cf18939f5cabb96f440 - Sigstore transparency entry: 1948259856
- Sigstore integration time:
-
Permalink:
morphllm/landing@1ef4fed61698bdf1c3c9937aba56fa193e0e1fe0 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/morphllm
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
morphcli-publish-python-sdk.yml@1ef4fed61698bdf1c3c9937aba56fa193e0e1fe0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file morphsdk-0.2.5-py3-none-any.whl.
File metadata
- Download URL: morphsdk-0.2.5-py3-none-any.whl
- Upload date:
- Size: 106.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b045d1e4e55b84e4b519138767582c9e9769f0ae1147348e919f16e3348a4d2
|
|
| MD5 |
b1d3ce3d411f51d485c2275f1059ab31
|
|
| BLAKE2b-256 |
27f1de6407efe9e1a15b066dae5887c5158362db634a5bd42a3a297d4f869826
|
Provenance
The following attestation bundles were made for morphsdk-0.2.5-py3-none-any.whl:
Publisher:
morphcli-publish-python-sdk.yml on morphllm/landing
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
morphsdk-0.2.5-py3-none-any.whl -
Subject digest:
2b045d1e4e55b84e4b519138767582c9e9769f0ae1147348e919f16e3348a4d2 - Sigstore transparency entry: 1948259950
- Sigstore integration time:
-
Permalink:
morphllm/landing@1ef4fed61698bdf1c3c9937aba56fa193e0e1fe0 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/morphllm
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
morphcli-publish-python-sdk.yml@1ef4fed61698bdf1c3c9937aba56fa193e0e1fe0 -
Trigger Event:
push
-
Statement type: