Skip to main content
Glama

Local Repo MCP 1.4.0

English | 简体中文

A focused, security-oriented MCP server for exactly one configured Git repository.

Primary constraint: provide only controlled repository access, allowlisted test/build/check execution, and verifiable result return. Keep the server lightweight, single-repository, and fixed-surface; do not evolve it into an Agent, orchestration platform, or general remote shell.

Capabilities

  • Seven fixed MCP tools for file listing, UTF-8 reads, fixed-string search, filtered Git status/diff, atomic unified patches, and allowlisted verification commands.

  • Three permission modes: read, write, and test.

  • STDIO, OpenAI Secure MCP Tunnel, and Streamable HTTP transports.

  • Remote HTTP through native HTTPS/mTLS or a trusted TLS-terminating reverse proxy.

  • Bearer authentication, Host/Origin restrictions, bounded requests and outputs, sensitive-path filtering, audit records, and cross-process repository mutation locking.

  • Desktop GUI with automatic configuration persistence. STDIO uses Connect; HTTP uses Start/Stop.

  • Structured log center with MCP, Tunnel, Audit, and Security views; searchable readable summaries, raw JSON details, live refresh, credential redaction, and bounded rotation.

Related MCP server: safe-code-mcp

Start from a source checkout

Windows:

start_gui.bat

Linux/macOS:

./start_gui.sh

On headless hosts (SSH/servers) use the interactive CLI instead of the GUI:

chmod +x start_cli.sh
./start_cli.sh

The bootstrap script creates .venv and refreshes dependencies whenever requirements.txt changes.

Package entry points

pip install .
local-repo-mcp-gui
local-repo-mcp-cli
local-repo-mcp

Installed and source-checkout layouts both use the packaged mcp_app.launcher; they do not depend on a repository-root wrapper being present.

Remote HTTP

Remote HTTP is not cloud-specific. It supports self-hosted servers, VMs, containers, Kubernetes, reverse proxies, and cloud load balancers.

Use either:

  1. Native TLS with HTTP_TLS_CERTFILE and HTTP_TLS_KEYFILE; optionally set HTTP_TLS_CLIENT_CA for mTLS.

  2. A trusted TLS reverse proxy with HTTP_TLS_TERMINATED_PROXY=true, HTTP_PUBLIC_URL=https://host/mcp, and explicit HTTP_PROXY_TRUSTED_IPS.

Wildcard bindings such as 0.0.0.0 are supported, but require an HTTPS HTTP_PUBLIC_URL whose path matches HTTP_PATH.

See docs/DEPLOYMENT.md and docs/SECURITY.md.

Tests

python -m pytest -q -p no:cacheprovider

Local Repo MCP never performs checkout, reset, rebase, merge, pull, push, or amend. Local git commit is off by default and requires an explicit GUI/ALLOW_GIT_COMMIT enablement in write or test mode.

Documentation

  • Complete usage guide — installation, first launch, STDIO, Secure MCP Tunnel, Streamable HTTP, logs, testing, and troubleshooting.

  • Deployment guide — native HTTPS, mTLS, reverse proxies, systemd, containers, and Kubernetes.

  • Security model — repository boundary, HTTP controls, secrets, logs, and trusted test execution.

  • Security policy — supported security boundary and issue reporting.

Requirements

  • Python 3.11 or newer.

  • Git available on PATH.

  • One local Git working tree to expose.

  • tunnel-client only when using OpenAI Secure MCP Tunnel.

Permission modes

Mode

Read/list/search/status/diff

Apply validated patch

Optional local commit

Run allowlisted verification commands

read

Yes

No

No

No

write

Yes

Yes

Yes when enabled

No

test

Yes

Yes

Yes when enabled

Yes

Test mode executes repository code with the current operating-system user's permissions. It is not a sandbox and must be enabled only for trusted repositories.

MCP tools

Tool

Purpose

repo_list_files

List allowed files under the configured repository.

repo_read_file

Read one allowed UTF-8 text file; PNG/JPEG return as MCP image content.

repo_search_code

Perform bounded fixed-string repository search.

repo_git_status

Return filtered Git worktree status.

repo_git_diff

Return a bounded, filtered Git diff.

repo_apply_patch

