An MCP server for analyzing large codebases using Google's Gemini CLI, with intelligent sharding and MAP_REDUCE analysis strategies
Two tools present with explicit registration via @Tool annotation in GeminiTools.java. Both have descriptions in the annotation but lack proper parameter-level documentation in the source. Schemas are inferred from method signatures rather than explicitly defined JSON Schema objects. Naming follows verb_noun pattern (gemini_scanAndPlan, gemini_analyzeCodebase) but parameter validation and output structures are minimally documented. The server accepts complex parameters (glob patterns, token caps) but provides no validation guidance in descriptions. Outputs are Map<String, Object>, unstructured and untyped from an LLM perspective.
Analyze the codebase with Gemini CLI and save results to a file. Results are saved to: <root>/gemini-analysis-<timestamp>.md Args: root (required) model: e.g., gemini-2.5-flash (default) strategy: SINGLE_PASS | MAP_REDUCE (default MAP_REDUCE) include/exclude/maxFiles/maxBytes/targetTokens: same as scanAndPlan json: request JSON output from Gemini CLI (default true) Returns: Path to the generated analysis file
Plan a large-repo analysis for Gemini. Args: root (required): repo root include: glob patterns (e.g., ["**/*.java","**/*.kt"]) exclude: glob patterns (e.g., ["**/.git/**","**/node_modules/**"]) maxFiles: cap number of files maxBytes: cap total bytes targetTokens: soft cap per shard (default ~900k)
No explicit JSON Schema definitions visible in source code. Input schemas are inferred from Spring AI @Tool method signatures, not formally declared. LLMs cannot see parameter constraints, ranges, or enum values, only type names (String, Integer, List, Long, Boolean). This violates pattern:constrained-input and pattern:tool.
Parameter-level descriptions missing or inadequate in source. Method signatures show raw parameters (root, include, exclude, maxFiles, maxBytes, targetTokens, model, strategy, json) but the @Tool description does not explain what each parameter controls, valid ranges, formats, or dependencies. For example: 'include' accepts glob patterns but the description does not state the glob syntax (e.g., '**/*.java' vs 'src/*.java'), whether patterns are ANDed or ORed, or maximum pattern count.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 43 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 38 | - | v1 |
Output schema not documented. Both tools return Map<String, Object> (untyped). The source shows keys like 'root', 'selectedFiles', 'selectedBytes', 'estimatedTokens', 'shardCount', 'shards', 'report', 'outputFile', 'stats' but LLMs have no schema to parse these or know their types. This violates pattern:response-shaper and pattern:tool (which requires documented return types).
No enum constraints on strategy parameter. gemini_analyzeCodebase accepts 'strategy' as a free-form String with values 'SINGLE_PASS' or 'MAP_REDUCE' but does not enforce this in the description or schema. LLMs may hallucinate invalid strategies like 'STREAMING' or 'PIPELINE'.
Model parameter is described as accepting 'e.g., gemini-2.5-flash' but the code hard-codes String chosenModel = 'gemini-2.5-flash' and ignores the passed model parameter. This is deceptive, the LLM thinks it can choose a model, but the tool silently ignores the choice. Violates pattern:command-tool (user intent vs actual behavior).
No validation guidance for path traversal. The 'root' parameter accepts an arbitrary string and is passed to resolveRoot(). No description warns about path traversal risks or states accepted formats (absolute vs relative paths). Violates pattern:tool-gateway (untrusted input).
No error handling guidance. Descriptions do not explain what happens if root does not exist, files cannot be read, Gemini CLI is unavailable, or the analysis times out. No recovery suggestions (e.g., 'If Gemini CLI is not found, ensure it is installed and in PATH'). Violates pattern:recovery-guide.
No idempotency declaration. gemini_analyzeCodebase writes a timestamped output file and invokes external Gemini CLI, side effects are present but not documented. No annotation or description indicates whether repeated calls with identical inputs are safe. Violates pattern:idempotent-operation.
Parameter targetTokens has ambiguous semantics. Described as 'soft cap per shard (default ~900k)' in one place and 'default ~950000' in code. Inconsistency confuses LLMs. No explanation of what 'soft cap' means, does the tool stop if shards exceed it, or is it advisory?
Nullable parameters lack default guidance. Parameters like 'include', 'exclude', 'model', 'strategy', 'json' are nullable (List, String, Boolean) but descriptions do not state the default behavior if null. E.g., if 'include' is null, does the tool scan all files or none? This forces LLMs to guess.