A Model Context Protocol server providing tools to read, search, and manipulate Git repositories programmatically via LLMs
The mcp-git server uses a meta-tool architecture with discover_tools, get_tool_spec, and execute_tool as entry points. While this design offers flexibility for dynamic tool registration, it critically violates core MCP patterns: (1) tools are not directly registered with the MCP server, only discovered at runtime; (2) input schemas for the three visible tools lack proper parameter type definitions and are minimal; (3) descriptions are present but generic and don't explain when/why to use each tool; (4) the execute_tool pattern defers schema validation to the tool-specific layer, making it opaque to the LLM at tool definition time. The architecture prioritizes runtime flexibility over schema clarity, which contradicts the Arcade pattern that tools must have explicit, machine-readable schemas at registration time.
[STEP 1] Discover available Git, GitHub, and Azure DevOps tools.
[STEP 3] Execute a Git, GitHub, or Azure DevOps operation with automatic parameter validation.
[STEP 2] Get detailed schema and parameters for a specific tool.
Tools not directly registered with MCP server. The three visible tools (discover_tools, get_tool_spec, execute_tool) appear to be a wrapper around dynamic tool discovery rather than explicit MCP tool registrations. This means the LLM never sees the actual tool schemas at initialization, only a meta-interface.
Input schemas lack type definitions and constraints. The three tools have minimal parameter schemas: 'pattern' and 'tool_name' are strings, but no enums, length limits, or patterns are defined. The 'params' parameter in execute_tool is a bare 'object' with no property definitions.
Output schemas not documented. None of the three tools include a documented return type or output structure. Callers (LLMs) don't know what fields to expect, which breaks the tool chain pattern.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 49 | <=2025-11-25 | v2 |
| 2026-03-09 | D | 53 | 1.11.0+ | v1 |
Descriptions are procedural ('STEP 1', 'STEP 2', 'STEP 3') rather than functional. They don't explain WHAT each tool does, WHEN to call it, or WHY it differs from alternatives. When to use? What does it return?' The '[STEP N]' format is implementation detail that belongs in docs, not tool descriptions.
execute_tool parameter 'params' is an untyped object. LLMs cannot validate their input before calling. The description says 'Tool-specific parameters (validate with get_tool_spec first)' but this defers validation to the LLM, the tool itself should reject invalid params with a clear error message (e.g., 'Invalid status: must be one of: open, in_progress, closed').
execute_tool marked IRREVERSIBLE but description doesn't warn or require confirmation. Per pattern:confirmation-request, destructive operations should support dry-run or explicit confirmation. The tool description mentions 'automatic parameter validation' but says nothing about reversibility or safety.
Generic naming: 'execute_tool' is vague. Best practice is verb_noun (e.g., 'run_git_command', 'invoke_github_api', 'execute_git_operation'). A generic 'execute' name doesn't convey intent to the LLM.
No error handling guidance documented. Tools don't explain what errors are retryable, user-fixable, or fatal. Per pattern:recovery-guide, error responses should guide the LLM: 'User not found. Try search_users() with a partial name.' The current definitions offer no recovery paths.