Atomically apply one validated unified text patch; one patch may modify multiple files, and any target failure prevents the whole patch from applying.

repo_git_commit

Create one local Git commit for allowlisted pending changes when ALLOW_GIT_COMMIT is enabled; optional paths limits the staged set.

repo_run_test

Run one or a bounded batch of allowlisted test/build/lint/check commands in test mode and return verifiable exit/output evidence.

repo_run_test keeps its historical tool name for client compatibility while delegating execution to the controlled command layer. The default allowlist includes python_pytest, go_test, go_build, go_vet, node_test, node_build, node_lint, maven_test, maven_build, gradle_test, and gradle_build.

Use command_key for one command. Use command_keys for a sequential batch of at most 8 commands. The complete batch is allowlist-validated before the first command starts; stop_on_failure=true stops on the first failure, while false continues through the remaining commands. This is bounded in-call execution, not a queue, scheduler, or background task system.

Every started command returns normalized evidence: command identity/kind, status, success, exit_code (with compatibility returncode), stdout/stderr plus truncation flags, and duration/timeout metadata. Timeout or output-limit termination remains a structured failed result with captured output. Command lifecycle metadata is logged, but stdout/stderr are not written to runtime/audit logs.

All eight public tools publish typed MCP input and output contracts. The server relies on MCP SDK structured-output generation instead of client-specific schema patches; GUI connection verification rejects missing/invalid tool schemas before accepting a connection. Optional collection inputs are represented as optional parameters with non-null array schemas rather than nullable unions.

src/tools/contracts.py is the single protocol-contract module for the public tool surface. Protocol regressions are tested against the actual MCPServer.list_tools() result, including the fixed eight-tool surface and presence of outputSchema for every tool.

First-use workflow

  1. Start the GUI.

  2. Select the target Git working tree.

  3. Choose read, write, or test mode.

  4. Choose STDIO or Streamable HTTP.

  5. For STDIO, select Connect to verify MCP initialize, tool discovery, and repository identity.

  6. For HTTP, configure the Bearer token, select Start, and then select Connect.

  7. Copy the generated client configuration from the MCP Server page.

The complete usage guide contains the full STDIO, Tunnel, HTTP, logging, testing, and troubleshooting procedures.

ChatGPT and other MCP clients

Local Repo MCP can let ChatGPT build and maintain a local Git project within the selected permission mode. It is not limited to ChatGPT: other MCP-compatible coding agents, IDEs, desktop clients, and automation platforms can connect through STDIO or Streamable HTTP and receive the same tools and security controls.

For a new local project, select an empty directory in the GUI, explicitly confirm Git initialization, and use write or test mode. See Client compatibility and local project workflow.

Current GUI behavior: selecting a plain folder triggers a Git check and an explicit confirmation dialog. Accepting runs git init; declining leaves the folder unchanged. Initialization is never silent and does not create commits or remotes. A selected child directory inside a parent Git working tree cannot become a separate security boundary; the GUI asks to switch to the actual Git working-tree root.

Available Tools

8 tools
repo_apply_patchA

Atomically apply one validated unified text patch.

One patch may contain multiple repository text-file targets. All targets are validated before mutation and Git applies the patch as one locked operation, so a target failure does not leave a partial multi-file edit.

ParametersJSON Schema
NameRequiredDescriptionDefault
patchYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
diffYes
branchYes
appliedYes
targetsYes
warningYes
truncatedYes
repositoryYes
result_hashYes
hidden_filesYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It goes beyond the schema by explaining atomicity ('Git applies the patch as one locked operation'), validation ('All targets are validated before mutation'), and the guarantee that a target failure does not leave a partial multi-file edit. This is substantial behavioral context, though it does not address side effects like staging or committing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the primary action ('Atomically apply...'). Every sentence adds value: the first defines the operation and format, the second elaborates on multi-file atomic behavior. No redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter tool with an output schema, the description is largely complete. It covers the core behavior (atomic apply), validation, and multi-file handling. It could mention prerequisites (e.g., patch must be relative to current HEAD) or explicit return behavior, but given the output schema exists, these omissions are acceptable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one parameter 'patch' with no description (0% coverage). The description compensates by explaining that the patch is a 'unified text patch' and can contain multiple repository text-file targets. It also implies validation semantics. While it doesn't give detailed syntax, it adds meaningful meaning beyond the bare schema definition.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Atomically apply one validated unified text patch.' It identifies the specific resource (repository text files) and distinguishes it from siblings like repo_git_diff (which shows diffs) and repo_git_commit (which commits changes). The phrase 'One patch may contain multiple repository text-file targets' further clarifies scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the use case: applying a unified patch to a repository. It does not explicitly name alternatives or state when NOT to use this tool. Given siblings like repo_git_commit and repo_run_test, there is no direct comparison or exclusion. The atomicity and multi-target details provide some context, but explicit when-to-use/alternatives guidance is missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

