Text Editor for AI Agents
Project description
Carve
Text Editor for AI Agents
Carve lets AI agents edit code structurally instead of rewriting entire files. It parses source code into a tree-sitter AST, exposes navigation and mutation tools over MCP or HTTP, and regenerates source files from the tree.
Install
pip install carve-server
Install with language grammars:
# Individual languages
pip install "carve-server[python]"
pip install "carve-server[javascript]"
# All supported languages
pip install "carve-server[all]"
Supported: Python, JavaScript, HTML, CSS, JSON, Markdown, TOML, YAML, Bash, Jinja.
Quick Start (MCP)
Add to Claude Code with one command:
claude mcp add carve -- carve serve --mcp
Or add to your MCP client config manually:
{
"mcpServers": {
"carve": {
"command": "carve",
"args": ["serve", "--mcp", "--path", "/path/to/your/project"]
}
}
}
Or run directly:
carve serve --mcp --path ./my-project
The agent can then navigate and edit code through Carve's tool interface.
Quick Start (HTTP)
carve serve --http --path ./my-project --port 8080
Import a file, explore its structure, make a surgical edit:
# See the tree structure
curl -X POST http://127.0.0.1:8080/tree/subtree \
-H "Content-Type: application/json" \
-d '{"node_id": "module", "depth": 2}'
# Inspect a specific function
curl -X POST http://127.0.0.1:8080/tree/inspect \
-H "Content-Type: application/json" \
-d '{"node_id": "module::MyClass::my_method"}'
# Update just that function
curl -X POST http://127.0.0.1:8080/tree/update \
-H "Content-Type: application/json" \
-d '{
"node_id": "module::MyClass::my_method",
"snippet": "def my_method(self, x):\n return x * 2"
}'
# Write changes to disk
curl -X POST http://127.0.0.1:8080/project/serialize \
-H "Content-Type: application/json" \
-d '{}'
How It Works
Source file → Tree-sitter AST → In-memory tree store → Tools → Regenerated source
Carve parses source files into a tree of named nodes with hierarchical IDs like module::Calculator::add. Agents navigate with subtree, search, and inspect, then make targeted edits with insert, update, and delete — down to individual statements. When done, project_serialize writes the tree back to disk.
This means an agent can change one line inside a method without seeing or rewriting the rest of the file.
Tools
| Tool | Description |
|---|---|
subtree |
Navigate tree structure from any node |
ancestors |
Get the path from a node up to root |
inspect |
Read a node's full source and metadata |
search |
Find nodes by name pattern and/or type |
find_references |
Cross-file dependency tracing |
insert |
Add new code at a specific position |
update |
Replace a node's implementation |
delete |
Remove a node |
move |
Relocate a node in the tree |
batch |
Apply multiple mutations in one pass |
ts_query |
Run tree-sitter S-expression queries |
project_import |
Load a file or directory |
project_serialize |
Write the tree back to source files |
error_locate |
Map stack traces to node IDs |
checkpoint / undo / redo |
Version control for mutations |
Configuration
carvesettings.toml
Drop a carvesettings.toml in your project root to configure formatters, custom tools, and language mappings.
workspace = "."
sidecars = true
[formatters]
python = "ruff format --quiet {file}"
javascript = "prettier --write {file}"
[tools]
test = "uv run pytest {args}"
lint = "uv run ruff check carve/ {args}"
typecheck = "uv run mypy carve/"
[language_map]
".djhtml" = "jinja"
".j2" = "jinja"
[import_map]
jinja = "tree_sitter_jinja"
formatters — Run after every disk write. {file} is replaced with the file path. Keyed by language name.
tools — Custom shell commands exposed as MCP tools (prefixed with run_). Placeholders like {args} become tool parameters. Requires --allow-custom-tools to enable.
sidecars — When true (default), Carve writes .crv sidecar files (see below). Set to false to disable.
workspace — Default project path. Also settable via CARVE_WORKSPACE env var.
language_map — Map file extensions to language names, extending the built-in defaults.
import_map — Map language names to tree-sitter grammar module names.
.carveignore
Controls which files are included when importing a directory. Uses gitignore-style patterns. Without this file, all supported files are included.
# Common defaults
.git/
__pycache__/
*.egg-info/
.venv/
node_modules/
dist/
build/
# Carve metadata
*.crv
# Project-specific
*.db
*.png
.crv Sidecar Files
Every time Carve mutates a source file, it appends an entry to a .crv JSON file next to it (e.g. app.py.crv). This is an audit trail of AI-driven changes:
[
{
"operation": "update",
"node_id": "Calculator::add",
"timestamp": "2026-02-13T18:30:00+00:00",
"model": "claude-opus-4-6",
"prompt": "Simplify the add method",
"notes": "Removed type annotations per user request"
}
]
Each entry records what changed, when, which model did it, and why. This metadata is restored when you re-import the file, so inspect shows the prompt and model that last touched each node.
To disable: set sidecars = false in carvesettings.toml. To keep them out of version control, add *.crv to your .gitignore.
CLI Options
carve serve --mcp # MCP server on stdio
carve serve --http # HTTP server (default port 8080)
--path DIR # Project directory or file to load
--port 8080 # HTTP port
--host 127.0.0.1 # HTTP host
--read-only # Block all mutations
--no-create # Block new file creation
--no-delete # Block file/directory deletion
--allow-custom-tools # Enable tools from carvesettings.toml
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 carve_server-0.1.1.tar.gz.
File metadata
- Download URL: carve_server-0.1.1.tar.gz
- Upload date:
- Size: 173.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1025149f9c736d5e9ce32e24dc5723ed67b53c987b1f5bc02cf1931806acd7d
|
|
| MD5 |
d653823f279b62b22e501d8f04470415
|
|
| BLAKE2b-256 |
05818b832abe04015b7de04f8a71e4497dddb715f89f3f4129a8b5c773a22956
|
File details
Details for the file carve_server-0.1.1-py3-none-any.whl.
File metadata
- Download URL: carve_server-0.1.1-py3-none-any.whl
- Upload date:
- Size: 57.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6eeb2aa9c1eeb76794f4ffe7734216dc66ff6fc0397b9f12400c897e244d5c9
|
|
| MD5 |
84003a3d1b1560310da7c9c2d59ff2d9
|
|
| BLAKE2b-256 |
c25561a659a8fe5ba342f570a675d67f4ed3b7419ce4059761c0fb41986040cd
|