Git
Generated automatically at build time from the madtea repository - do not edit here. Source: docs/reference/cli-git.md.
Foreign-checkout immutability model (madt_fetch, madt_pull, madt_worktrees): ADR 0019. Credential injection model (GIT_ASKPASS, never token-in-URL): ADR 0013.
CLI Commands
madtea add
Stage files for commit
madtea branch
Create, list, or delete local branches
| Flag | Type | Default | Description |
|---|---|---|---|
--base | string | Start-point ref/sha to branch from (with -b; default: current HEAD) | |
--create | bool | false | Create and checkout a new branch |
--delete | bool | false | Delete a merged branch (safe; madtea never force-deletes) |
--issue | int | 0 | Link branch to Forgejo/Gitea issue number |
--list | bool | false | List branches |
madtea checkout
Switch branches
| Flag | Type | Default | Description |
|---|---|---|---|
--branch | bool | false | Create and checkout a new branch |
madtea cherry-pick
Apply the changes introduced by some existing commits
| Flag | Type | Default | Description |
|---|---|---|---|
--abort | bool | false | Abort the current cherry-pick |
--continue | bool | false | Continue after resolving conflicts |
--no-commit | bool | false | Apply changes without committing |
madtea clone
Clone a repository
| Flag | Type | Default | Description |
|---|---|---|---|
--bare | bool | false | Create a bare repository |
--branch | string | Clone specific branch | |
--depth | int | 0 | Create a shallow clone with specified depth |
madtea commit
Create a commit
| Flag | Type | Default | Description |
|---|---|---|---|
--allow-default-branch | bool | false | Permit committing on the repository’s default branch (refused by default — an unplanned default-branch commit is almost always a wrong-checkout accident) |
--message | stringArray | [] | Commit message (can be specified multiple times) |
madtea diff
Show changes between commits, working tree, etc.
| Flag | Type | Default | Description |
|---|---|---|---|
--staged | bool | false | Show staged changes |
--stat | bool | false | Show diffstat only |
madtea fetch
Download objects and refs from another repository
| Flag | Type | Default | Description |
|---|---|---|---|
--all | bool | false | Fetch from all remotes |
--prune | bool | false | Prune remote-tracking branches no longer on remote |
--tags | bool | false | Fetch all tags |
madtea log
Show commit logs
| Flag | Type | Default | Description |
|---|---|---|---|
--graph | bool | false | Show ASCII graph of branches |
--grep | string | Limit to commits whose message matches the pattern (git log –grep) | |
--max-count | int | 10 | Number of commits to show |
--oneline | bool | false | Show each commit on one line |
--regexp-ignore-case | bool | false | Match the –grep pattern case-insensitively |
--unreleased | bool | false | Show commits since the latest local tag ( |
madtea merge
Join two or more development histories together
| Flag | Type | Default | Description |
|---|---|---|---|
--abort | bool | false | Abort the current merge |
--continue | bool | false | Continue after resolving conflicts |
--message | string | Merge commit message | |
--no-ff | bool | false | Create a merge commit even when fast-forward is possible |
--squash | bool | false | Squash commits into one |
madtea pull
Fetch from and integrate with another repository or local branch
| Flag | Type | Default | Description |
|---|---|---|---|
--rebase | bool | false | Rebase instead of merge |
madtea push
Push branch or tags using tea credentials
| Flag | Type | Default | Description |
|---|---|---|---|
--force | bool | false | Force push using –force-with-lease |
--tags | bool | false | Push tags instead of branches |
madtea rebase
Reapply commits on top of another base tip
| Flag | Type | Default | Description |
|---|---|---|---|
--abort | bool | false | Abort the rebase |
--continue | bool | false | Continue after resolving conflicts |
--skip | bool | false | Skip the current patch |
madtea remote add
Add an authenticated Forgejo/Gitea remote to an existing repo
| Flag | Type | Default | Description |
|---|---|---|---|
--name | string | origin | Remote name |
madtea reset
Reset current HEAD to the specified state
| Flag | Type | Default | Description |
|---|---|---|---|
--mixed | bool | false | Unstage changes (default) |
--soft | bool | false | Keep changes staged |
madtea revert
Revert some existing commits
| Flag | Type | Default | Description |
|---|---|---|---|
--no-commit | bool | false | Don’t automatically commit |
madtea stash
Stash the changes in a dirty working directory away
| Flag | Type | Default | Description |
|---|---|---|---|
--include-untracked | bool | false | Include untracked files |
--keep-index | bool | false | Keep staged changes in index |
--message | string | Stash message |
madtea status
Show working tree status
| Flag | Type | Default | Description |
|---|---|---|---|
--branch-commits | bool | false | Opt-in: also list the commits the current branch carries ahead of mainline ( |
--glob | string | Opt-in working-tree file inventory: comma-separated glob patterns, matched by full repo-relative path if the pattern contains ‘/’ (e.g. “internal/cmd/admin/”), otherwise by base name (e.g. “.go”, “.go,.md”, or “*” for all). Omit to skip the inventory. |
madtea tag
Create, list, delete, or verify a tag object
| Flag | Type | Default | Description |
|---|---|---|---|
--annotate | bool | false | Create an annotated tag |
--delete | bool | false | Delete a tag |
--force | bool | false | Replace existing tag |
--message | string | Tag message (implies -a) | |
--push | bool | false | Push tag to remote after creating |
madtea worktree add
Add a new worktree (checks out an existing ref; -b creates a branch)
| Flag | Type | Default | Description |
|---|---|---|---|
--branch | string | Create a new branch in the worktree (git worktree add -b) | |
--force | bool | false | Force operation (override path-exists check) |
madtea worktree list
List worktrees
madtea worktree prune
Clean up stale worktree administrative files
madtea worktree rebase
Rebase a worktree’s branch onto a base ref (refuses primary checkout)
| Flag | Type | Default | Description |
|---|---|---|---|
--onto | string | Base branch/ref to rebase the worktree’s branch onto (defaults to the forge default branch) |
madtea worktree remove
Remove a worktree (refuses dirty/locked; no force override)
madtea worktree status
Batch commit-clean report across all linked worktrees
MCP Tools
madt_add
Stage files in a repository’s working tree (git add), returning the resulting staged file list. This is the staging step before madt_finish — use it instead of shelling out to raw git add. Name the paths in files=[…] (a single string, comma-separated, or an array; a directory such as ‘src/’ or ‘.’ counts as a deliberate known-scope declaration). There is NO blanket “stage everything” mode (the removed all=true/git add -A): declare the paths you mean, so a stray build artifact can never be swept in. Defaults to the repo at the server’s working directory; pass dir to target a sibling repo in a multi-repo workspace, or any OTHER repo on disk.
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to stage in, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
files | []string | string | no | Paths to stage (files or directories, e.g. [‘docs/’, ‘main.go’]). Accepts a single string, a comma-separated string, or an array. Required — there is no blanket “stage everything” mode (the removed all/git add -A); a directory such as ‘src/’ or ‘.’ counts as a deliberate known-scope declaration. |
raw_json | boolean | no | Return raw JSON ({“staged”:[…]}) instead of the formatted text line. |
madt_branch_create
Create AND check out a LOCAL feature branch (git checkout -b) — the start of feature work — instead of shelling out to raw git checkout -b, which silently lands in the WRONG repo in a multi-repo workspace because the MCP server’s working directory is fixed at launch and cannot follow an agent’s cd. Branches from the CURRENT HEAD by default; pass base=<ref/sha> to branch from an explicit start-point instead (e.g. base=“main” or base=“origin/main” to branch off the mainline regardless of what is checked out). This is purely local: NO remote contact (to create a branch on the REMOTE via the API, use madt_branches_remote action=create). Pass dir to target an explicitly-named sibling repo in the workspace, or any OTHER repo on disk; omit it to use the server’s working directory. A dir= pointing at the PRIMARY checkout of a FOREIGN repo (outside the server’s own working directory) is refused — moving a foreign primary’s HEAD is shared-state clobber; create a linked worktree with madt_worktrees action=add instead (the sanctioned foreign-repo writable surface; see madt_help topic=worktrees). When the server’s working directory is itself NOT a git repo (a session launched in a plain parent dir that merely contains clones), a repo whose toplevel is strictly UNDER that dir is in-scope, not foreign, and is NOT refused. A LINKED WORKTREE of a foreign repo is writable: refused only when the tree has modified or staged tracked-file changes (a new branch must never carry a stranger’s uncommitted work onto it). After this, edit → madt_commit (stages + commits in one call), then madt_finish (or madt_push + madt_prs for a review-only PR).
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
base | string | no | Start-point ref or sha to create the new branch FROM (e.g. “main”, “origin/main”, a commit sha). Defaults to the CURRENT HEAD when omitted — this is a purely local git checkout -b, so it does NOT default to the repo’s remote default branch; pass base=origin/ |
branch | string | yes | Branch name to create and check out. |
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to create the branch in, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
raw_json | boolean | no | Return raw JSON ({“action”:…,“name”:…,“checkedOut”:…,“headSHA”:…}) instead of the formatted text line. headSHA is the short HEAD SHA immediately after checkout (empty string if the post-checkout rev-parse failed). |
madt_branch_delete
Delete a MERGED local branch (git branch -d). SAFE by design: it refuses a branch with unmerged commits — madtea NEVER force-deletes (there is no -D path). To re-sync a feature branch with its updated base, use madt_pull rebase=true; do NOT delete-and-recreate the branch. This is purely LOCAL (no remote contact): to delete a branch on the REMOTE use madt_branches_remote action=delete, and for bulk cleanup of branches already merged into the default branch use madt_prune. Pass dir to target an explicitly-named sibling repo in a multi-repo workspace; omit it to use the server’s working directory.
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
branch | string | yes | Local branch to delete (must be merged; this is git branch -d, NOT -D). |
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to delete the branch in, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
raw_json | boolean | no | Return raw JSON ({“action”:…,“name”:…}) instead of the formatted text line. On a REFUSAL (raw_json=true) it returns a structured (non-error) object {refused:true, reason, cherry_equivalent, tree_identical, likely_squash_merged, ahead_unique, escape_hatch} so agents branch on fields instead of prose. |
madt_commit
Record an intermediate/checkpoint commit in ONE call: it stages the chosen changes, commits them, and confirms the result — branch @ short hash plus file/line stats — collapsing the raw-git git add && git commit && git rev-parse dance. Two modes: files=[…] stages those paths then commits; omit files to commit only what is ALREADY staged (e.g. the subset you just placed with madt_add). There is NO blanket “stage everything” mode (the removed all=true/git add -A): declare the paths you mean in files=[…]. DEFAULT-BRANCH GUARD: a commit while HEAD is this repo’s own default branch is REFUSED (almost always a wrong-checkout accident) — branch first with madt_branch_create, or pass allow_default_branch=true to commit there deliberately; an empty/bootstrap repo (no HEAD) and a merge/revert/cherry-pick completion are exempt structurally. Cherry-pick / precise-subset flow — commit exactly the changes you choose, even when the tree has more: madt_status (see the staged / unstaged / untracked files) → madt_add files=[…] (stage just the subset you want) → madt_commit (omit files → commits exactly that staged subset). Nuance (SAME-repo target only): madt_commit files=[x] is git add x then git commit, so the commit also includes anything ALREADY staged — it is NOT a pathspec-isolated git commit -- x. For an exact subset while other changes are staged, use the stage-then-commit-only-staged flow above. This is purely LOCAL (no remote contact) and is for MID-BRANCH work: the returned short hash and branch are authoritative, so there is no need to re-run git log/show/status to confirm the commit. COMPLETING AN IN-PROGRESS merge/revert/cherry-pick: after you resolve the conflicts and stage them with madt_add, call madt_commit (files may be omitted — the resolutions are already staged) to record the merge/revert/cherry-pick commit; this is the sanctioned completion in place of raw git merge/revert/cherry-pick --continue, and it works both in your own repo and in a linked worktree of a foreign repo (a foreign PRIMARY checkout, and a rebase/git-am/bisect in progress, stay refused). Contrast: madt_finish COMPLETES a branch (commit+push+PR+merge) — finishing NOW with an uncommitted tree? Skip this call and pass files=[…] to madt_finish directly instead (one call, not this-then-no_commit); reach for madt_commit only for MID-FLOW checkpoints, then madt_finish (or madt_push for a review-only PR) when done. Defaults to the repo at the server’s working directory; pass dir to commit in a sibling repo in a multi-repo workspace, or any OTHER repo on disk. A dir= pointing at the PRIMARY checkout of a FOREIGN repo is refused outright (even with files=) — the primary’s tree and HEAD are shared state the caller does not own; use a linked worktree of that repo as the commit target instead (see madt_help topic=worktrees). A LINKED WORKTREE of a foreign repo MUST name files=[…] explicitly for an ordinary commit — the implicit staged-only mode is refused there (implicit staging could sweep up a stranger’s own uncommitted work), and a target mid-rebase/git-am/bisect is refused too (a rebase/am is not concluded by a commit); a mid-merge/revert/cherry-pick is the exception — it is COMPLETED as described above (files may be omitted). UNLIKE the same-repo nuance above, an ordinary foreign linked-worktree commit IS pathspec-isolated to exactly files=[…] (git’s own commit -- <files> default), so it can never sweep in something else already staged — also stage a foreign worktree target with madt_add files=[…] only. A same-repo dir (including a linked worktree of THIS repo) is unaffected. For the parallel-agent worktree flow — commit each checkpoint with dir=
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
allow_default_branch | boolean | no | Per-call override permitting a commit while HEAD is the repository’s own default branch (refused by default — an unplanned default-branch commit is almost always a wrong-checkout accident). Never read from git config. An empty/bootstrap repo (no HEAD) is exempt structurally and needs no override. |
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to commit in, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
files | []string | string | no | Paths to stage before committing (files or directories, e.g. [‘docs/’, ‘main.go’]). Accepts a single string, a comma-separated string, or an array. Omit to commit only what is ALREADY staged. There is no blanket “stage everything” mode (the removed all/git add -A) — name the paths you mean. |
message | string | yes | Commit message (the summary line, e.g. ‘feat: add rate limiting’). Required. |
raw_json | boolean | no | Return raw JSON (hash, shortHash, branch, message, filesChanged/insertions/deletions) instead of the formatted confirmation line. |
madt_fetch
Update remote-tracking refs from origin (git fetch) with authenticated credentials — use it instead of shelling out to raw git fetch, which can leak a credentialed remote URL’s token. This is the READ-SIDE primitive that freshens a repo’s origin/
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to fetch in, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. Unlike madt_pull, dir may point at the PRIMARY checkout of a foreign repo — fetch updates remote-tracking refs only (no working-tree or branch mutation), so it is safe on a checkout you do not own. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
raw_json | boolean | no | Return raw JSON (remote, refs, pruned, summary) instead of the formatted text line. |
remote | string | no | Remote to fetch from (default “origin”). Use this to freshen a non-default remote’s tracking refs. |
madt_log
Search and read LOCAL commit history (git log), with action=list. Its headline use is COMMIT-MESSAGE SEARCH: pass grep to limit the output to commits whose message matches a pattern — use this instead of shelling out to raw git log --grep "..." or git log | grep .... This MUST be local git, not madt_commits: the forge commits API has NO message filter, so message search only exists here. grep takes a regex (POSIX basic by default); add regexp_ignore_case=true for git’s case-insensitive -i. Optional sha logs from a revision range or start ref (e.g. HEAD~5..HEAD, a branch, a tag, or a remote-tracking ref); limit caps the count (default 10); oneline/graph control the display. sha with limit=1 also RESOLVES a single ref to its commit (full hash, author, date, message) — use it instead of raw git rev-parse/git log -1 <ref>. MAINLINE ORIENTATION without a checkout: sha=‘origin/main’ limit=3 shows the last 3 commits on the remote mainline WITHOUT switching branches — the one-call orient that replaces raw git log --oneline -3 main. unreleased=true is the one-call release-prep sugar: it finds the latest local tag and logs everything since it (
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | no | action: list (the only action; defaults to list when omitted). |
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to read the log from, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
graph | boolean | no | Draw the ASCII branch/merge graph alongside the commits (git log –graph). |
grep | string | no | Limit to commits whose COMMIT MESSAGE matches this pattern (git log –grep, POSIX basic regex by default). This is the message/grep search — the reason to use this tool instead of madt_commits (the forge commits API has no message filter). |
limit | integer | no | Maximum number of commits to return (git log -n). Defaults to 10 when omitted — except with unreleased=true, where an omitted limit is UNCAPPED (every commit since the latest tag, not just the last 10). |
oneline | boolean | no | Compact one-line-per-commit display (the default text rendering already shows short-hash + subject per line). |
raw_json | boolean | no | Return raw JSON (commits[] with hash/shortHash/author/email/date/message, plus range/grep/since) instead of the formatted one-line-per-commit text. |
regexp_ignore_case | boolean | no | Match the grep pattern case-insensitively (git’s own -i / –regexp-ignore-case flag). Only meaningful together with grep. |
sha | string | no | Optional revision range or start ref to log from (e.g. HEAD~5..HEAD, a branch, or a commit SHA). Mirrors madt_commits’ sha start filter. Omit to log from HEAD. Pass a single ref with limit=1 to RESOLVE that ref to its commit (full hash, author, date, message) instead of shelling out to raw git rev-parse. Mutually exclusive with unreleased. |
unreleased | boolean | no | One-call release-prep sugar: resolves the latest local tag and logs everything since it (equivalent to sha=" |
madt_pull
Fetch and integrate remote changes into the current branch (git pull) with authenticated credentials — use it instead of shelling out to raw git pull. If the pull fails because the remote’s DEFAULT branch was renamed (your branch tracks a ref the remote no longer has), madtea auto-repairs the common case: it confirms the new default via the forge API, renames your local branch to match, re-tracks it, and re-runs the fast-forward pull. When it cannot do so safely — histories diverged, the target branch name is already taken, or the API is unreachable — it changes NOTHING and returns the exact commands to fix it by hand. Pass rebase=true for git pull --rebase. To re-base your CURRENT branch onto an updated base, use rebase=true instead of a raw git rebase <base> (for a linked worktree, use madt_worktrees action=rebase); a rebase=true pull on a branch with NO upstream returns a clear error naming the branch and the fix, rather than a silent no-op. Defaults to the repo at the server’s working directory; pass dir to pull a sibling repo in a multi-repo workspace. A dir= pointing at the PRIMARY checkout of a FOREIGN repo is refused — a pull rewrites its checked-out branch and working tree, which the caller does not own; pull against a foreign LINKED WORKTREE (the caller’s own, created via the worktree flow) is allowed. When the server’s working directory is itself NOT a git repo (a session launched in a plain parent dir that merely contains clones), a repo whose toplevel is strictly UNDER that dir is in-scope, not foreign, and is NOT refused. With dir, the pull uses the configured forge credentials against the dir repo’s OWN origin remote — the credential is supplied by GIT_ASKPASS, host-scoped so it is only ever offered to the configured forge host.
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to pull into, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. dir only selects WHICH local repo; the fetch still goes through madtea’s authenticated path. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
raw_json | boolean | no | Return raw JSON (branch, remote, fastForward, commitsMerged, conflicts, summary, repaired/renamedFrom/renamedTo, oldSha/newSha, newBranches, diffstatText, filesChanged/insertions/deletions, recentCommits) instead of the formatted text line. |
rebase | boolean | no | Rebase the current branch onto the upstream instead of merging (git pull –rebase). |
madt_push
Push a branch to origin with authenticated credentials (defaults to the current branch) — use it instead of shelling out to raw git push, which can leak a credentialed remote URL’s token. This is the publish step for intermediate work and the prerequisite for madt_prs action=create: the head branch must exist on the remote before a PR can be opened from it. Review-only PR flow (no merge): madt_commit → madt_push → madt_prs action=create draft=true. NOT needed before madt_finish — finish pushes itself. Defaults to the repo at the server’s working directory; pass dir to push a sibling repo in a multi-repo workspace, or any OTHER repo on disk. A dir= target OUTSIDE the server’s own repo (a foreign repo) requires branch= explicitly — no falling back to whatever happens to be checked out in a repo madtea does not own; a same-repo dir is unaffected. With dir, the push uses the configured forge credentials against the dir repo’s OWN origin remote — the credential is supplied by GIT_ASKPASS, host-scoped so it is only ever offered to the configured forge host.
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
branch | string | no | Branch to push (defaults to the current branch). |
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to push from, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. dir only selects WHICH local repo; the push still goes through madtea’s authenticated path. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
force | boolean | no | Force push using –force-with-lease (refuses to overwrite remote commits you haven’t fetched). |
raw_json | boolean | no | Return raw JSON ({“branch”:…,“remote”:…}) instead of the formatted text line. |
madt_ref_inspect
Inspect a LOCAL git ref — including one that exists ONLY locally (unpushed commits), which the forge-API tools (madt_files, madt_commits, madt_search, madt_git_objects) cannot see at all. Action-dispatched (tree / grep / show / diff / checkout_state), mirroring the raw git ls-tree / git grep / git cat-file / git diff / git ls-files an agent would otherwise shell out to when auditing an unpushed branch. Read-only and purely LOCAL: no remote contact, no credentials, no mutation. Defaults to the repo at the server’s working directory; pass dir to target a sibling repo in a multi-repo workspace.
Actions (set action to one of):
checkout_state — Report working-tree checkout-state signals the forge API cannot see: files deleted on disk (git ls-files –deleted), skip-worktree files (git ls-files -v), and sparse-checkout patterns (git sparse-checkout list) — e.g. action=checkout_state. Non-sparse reports sparseCheckoutEnabled=false, not an error.
contains — Ancestry check (git merge-base –is-ancestor): is ref an ancestor of in? — e.g. action=contains, ref=‘issue-42-fix’, in=‘main’. The post-rebase / pre-finish ‘did my branch land on the base?’ verification. Reports contained yes/no; both refs may be local-only. Required: “ref”, “in”.
diff — Diff a ref against the WORKING TREE (to omitted) or another ref (to set): name-status rows by default, or –stat summary text (stat=true) — e.g. action=diff, from=‘my-local-branch’, or from=‘HEAD~3’, to=‘my-local-branch’. paths narrows the diff. Distinct from the CLI-only madtea diff (full patches).
grep — Search file CONTENT at a ref (git grep) — e.g. action=grep, pattern=‘TODO’, ref=‘my-local-branch’. Omit ref for HEAD. ignore_case mirrors git -i; count switches to per-file match counts (git grep -c); paths narrows the search. No match is a successful empty result, not an error. Required: “pattern”.
show — Read one file’s raw content at a ref (git cat-file -p :
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | no | Which local-ref read to run: tree (list tree contents at a ref), grep (search file content at a ref), show (read one file’s raw content at a ref), diff (working-tree-vs-ref or ref-vs-ref diff), checkout_state (deleted/skip-worktree/sparse-checkout signals), or contains (ancestry check: is ref an ancestor of in?). Defaults to tree when omitted. |
count | boolean | no | For grep: report a per-file match COUNT (git grep -c) instead of per-line matches. |
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to read from, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
from | string | no | For diff: the base ref to diff FROM (a branch, tag, or commit SHA — including one that exists ONLY locally, unpushed). Omit for HEAD. |
ignore_case | boolean | no | For grep: match pattern case-insensitively (git grep’s own -i flag). |
in | string | no | For contains: the branch or ref that should CONTAIN ref (e.g. ‘main’) — contains reports whether ref is a SHA-ancestor of in. The post-rebase / pre-finish verification target. |
path | string | no | For show: the file path (relative to the repo root) to read at ref, e.g. ‘internal/cmd/admin/admin.go’. |
paths | []string | string | no | For tree/grep/diff: narrow the read to specific files or directories (pathspecs), e.g. [‘go.mod’,‘cmd’]. Accepts a single string, a comma-separated string, or an array. Omit to read the whole tree/repo. |
pattern | string | no | For grep: the search pattern (a POSIX basic regex by default, matching git grep’s own pattern syntax) to look for in file content at ref. |
raw_json | boolean | no | Return raw JSON instead of formatted text. The formatted text shows the full content — titles, bodies, and comments are complete, not previewed — so do not re-fetch with raw_json to check for truncation; use raw_json only when you need machine-readable fields (ids, URLs, timestamps, full hashes). |
recursive | boolean | no | For tree: expand into subdirectories instead of listing only the top level of the tree (git ls-tree -r). |
ref | string | no | For tree/grep/show/contains: the git ref to read (or, for contains, to test) — a branch, tag, or commit SHA, including one that exists ONLY locally (unpushed commits), which the forge API cannot resolve at all. Omit for HEAD on tree/grep/show; required for contains. |
stat | boolean | no | For diff: return a raw –stat summary (file | changes, insertions/deletions) instead of the default per-file name-status rows. |
to | string | no | For diff: the ref to diff ‘from’ against. Omit to diff ‘from’ against the WORKING TREE instead of another ref. |
madt_remote_add
Add an authenticated Forgejo/Gitea remote to an existing local git repo. Looks up the repo on Forgejo/Gitea, adds the remote, and configures per-repo credentials. The repo must already exist on Forgejo/Gitea — create it first with madt_repos action=create. (For bootstrapping a brand-new project from scratch — a directory with no commits — use madt_init instead.)
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | no | Remote name (default: origin) |
owner_repo | string | yes | Repository in owner/repo format |
madt_status
Show a repository’s working-tree status: the forge owner/repo identity (parsed from the remote, no credentials), branch, HEAD short sha, upstream tracking (ahead/behind), mainline-behind count (how many commits the current branch is behind origin/git log --oneline -3 main for agents), and the staged, unstaged (including deletions), untracked, and conflicted files. HEAD short sha is omitted (non-fatally) when the repo has no commits yet. mainlineBehind/mainlineRef are omitted on the default branch or when origin/git fetch (origin, ~2s timeout) so ahead/behind + mainlineBehind reflect fresh refs; on timeout/failure it falls back to cached refs with remoteStale/remoteWarning (never the remote URL), never blocking or erroring. No origin → skipped, not stale. latestTag/commitsSinceTag report the release cadence — the latest reachable tag and the number of commits on HEAD since it (computed LOCAL-only, no network); both are omitted when the repo has no tags. On a feature branch mainlineCommitsSinceTag gives the release-from-main count, and branch_commits=true adds branchCommits (commits ahead of mainline, git branch + git status + git rev-parse. This is the inspect/choose-what-to-commit tool: read the separated staged / unstaged / untracked lists here, then madt_add files=[…] the subset you want and madt_commit it (the cherry-pick flow). Pass glob=’.go’ to also get an opt-in working-tree file inventory in the same call — replaces a separate git ls-files + filter. A pattern containing ‘/’ is path-scoped against the full repo-relative path (e.g. glob=‘internal/cmd/admin/’ lists one package’s files, ‘internal/opspec/spec_.go’ combines a directory scope with a base-name pattern); a pattern with no ‘/’ matches by base name across the whole tree, unchanged (e.g. ‘.go’ matches every Go file). A pattern with no glob metacharacters is an existence check for that base name or exact path (e.g. glob=‘go.mod’). Large listings are capped, not silently truncated — filesTruncated=true means narrow the glob. Also use it to confirm which repo madt_* target and to inspect what madt_add staged before madt_finish. Defaults to the repo at the server’s working directory; pass dir to inspect a sibling repo in a multi-repo workspace.
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
branch_commits | boolean | no | Opt-in: ‘branchCommits’ lists the commits the current branch carries ahead of mainline ( |
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to inspect, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
glob | string | no | Opt-in working-tree file inventory. When set, the response includes a ‘files’ list of every tracked and untracked file in the local checkout that git can see (respects .gitignore). The value is a comma-separated list of filepath.Match glob patterns matched against each file’s base name — e.g. ‘.go’ (Go sources only), ‘.go,.md’ (Go + Markdown), or ‘’ (every file). Omit the parameter entirely to skip the inventory (the default, keeping the call token-cheap). This lists the LOCAL checkout on disk; it is NOT the remote Gitea API — use madt_files for remote content. |
raw_json | boolean | no | Return raw JSON (branch, head sha, ahead/behind, mainlineBehind/mainlineRef, staged/unstaged/untracked/conflicts, latestTag/commitsSinceTag + feature-branch mainlineCommitsSinceTag, optional files inventory and branchCommits) instead of the formatted text line. |
madt_tag_list
List LOCAL git tags, version-sorted newest-first (git tag –sort=-version:refname) — the standard pre-release “what’s the latest tag” read, so an agent never shells out to raw git tag --sort=-v:refname. This is purely LOCAL (no remote contact, no credentials): remote tag CRUD lives on the separate madt_tags tool (requires madt_enable(domains=[“tags”])), a different concern. Each row is a tag name plus the short commit sha it resolves to — annotated tags are peeled past the tag object to the underlying commit. To resolve a tag to its FULL commit sha, use madt_log sha=
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to list tags from, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted. The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
raw_json | boolean | no | Return raw JSON (tags[] with name/commit) instead of the formatted “name @ sha” one-line-per-tag text. |
madt_worktrees
Manage git worktrees (linked working trees) over MCP, action-dispatched (list / status / add / remove / rebase / prune) — mirroring the madtea worktree CLI. This is the SANCTIONED way to set up and tear down per-task worktrees for parallel agent work, so you never shell out to raw git worktree remove + git switch after madt_finish. Batch the commit-clean check before finishing/cleanup with action=status, and rebase a worktree’s branch onto an updated base with action=rebase, instead of a raw cd <wt> && git status/git rebase loop. SAFETY: remove refuses a dirty or locked worktree and madtea offers NO force override for it on any surface — discarding uncommitted work or overriding a deliberate lock is unrecoverable, so there is no force= on action=remove. Commit or stash first, or (if the work is genuinely disposable) the user runs git worktree remove <path> --force themselves in their own shell. madtea NEVER escalates privileges and NEVER runs a recursive filesystem delete (no sudo, no rm -rf); the only sanctioned metadata cleanup stays inside git via prune. For the commit-in-worktree → finish-from-mainline flow, see madt_help(topic=“worktrees”). Purely LOCAL: no remote contact, no credentials. Defaults to the repo at the server’s working directory; pass dir to target a sibling repo/worktree in a multi-repo workspace.
Actions (set action to one of):
add — Create a linked worktree for parallel work (git worktree add) — e.g. action=add, path=’.worktrees/feat’, branch=‘feat’ checks out a new branch in its own directory. Pass force=true to reuse a branch already checked out elsewhere. Required: “path”.
list — List the repo’s linked worktrees with their paths, branches, and HEAD shas (git worktree list) — e.g. action=list. Read-only and unguarded. Pass dir to inspect a sibling repo in a multi-repo workspace.
prune — Prune administrative metadata for worktrees whose directory is already gone (git worktree prune) — e.g. action=prune. The only sanctioned stale-metadata cleanup; it stays inside git, never a recursive filesystem delete. Pass dir to target a sibling repo.
rebase — Rebase a NAMED worktree’s branch onto an updated base. Two forms: dir=git worktree remove --force themselves. Never sudo/rm -rf. Foreign: only session-created worktrees. Required: “path”.
status — Batch commit-clean report across the repo’s worktrees in ONE call — per worktree: path, branch, HEAD short-sha, clean/dirty (porcelain), ahead/behind — e.g. action=status. A read (unguarded): the pre-finish/pre-cleanup check, replacing a cd <wt> && git status loop. Pass dir for a sibling repo.
Output schema: declared
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | no | Which worktree operation to run: list (the worktrees attached to the repo), status (batch commit-clean report across all worktrees — HEAD, clean/dirty, ahead/behind — the pre-finish/pre-cleanup check), add (create a new linked working tree), remove (delete a linked working tree), rebase (rebase a named worktree’s branch onto an updated base), or prune (clear stale worktree registrations). Mirrors the madtea worktree CLI subcommands; defaults to list when omitted. |
branch | string | no | For add: the branch to check out in the new worktree. If the branch does not exist it is created (git worktree add -b); if it exists it is checked out. Omit to detach at the current HEAD. |
dir | string | no | Optional absolute or workspace-relative path to a LOCAL git repo/worktree to operate on, for multi-repo workspaces where the MCP server’s launch-fixed working directory is NOT the repo you mean. Defaults to the server’s working directory when omitted (rebase REQUIRES dir — it targets a named worktree, never the cwd checkout). The path is validated strictly: resolved and required to be an existing git repository. There is no workspace-roots confinement — dir accepts any absolute path that resolves to a git repo, in or out of the current workspace. |
force | boolean | no | For add ONLY: reuse a branch already checked out elsewhere or a registered path (git worktree add -f). It creates a working tree and destroys nothing — git still refuses to overwrite a non-empty non-worktree directory. There is NO force on action=remove: madtea will not force-discard a DIRTY or LOCKED worktree (unrecoverable), so removing one is refused with a message that names raw git for the user to run in their own shell. |
onto | string | no | For rebase: the base branch or ref to rebase the worktree’s branch ONTO (e.g. onto=“main” replays the worktree’s commits on top of the freshly-updated main). Required for rebase. |
path | string | no | Filesystem path of the linked working tree. Required for add (where the new checkout is created, e.g. ‘.worktrees/feature’) and remove (the worktree to delete, e.g. ‘.worktrees/feature’). A leading-dash path is treated as a positional, never a git flag. |
raw_json | boolean | no | Return raw JSON (action plus the worktrees list; for status the per-worktree commit-clean report; for rebase the rebased/conflict result; otherwise the added/removed/pruned worktree) instead of the formatted text line. |
Canonical source: docs/reference/cli-git.md in the madtea repo.