repo_git_commitA

Create one local Git commit for allowlisted pending changes.

Disabled unless ALLOW_GIT_COMMIT is enabled (GUI: allow Git commit). Requires write or test mode. Does not push, amend, reset, rebase, checkout, or skip hooks. Sensitive paths are never staged.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathsNo
messageYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
pathsYes
branchYes
commitYes
messageYes
warningYes
committedYes
repositoryYes
hidden_pathsYes

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and covers key behavioral traits: local-only commit, no push/amend/reset/rebase/checkout/hooks, and never staging sensitive paths. It also discloses the configuration flag and mode requirement, offering comprehensive behavioral transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four short sentences with the core purpose front-loaded. Every sentence adds useful information, covering preconditions, exclusions, and security behavior with no fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, conditions, mode requirements, exclusions, and sensitive-path safety, which is substantial for a mutation tool with no annotations. The presence of an output schema accounts for return-value details, so the description is sufficiently complete for context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the description does not explain the `message` or `paths` parameters beyond general hints like 'Sensitive paths are never staged.' The message's purpose is inferable, but the paths parameter semantics remain underspecified for selecting specific changes to commit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence 'Create one local Git commit for allowlisted pending changes' uses a specific verb, resource, and scope. It clearly distinguishes this tool from sibling tools like repo_git_status and repo_apply_patch.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides preconditions (ALLOW_GIT_COMMIT enabled, write/test mode) and explicitly lists actions it does not perform (push, amend, reset, rebase, checkout, skip hooks). It gives clear context and exclusions, but does not explicitly name alternative tools for related operations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

repo_git_diffD
ParametersJSON Schema
NameRequiredDescriptionDefault
stagedNo
max_bytesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
diffYes
branchYes
truncatedYes
repositoryYes
hidden_filesYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

repo_git_statusD
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
branchYes
entriesYes
repositoryYes
hidden_entriesYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

repo_list_filesD
ParametersJSON Schema
NameRequiredDescriptionDefault
pathNo.
limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
filesYes
limitYes
truncatedYes
repositoryYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

repo_read_fileD
ParametersJSON Schema
NameRequiredDescriptionDefault
pathYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
pathYes
bytesYes
contentYes
repositoryYes
content_trustYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

repo_run_testA

Run one or more allowlisted repository verification commands.

The allowlist covers test/build/lint/check profiles for common Python, Go, Node, Maven, and Gradle repositories. command_key preserves the original single-command API. command_keys runs a bounded sequential batch; the complete batch is validated before the first command starts.

Every started command returns command, exit_code, stdout, stderr, duration and truncation metadata. Timeout/output-limit termination is a structured failed result so captured evidence is not discarded.

Commands may emit MCP_IMAGE:<repository-relative-path> lines for PNG/JPEG files under the configured test artifact directory; screenshots are returned as native MCP image content.

