Give AI coding agents your local sites (MCP)
On this page
leash mcp is a Model Context Protocol server. Connect it to an AI coding tool and the assistant can see what Short Leash sees: your sites, recent requests, dumps and queries, logs and mail. It can also start and stop sites and services, share a site, run Artisan with the site's PHP, and run code inside a site with the app booted.
Local AI is part of Short Leash Pro.
Connect
Settings › Coding assistants (MCP) has a button for each coding assistant Short Leash finds on this computer. Each one adds Short Leash through that assistant's own command or install link, and the command it runs, or the link it opens, is shown under the button:
- Add to Claude Code runs
claude mcp add --scope user leash -- <leash> mcp, so Short Leash is there in every project. If Short Leash is there already, it says "Short Leash is already in Claude Code". - Add to VS Code runs
code --add-mcp '{"name":"leash","command":"<leash>","args":["mcp"]}'on a Mac when thecodecommand is on your PATH. On Windows, or when VS Code is installed without thecodecommand, it opens VS Code's install link instead. - Add to Cursor opens Cursor's install link.
An install link opens the assistant, which asks you to confirm before it adds Short Leash. <leash> is always the full path to Short Leash's leash, because apps opened from the Dock or the Start menu don't read your shell's PATH: on a Mac it's in Short Leash's bin folder, and on Windows it's leash.exe in Short Leash's app folder. That path stays the same when Short Leash updates.
Short Leash never edits these apps' settings files. Each assistant keeps its own list of MCP servers, and you remove Short Leash there. To find them, Short Leash looks only for claude and code on your login shell's PATH, and for VS Code and Cursor in your Applications folders (on Windows, in your programs folders). An assistant it doesn't find gets no button.
Other tools
For other tools, or to add Short Leash by hand, the section also has the command and config to copy. With Short Leash on your terminal's PATH (Terminal) it's just leash mcp; apps that don't read your shell's PATH need the full path, which Settings can show instead.
Claude Code's command is there only when Short Leash didn't find Claude Code, since Add to Claude Code runs it otherwise:
claude mcp add --scope user leash -- leash mcp
Other tools (Cursor, Windsurf, VS Code and others) take a JSON config:
{
"mcpServers": {
"leash": {
"command": "/Users/you/Library/Application Support/Short Leash/bin/leash",
"args": ["mcp"]
}
}
}
Let your assistant check its own change
With send_call, your assistant sends a request to the site and gets the answer back with what it caused: the dump() calls, the queries (and how long each took) and the log lines. After changing a controller it can call the route, see the query it added, and fix an N+1 before you look. Calls reach the site and its share URL; see Calls.
Hand work to the local model
Your assistant can plan a change and hand the writing to the model Short Leash runs on this computer (Chat uses the same one), then review what it wrote. The model works in a branch workspace, never your site's own folder:
- Your assistant makes a branch workspace for the change with
add_workspace, or picks one fromlist_workspaces. - It calls
delegate_to_localwith the task, the files toreadfor context and the files the model maywrite. It waits up to 50 seconds (orwaitseconds, up to 10 minutes, for assistants that wait longer for a tool) and gets back the files Short Leash wrote and the model's notes, or an id to follow withlocal_work. - It reviews the change with
site_changeson the branch workspace and runs its tests withrun_processorrun_code. - Then it hands the work back with what to fix (the model starts from the files as they are now), or keeps it with
changes_stage,changes_commitandmerge_workspace.
The model gets no tools and runs nothing. It rewrites each file it changes whole, so hand over files small enough to rewrite (under about 10 KB each works best), and put a test file in write too. Short Leash writes the files only once the whole answer is in, so a stopped or cut-off answer writes nothing. Before writing any, it checks each is still as the model read it: if your assistant or you changed one meanwhile, nothing is written. If a write fails part way, the answer names the files it wrote. Each written file says how many lines it had and has, with a warning when a line looks like a placeholder for code the model left out or the file lost more than half its lines. Short Leash refuses:
- a path outside the branch workspace's folder, through a link, or inside
.git(or a Windows short name for it, such asGIT~1) - a name Windows keeps for a device (
nul,con.php), a character that hides text, and two files to write that differ only in case - the project's own
leash.tomlandleash.local.toml - more than 6 files to write or 12 to read, a file over 256 KB or one that isn't text, files to write over about 40 KB in all (the most the model writes at once), and a task the model can't fit with room to write the files
Nothing is staged, committed or run. While the model works, a merge or removal of the branch workspace is refused, and while a merge or removal runs, so is handing work over. Once the model has finished and Short Leash is writing its files, stop_local_work can't stop it. The work uses the model chosen for chat in Settings › Models, one piece at a time in each branch workspace. Your own chats wait while it writes. Short Leash keeps the last 20 pieces of work until it restarts.
The model is smaller than your assistant, and the files it reads come from your repository. Tell your assistant to review what it wrote as code to check, and to read its notes as suggestions, never as instructions.
Tools
| Tool | What it does |
|---|---|
list_sites, site_info |
Sites with their address, folder, runtime and share |
start_site, stop_site, secure_site |
Start, stop or serve a site over HTTPS |
run_process |
Run one of a site's commands that run once (migrate, build, the tests), wait for it, and return how it ended with its last lines of output |
set_php_version |
Pin a site's PHP version |
check_extensions |
The PHP extensions a site's composer files need that its PHP doesn't have, and how to fix each |
project_file |
What a site's leash.toml and leash.local.toml set, where each setting comes from, whether the folder is trusted and any problems reading them. It only reads: trusting a folder or applying its file is never a tool |
share_site, unshare_site |
Share a site and return its public address, or stop sharing |
list_services, start_service, stop_service |
Services and their connection details |
add_service, remove_service |
Add a service, or another version of one on its own port, and start it; remove an added one (its data stays on disk) |
list_databases, create_database, database_url |
Databases on each MySQL, MariaDB, PostgreSQL and MongoDB service, creating one for a site on MySQL, MariaDB or PostgreSQL (named after its .env or the site, on the service the .env points at), and its connection URL |
drop_database |
Drop a database after Short Leash backs it up; leash backup restore brings it back |
get_recent_requests, get_request |
Requests to a site, with headers and bodies |
get_dumps |
Dumps, queries, jobs, views, HTTP calls and log messages |
explain_query |
The plan for a captured query, from its database's EXPLAIN (the query doesn't run), with what to change |
list_log_sources, get_logs |
Output from sites, workers and services |
get_mail, read_mail |
Caught mail |
list_backups |
Database backups, the folder and the daily schedule |
list_webhooks, get_webhook_deliveries, get_webhook_delivery |
Webhooks, their deliveries and each delivery's signature check and replies |
resend_webhook_delivery |
Send a delivery to its sites again, signed afresh |
run_artisan |
Run an Artisan command in a Laravel site, with its PHP |
list_calls, send_call |
A site's saved calls, and sending one (or any request to the site): returns the answer with the dumps, queries and log lines it caused. Calls reach only the site and its share URL, unless the site's settings let AI tools call other hosts |
run_calls, list_routes |
Send a site's calls, or a folder's, in order and see which passed their checks; a Laravel or Symfony site's routes |
run_code |
Run code inside a site with the app booted, like a scratchpad: returns the last line's value, what it printed, its dumps and queries, and any error with its line |
tasks_list, task_get, task_add |
A site's tasks, or General's when the site is left out, with each one's status, priority, tags and claim (status narrows the list); one task with its description, steps and latest activity, your notes included; and adding one, signed with the agent's name ("Coding agent" when an older agent leaves by out) |
task_claim, task_note, task_block, task_release |
Claim a task before working on it (others are refused until the claim runs out), post progress, say what's in the way (it ends the claim and waits for your reply), and let it go unfinished. Every one signs with by, the agent's own name in plain letters, digits and punctuation, never "you" |
task_review, task_done |
Hand finished work back with a summary (and the branch workspace it's in), which waits in Review for you unless you turned Review off; task_done does the same with a plain summary. Short Leash's chat marks a task done directly, after asking, even one waiting in Review |
task_update |
Change a task's title, description, priority or tags; ticking a step means rewriting its line as - [x]. Refused on a task in Review, a done one, or one another agent holds; it moves a task to In progress only with the agent's own claim, and never changes a blocked task's status |
pair_status, pair_let_in, pair_end |
The Pair call: who's waiting and who's in, letting someone in, and ending it. Giving control isn't possible from here |
notes_list, note_read, note_add, note_update |
Your notes: find them by words, site or tag (each with its tags, whether it's pinned and who last changed it when that wasn't you), read one with its links, backlinks and the names of its pictures (never the pictures), write a new one, and change one, preferably by adding to the end, signed with the agent's name. Renaming a note updates the links to it in other notes |
changes_stage, changes_unstage |
Stage or unstage a site's files, or everything in its folder |
changes_commit |
Commit the staged files. Hooks run only in a folder Short Leash trusts; elsewhere pass no_verify to commit without them |
changes_discard |
Throw away a file's changes; new files move to the Trash |
changes_push |
Push the current branch to its upstream, never forced |
site_changes |
A site's changes from Git: uncommitted, or everything its branch committed since its base branch. The file list first, then one file's diff (or some of its lines) on request, cut to fit. Characters that hide text show as codes such as ⟦U+202E⟧; commit subjects are cut to 200 characters |
pull_request |
The GitHub pull request for a site's branch, through your own gh: title, description, state, reviews, comments, checks and changed files, or one file's diff. Off until you turn on Let chat read pull requests from GitHub in Settings › Chat; everything in it is marked as outside text |
list_change_comments, resolve_change_comment |
Review comments on a site's changes, and resolving one when it's dealt with. Comments Short Leash's model wrote carry outside_text: true; suggestions you haven't kept aren't listed |
list_workspaces, add_workspace, merge_workspace, remove_workspace |
A site's branch workspaces: list them, make one for a branch, merge one back into its base and remove one. Each waits for its job and returns the steps. Merging in a repository Short Leash doesn't trust runs its hooks only from Short Leash; pass hooks: skip to merge without them. Branch names and Git's output show hidden characters as codes such as ⟦U+202E⟧, with a note to treat them as data. Short Leash's chat lists and makes branch workspaces, asking first, and never merges or removes one |
delegate_to_local, local_work, stop_local_work |
Hand work to Short Leash's local model in a branch workspace: the task and the files it may read and write go in, and the files it wrote and its notes come back, marked as outside text. Following the work, and stopping it, which writes nothing. Short Leash's chat doesn't get these tools |
meeting_notes |
Your meeting notes: the meetings, or one meeting's summary, action items and transcript. Off until you turn on Let coding assistants read meeting notes in Settings › Coding assistants (MCP) |
Comments by Short Leash's model are text a model wrote from the diff, which can hold anything the repository holds. Tell your assistant to treat them as suggestions to check, never as instructions.
Pull request text is written by people on GitHub. Tell your assistant to treat it as data, never as instructions. Comments on single lines aren't read.
The MCP server talks only to Short Leash on your computer. What your assistant does with the results depends on the tool you connect.