ParametersJSON Schema
NameRequiredDescriptionDefault
command_keyNo
command_keysNo
stop_on_failureNo
timeout_secondsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
argvNo
batchNo
imagesNo
statusYes
stderrNo
stdoutNo
commandNo
resultsNo
successYes
exit_codeNo
remainingNo
requestedNo
repositoryYes
returncodeNo
command_keyNo
duration_msYes
command_kindNo
image_warningsNo
completed_countNo
requested_countNo
stop_on_failureNo
timeout_secondsNo
stderr_truncatedNo
stdout_truncatedNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even without annotations, the description fully discloses return fields ('command, exit_code, stdout, stderr, duration and truncation metadata'), timeout behavior ('structured failed result'), and the MCP_IMAGE emission mechanism. This goes beyond annotations would typically provide and prepares the agent for unusual outcomes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured with a lead sentence defining the tool, followed by parameter-specific clarifications and behavioral details. It is moderately long but every sentence earns its place, with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there are 4 parameters, an output schema, and no annotations, the description covers the tool's purpose, parameter options, return format, timeout behavior, and image handling. It is sufficiently complete for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description compensates by explaining `command_key` vs `command_keys` and batch validation behavior. However, it does not explicitly document `stop_on_failure` and only implicitly references `timeout_seconds` via 'timeout/output-limit termination,' so it adds value for the main parameters but leaves some to inference.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Run one or more allowlisted repository verification commands,' which specifies the verb 'run' and resource 'repository verification commands.' This clearly distinguishes the tool from sibling file/git operations, as no other sibling runs commands.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the allowlist scope (test/build/lint/check for common languages) and contrasts the single-command `command_key` with the batch `command_keys`, providing clear situational usage. It doesn't explicitly state when not to use the tool, but the scope restrictions imply that arbitrary commands are not allowed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

repo_search_codeD
ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
limitYes
backendYes
matchesYes
truncatedYes
repositoryYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv1.4.0
    • Changedrepo_apply_patch5 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "RepositoryRef": {
        +    "properties": {
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "root": {
        +        "title": "Root",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "root"
        +    ],
        +    "title": "RepositoryRef",
        +    "type": "object"
        +  }
        +}
      • removedOutput schema / additionalProperties
        Removed value: -true
      • addedOutput schema / properties
        Added value: +{
        +  "applied": {
        +    "title": "Applied",
        +    "type": "boolean"
        +  },
        +  "branch": {
        +    "title": "Branch",
        +    "type": "string"
        +  },
        +  "diff": {
        +    "title": "Diff",
        +    "type": "string"
        +  },
        +  "hidden_files": {
        +    "title": "Hidden Files",
        +    "type": "integer"
        +  },
        +  "repository": {
        +    "$ref": "#/$defs/RepositoryRef"
        +  },
        +  "result_hash": {
        +    "title": "Result Hash",
        +    "type": "string"
        +  },
        +  "targets": {
        +    "items": {
        +      "type": "string"
        +    },
        +    "title": "Targets",
        +    "type": "array"
        +  },
        +  "truncated": {
        +    "title": "Truncated",
        +    "type": "boolean"
        +  },
        +  "warning": {
        +    "anyOf": [
        +      {
        +        "type": "string"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "title": "Warning"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "applied",
        +  "repository",
        +  "targets",
        +  "branch",
        +  "warning",
        +  "diff",
        +  "truncated",
        +  "result_hash",
        +  "hidden_files"
        +]
      • changedOutput schema / title
        Previous value: -"repo_apply_patchDictOutput"New value: +"ApplyPatchResult"
    • Addedrepo_git_commit
    • Changedrepo_git_diff5 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "RepositoryRef": {
        +    "properties": {
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "root": {
        +        "title": "Root",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "root"
        +    ],
        +    "title": "RepositoryRef",
        +    "type": "object"
        +  }
        +}
      • removedOutput schema / additionalProperties
        Removed value: -true
      • addedOutput schema / properties
        Added value: +{
        +  "branch": {
        +    "title": "Branch",
        +    "type": "string"
        +  },
        +  "diff": {
        +    "title": "Diff",
        +    "type": "string"
        +  },
        +  "hidden_files": {
        +    "title": "Hidden Files",
        +    "type": "integer"
        +  },
        +  "repository": {
        +    "$ref": "#/$defs/RepositoryRef"
        +  },
        +  "truncated": {
        +    "title": "Truncated",
        +    "type": "boolean"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "diff",
        +  "hidden_files",
        +  "truncated",
        +  "branch",
        +  "repository"
        +]
      • changedOutput schema / title
        Previous value: -"repo_git_diffDictOutput"New value: +"GitDiffResult"
    • Changedrepo_git_status5 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "GitStatusEntry": {
        +    "properties": {
        +      "path": {
        +        "title": "Path",
        +        "type": "string"
        +      },
        +      "status": {
        +        "title": "Status",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "status",
        +      "path"
        +    ],
        +    "title": "GitStatusEntry",
        +    "type": "object"
        +  },
        +  "RepositoryRef": {
        +    "properties": {
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "root": {
        +        "title": "Root",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "root"
        +    ],
        +    "title": "RepositoryRef",
        +    "type": "object"
        +  }
        +}
      • removedOutput schema / additionalProperties
        Removed value: -true
      • addedOutput schema / properties
        Added value: +{
        +  "branch": {
        +    "title": "Branch",
        +    "type": "string"
        +  },
        +  "entries": {
        +    "items": {
        +      "$ref": "#/$defs/GitStatusEntry"
        +    },
        +    "title": "Entries",
        +    "type": "array"
        +  },
        +  "hidden_entries": {
        +    "title": "Hidden Entries",
        +    "type": "integer"
        +  },
        +  "repository": {
        +    "$ref": "#/$defs/RepositoryRef"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "branch",
        +  "entries",
        +  "hidden_entries",
        +  "repository"
        +]
      • changedOutput schema / title
        Previous value: -"repo_git_statusDictOutput"New value: +"GitStatusResult"
    • Changedrepo_list_files5 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "RepositoryRef": {
        +    "properties": {
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "root": {
        +        "title": "Root",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "root"
        +    ],
        +    "title": "RepositoryRef",
        +    "type": "object"
        +  }
        +}
      • removedOutput schema / additionalProperties
        Removed value: -true
      • addedOutput schema / properties
        Added value: +{
        +  "files": {
        +    "items": {
        +      "type": "string"
        +    },
        +    "title": "Files",
        +    "type": "array"
        +  },
        +  "limit": {
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  "repository": {
        +    "$ref": "#/$defs/RepositoryRef"
        +  },
        +  "truncated": {
        +    "title": "Truncated",
        +    "type": "boolean"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "files",
        +  "truncated",
        +  "limit",
        +  "repository"
        +]
      • changedOutput schema / title
        Previous value: -"repo_list_filesDictOutput"New value: +"ListFilesResult"
    • Changedrepo_read_file5 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "RepositoryRef": {
        +    "properties": {
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "root": {
        +        "title": "Root",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "root"
        +    ],
        +    "title": "RepositoryRef",
        +    "type": "object"
        +  }
        +}
      • removedOutput schema / additionalProperties
        Removed value: -true
      • addedOutput schema / properties
        Added value: +{
        +  "bytes": {
        +    "title": "Bytes",
        +    "type": "integer"
        +  },
        +  "content": {
        +    "title": "Content",
        +    "type": "string"
        +  },
        +  "content_trust": {
        +    "const": "untrusted_repository_data",
        +    "title": "Content Trust",
        +    "type": "string"
        +  },
        +  "path": {
        +    "title": "Path",
        +    "type": "string"
        +  },
        +  "repository": {
        +    "$ref": "#/$defs/RepositoryRef"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "path",
        +  "bytes",
        +  "content",
        +  "content_trust",
        +  "repository"
        +]
      • changedOutput schema / title
        Previous value: -"repo_read_fileDictOutput"New value: +"ReadFileResult"
    • Changedrepo_run_test9 fields changed
      • addedInput schema / properties / command_key / default
        Added value: +""
      • addedInput schema / properties / command_keys
        Added value: +{
        +  "default": [],
        +  "items": {
        +    "type": "string"
        +  },
        +  "title": "Command Keys",
        +  "type": "array"
        +}
      • addedInput schema / properties / stop_on_failure
        Added value: +{
        +  "default": true,
        +  "title": "Stop On Failure",
        +  "type": "boolean"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "command_key"
        -]
      • addedOutput schema / $defs
        Added value: +{
        +  "CommandEvidence": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "argv": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "title": "Argv",
        +        "type": "array"
        +      },
        +      "command": {
        +        "title": "Command",
        +        "type": "string"
        +      },
        +      "command_key": {
        +        "title": "Command Key",
        +        "type": "string"
        +      },
        +      "command_kind": {
        +        "enum": [
        +          "test",
        +          "build",
        +          "lint",
        +          "check"
        +        ],
        +        "title": "Command Kind",
        +        "type": "string"
        +      },
        +      "duration_ms": {
        +        "title": "Duration Ms",
        +        "type": "integer"
        +      },
        +      "exit_code": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "title": "Exit Code"
        +      },
        +      "returncode": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "title": "Returncode"
        +      },
        +      "status": {
        +        "enum": [
        +          "success",
        +          "failed",
        +          "timeout",
        +          "output_limit"
        +        ],
        +        "title": "Status",
        +        "type": "string"
        +      },
        +      "stderr": {
        +        "title": "Stderr",
        +        "type": "string"
        +      },
        +      "stderr_truncated": {
        +        "title": "Stderr Truncated",
        +        "type": "boolean"
        +      },
        +      "stdout": {
        +        "title": "Stdout",
        +        "type": "string"
        +      },
        +      "stdout_truncated": {
        +        "title": "Stdout Truncated",
        +        "type": "boolean"
        +      },
        +      "success": {
        +        "title": "Success",
        +        "type": "boolean"
        +      },
        +      "timeout_seconds": {
        +        "title": "Timeout Seconds",
        +        "type": "integer"
        +      }
        +    },
        +    "required": [
        +      "command_key",
        +      "command_kind",
        +      "argv",
        +      "command",
        +      "status",
        +      "success",
        +      "exit_code",
        +      "returncode",
        +      "stdout",
        +      "stderr",
        +      "stdout_truncated",
        +      "stderr_truncated",
        +      "timeout_seconds",
        +      "duration_ms"
        +    ],
        +    "title": "CommandEvidence",
        +    "type": "object"
        +  },
        +  "ImageMetadata": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "mime_type": {
        +        "enum": [
        +          "image/png",
        +          "image/jpeg"
        +        ],
        +        "title": "Mime Type",
        +        "type": "string"
        +      },
        +      "path": {
        +        "title": "Path",
        +        "type": "string"
        +      },
        +      "size": {
        +        "title": "Size",
        +        "type": "integer"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "mime_type",
        +      "size"
        +    ],
        +    "title": "ImageMetadata",
        +    "type": "object"
        +  },
        +  "RepositoryRef": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "root": {
        +        "title": "Root",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "root"
        +    ],
        +    "title": "RepositoryRef",
        +    "type": "object"
        +  }
        +}
      • addedOutput schema / description
        Added value: +"Wire contract for repo_run_test structuredContent.\n\nThe command tool has two result shapes (single and bounded batch) and may\nattach image metadata. Common fields are explicit while mode-specific fields\nremain optional. Extra fields stay allowed so the execution layer can evolve\nevidence without silently dropping data from direct CallToolResult responses."
      • addedOutput schema / properties
        Added value: +{
        +  "argv": {
        +    "anyOf": [
        +      {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Argv"
        +  },
        +  "batch": {
        +    "anyOf": [
        +      {
        +        "type": "boolean"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Batch"
        +  },
        +  "command": {
        +    "anyOf": [
        +      {
        +        "type": "string"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Command"
        +  },
        +  "command_key": {
        +    "anyOf": [
        +      {
        +        "type": "string"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Command Key"
        +  },
        +  "command_kind": {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "test",
        +          "build",
        +          "lint",
        +          "check"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Command Kind"
        +  },
        +  "completed_count": {
        +    "anyOf": [
        +      {
        +        "type": "integer"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Completed Count"
        +  },
        +  "duration_ms": {
        +    "title": "Duration Ms",
        +    "type": "integer"
        +  },
        +  "exit_code": {
        +    "anyOf": [
        +      {
        +        "type": "integer"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Exit Code"
        +  },
        +  "image_warnings": {
        +    "anyOf": [
        +      {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Image Warnings"
        +  },
        +  "images": {
        +    "anyOf": [
        +      {
        +        "items": {
        +          "$ref": "#/$defs/ImageMetadata"
        +        },
        +        "type": "array"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Images"
        +  },
        +  "remaining": {
        +    "anyOf": [
        +      {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Remaining"
        +  },
        +  "repository": {
        +    "$ref": "#/$defs/RepositoryRef"
        +  },
        +  "requested": {
        +    "anyOf": [
        +      {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Requested"
        +  },
        +  "requested_count": {
        +    "anyOf": [
        +      {
        +        "type": "integer"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Requested Count"
        +  },
        +  "results": {
        +    "anyOf": [
        +      {
        +        "items": {
        +          "$ref": "#/$defs/CommandEvidence"
        +        },
        +        "type": "array"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Results"
        +  },
        +  "returncode": {
        +    "anyOf": [
        +      {
        +        "type": "integer"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Returncode"
        +  },
        +  "status": {
        +    "enum": [
        +      "success",
        +      "failed",
        +      "timeout",
        +      "output_limit"
        +    ],
        +    "title": "Status",
        +    "type": "string"
        +  },
        +  "stderr": {
        +    "anyOf": [
        +      {
        +        "type": "string"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Stderr"
        +  },
        +  "stderr_truncated": {
        +    "anyOf": [
        +      {
        +        "type": "boolean"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Stderr Truncated"
        +  },
        +  "stdout": {
        +    "anyOf": [
        +      {
        +        "type": "string"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Stdout"
        +  },
        +  "stdout_truncated": {
        +    "anyOf": [
        +      {
        +        "type": "boolean"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Stdout Truncated"
        +  },
        +  "stop_on_failure": {
        +    "anyOf": [
        +      {
        +        "type": "boolean"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Stop On Failure"
        +  },
        +  "success": {
        +    "title": "Success",
        +    "type": "boolean"
        +  },
        +  "timeout_seconds": {
        +    "anyOf": [
        +      {
        +        "type": "integer"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "default": null,
        +    "title": "Timeout Seconds"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "status",
        +  "success",
        +  "repository",
        +  "duration_ms"
        +]
      • changedOutput schema / title
        Previous value: -"repo_run_testDictOutput"New value: +"VerificationResultModel"
    • Changedrepo_search_code5 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "RepositoryRef": {
        +    "properties": {
        +      "name": {
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "root": {
        +        "title": "Root",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "root"
        +    ],
        +    "title": "RepositoryRef",
        +    "type": "object"
        +  },
        +  "SearchMatch": {
        +    "properties": {
        +      "line": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "title": "Line"
        +      },
        +      "path": {
        +        "title": "Path",
        +        "type": "string"
        +      },
        +      "text": {
        +        "title": "Text",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "line",
        +      "text"
        +    ],
        +    "title": "SearchMatch",
        +    "type": "object"
        +  }
        +}
      • removedOutput schema / additionalProperties
        Removed value: -true
      • addedOutput schema / properties
        Added value: +{
        +  "backend": {
        +    "enum": [
        +      "ripgrep",
        +      "python"
        +    ],
        +    "title": "Backend",
        +    "type": "string"
        +  },
        +  "limit": {
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  "matches": {
        +    "items": {
        +      "$ref": "#/$defs/SearchMatch"
        +    },
        +    "title": "Matches",
        +    "type": "array"
        +  },
        +  "repository": {
        +    "$ref": "#/$defs/RepositoryRef"
        +  },
        +  "truncated": {
        +    "title": "Truncated",
        +    "type": "boolean"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "matches",
        +  "truncated",
        +  "backend",
        +  "limit",
        +  "repository"
        +]
      • changedOutput schema / title
        Previous value: -"repo_search_codeDictOutput"New value: +"SearchCodeResult"
  2. 7 tool updatesv0.1.0
    • First observedrepo_apply_patch
    • First observedrepo_git_diff
    • First observedrepo_git_status
    • First observedrepo_list_files
    • First observedrepo_read_file
    • First observedrepo_run_test
    • First observedrepo_search_code

TDQS

C2.7/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct operation: listing files, reading files, searching code, checking git status, viewing diffs, applying patches, committing, and running tests. No two tools have overlapping purposes, making selection unambiguous.

Naming Consistency5/5

All tools follow a consistent `repo_` prefix with verb_noun snake_case naming (e.g., list_files, read_file, git_status, run_test). The pattern is uniform and predictable across the entire set.

Tool Count5/5

Eight tools is well-scoped for a local repository MCP server, covering file exploration, git inspection, patch application, committing, and testing without excess. Each tool serves a clear purpose.

Completeness4/5

The surface covers the core workflow: explore files, inspect git state, modify via patch, commit, and run verification commands. Minor gaps exist such as git log/history and branch management, but the primary workflow is complete and patch-based editing covers file modifications.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers