Code Intelligence MCP Server for 15 languages - provides semantic code search, git history, and codebase indexing with AI assistant integration
Cicada MCP demonstrates strong definition quality with well-documented tools designed for code exploration. All 7 tools have clear names starting with action verbs (query, search_*, git_history, expand_result, refresh_index, query_jq) and comprehensive descriptions ranging from 400-1500+ characters. Input schemas are present for all tools with proper JSON Schema structure including types and descriptions. However, there are notable gaps: (1) Output schemas are not explicitly documented in the tool definitions shown; (2) No error handling or recovery guidance visible in descriptions; (3) Tool composition could be tighter, query/search_module/search_function/expand_result form a redundant cluster where expand_result appears to be a convenience wrapper duplicating search_module/search_function logic; (4) Some parameter descriptions are overly verbose and include implementation details rather than user-facing guidance; (5) No visible parameter constraints (enums, ranges, patterns) in the schema definitions for critical parameters like 'scope', 'result_type', 'type', 'match_source'.
DRILL-DOWN TOOL: Expand a query result to see complete details. After discovering modules or functions with query, use this tool to explore a specific result in depth. Query results often suggest using this tool to get more details. Automatically determines whether you're expanding a module or function. For modules: Shows all functions, documentation, and structure. For functions: Shows definition, documentation, call sites, and relationships. AI USAGE TIPS: • **Primary use case:** Follow query's suggestions to expand interesting results • Copy the identifier directly from query results (e.g., 'MyApp.Auth.verify_token/2') • Type detection is automatic - no need to specify module vs function • Perfect for understanding what a result does before modifying it • Shows: full code context, relationships, usage examples • Convenience wrapper - calls search_module or search_function automatically
UNIFIED HISTORY TOOL: One tool for all git history queries - replaces get_blame, get_commit_history, find_pr_for_line, and get_file_pr_history. Smart routing based on parameters: • start_line only → single line blame + find PR • start_line + end_line → line range blame with PR enrichment • function_name → function tracking with evolution metadata • file_path only → file-level history (PRs preferred, commits fallback) Automatically uses PR index when available for enriched results. Returns compact output by default (PR number, title, author). Use verbose=true for descriptions and comments. AI USAGE TIPS: • Single line authorship: git_history(file_path='lib/auth.ex', start_line=42) • Line range blame: git_history(file_path='lib/auth.ex', start_line=40, end_line=60) • Function evolution: git_history(file_path='lib/auth.ex', function_name='create_user', show_evolution=true) • File PR history: git_history(file_path='lib/auth.ex') • Recent changes only: git_history(file_path='lib/auth.ex', recent=true) • Older changes: git_history(file_path='lib/auth.ex', recent=false) • All time: git_history(file_path='lib/auth.ex', recent=null) • By author: git_history(file_path='lib/auth.ex', author='john')
Output schemas not documented: All 7 tools describe their results in text (e.g., 'Compact results with essential info') but do not provide formal JSON Schema for return types. LLMs need structured schemas to plan downstream tool calls and extract fields reliably.
Parameter enums missing or underdocumented: Parameters like 'scope' (all|public|private), 'result_type' (all|modules|functions), 'type' (public|private|all), 'match_source' (all|docs|strings), 'usage_type' (e.g., tests) are described in text examples but lack formal enum constraints in JSON Schema. This allows LLMs to hallucinate invalid values.
No error handling or recovery guidance: Tool descriptions do not explain how to handle failure cases (e.g., 'Module not found, try wildcard search', 'Index refresh failed, check file permissions'). Error responses would not guide agents on next steps.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 68 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 31 | - | v1 |
YOUR PRIMARY TOOL - Start here for ALL code exploration and discovery. The 'Google for code' - this is your FIRST STOP for any code search task. Intelligently searches by keywords OR patterns, combines results, and suggests exactly which specialized tools to use next. Smart Auto-Detection: • Keywords: ['authentication', 'login'] → semantic search • Patterns: 'MyApp.User.create*' → pattern matching • Mixed: ['oauth', 'MyApp.Auth.*'] → combines both Power Filters: • scope: 'all' (default) | 'public' | 'private' • result_type: 'all' | 'modules' | 'functions' • match_source: 'all' | 'docs' | 'strings' (search in code strings like SQL) • recent: false (default) | true (last 14 days only) • glob: glob pattern like 'lib/auth/**' or '**/*_controller.ex' • path: base directory to search in (e.g., 'lib/auth') • type: file type shorthand (e.g., 'py', 'ex', 'ts') Returns: • Compact results with essential info (verbose=true for full details) • Smart suggestions for next steps with actual tool names to use • Match indicators: (d) docs, (s) strings, (d+s) both • Search source: (k) keyword, (s) semantic, (k+s) both (hybrid mode) AI USAGE TIPS: • **ALWAYS START HERE** - This replaces the need to choose between multiple tools • Don't ask users for module/function names - query will find them for you • Start broad: query('authentication') then follow the tool suggestions • Try patterns when you know structure: query('MyApp.*.create*') • Use filters to narrow: query('login', scope='recent', glob='lib/auth/**') • The results include smart suggestions - follow them to drill deeper • Only skip this tool if you already have exact module.function/arity identifiers Example Workflow: 1. query(['jwt', 'authentication']) → discovers relevant code + suggests next steps 2. Follow suggestion → search_function('verify_token') → see detailed usage 3. Follow suggestion → search_module('MyApp.Auth') → see complete API When NOT to use: • You already have exact identifiers like 'MyApp.User.create_user/2' • Analyzing git history for known file paths (use history tools directly) • Targeted operations on specific, already-identified code
ADVANCED: Execute jq queries directly against the Cicada index for custom analysis and data exploration. Provides direct access to the raw index structure using jq query syntax. Ideal for custom analysis, debugging index contents, and exploring data not covered by specialized tools. Index structure: {modules: {<name>: {file, line, functions[], keywords, ...}}, metadata: {...}} Quick Examples: • List all modules: '.modules | keys' • Count functions per module: '.modules[].functions | length' • Find test files: '.modules | to_entries | map(select(.value.file | test("test")))' • Get metadata: '.metadata' • Find functions by arity: '.modules[].functions[] | select(.arity == 2)' Module fields: file, line, moduledoc, functions[], keywords{}, string_keywords{}, string_sources[]
Force refresh the code index to pick up recent file changes. Use when auto-refresh hasn't caught recent edits, or when you need the index to be immediately up-to-date. By default, runs an incremental refresh (only reindexes changed files). Use force_full=true for a complete reindex if incremental seems stale. AI USAGE TIPS: • Use after making code changes if query results seem stale • Incremental refresh is fast (~1-2s for small changes) • Full refresh is slower but comprehensive • Returns: success status, time taken, module/function counts
DEEP-DIVE TOOL: Find function definitions and call sites after discovering with query. Provides function analysis: definition location and all call sites. Use this when query suggests drilling into a specific function's usage. Search by function name, optionally with module, file path, and arity: 'function_name', 'Module.function_name', 'function_name/2', or 'lib/my_app/user.ex:function_name'. Supports wildcards (*) and OR patterns (|) across function names, modules, and file paths (e.g., 'create*|update*', 'MyApp.*.create', 'lib/*/user.ex:create*'). Returns compact output by default (location + call sites). Use verbose=true for signatures and documentation. AI USAGE TIPS: • After query finds functions, use this for detailed impact analysis • Query will suggest this tool when you need to see where functions are called • Set include_usage_examples=true to see real code examples (helps understand usage patterns) • Use usage_type='tests' to see only how functions are tested • Returns: definition + ALL call sites with file:line references (add verbose=true for docs/specs) • If you see function references in code, search them to understand what they do • Call sites and line numbers are automatically truncated for popular functions (>20 sites)
DEEP-DIVE TOOL: View a module's complete API and dependencies after discovering it with query. Shows full module details: functions with arity, signatures, docs, typespecs, and line numbers. Analyze both what this module depends on (what_it_calls) and what depends on it (what_calls_it). Use this when query suggests drilling into a specific module. Supports wildcards (*) and OR patterns (|) for both module names and file paths. Examples: 'MyApp.*', '*User*', 'lib/my_app/*.ex', 'MyApp.User|MyApp.Admin'. Search by module_name='MyApp.User' or file_path='lib/my_app/user.ex'. Control visibility with type: 'public' (default), 'private', or 'all'. Returns compact output by default (name/arity only). Use verbose=true for full details. AI USAGE TIPS: • After query finds modules, use this to see the full API surface • Query will suggest using this tool when detailed module info is needed • Don't ask user for module names - use query first to discover them • Use what_calls_it=true BEFORE modifying a module to see impact (what depends on it) • Use what_it_calls=true to see what this module depends on • Returns: function list with line numbers (add verbose=true for signatures/docs) • If module not found, error will suggest alternatives - try those suggestions! • Wildcard searches are limited to 20 modules - use more specific patterns for large codebases • Output is automatically truncated for large results to prevent token overflow
Composition redundancy: expand_result duplicates search_module and search_function logic ('Automatically determines whether you're expanding a module or function'). This violates single-responsibility and forces agents to reason about when to use expand_result vs direct search tools. Either remove expand_result or rename/differentiate it clearly.
query_jq exposes internal index structure and requires jq expertise: Parameter accepts raw jq query syntax, which is low-level and not user-friendly. Tool name and description don't guide LLMs on when to use it (marked 'ADVANCED'). No validation or error guidance for malformed queries.
Missing pagination/result limit documentation: query and search_* tools mention 'compact output' or 'output is automatically truncated' but do not formally specify max result counts, pagination parameters, or how to request next page. Results truncation should be predictable.
Tool descriptions are overly verbose with implementation details: e.g., query description spans 850+ chars with extensive AI tips, wildcard syntax, and filter explanations. While helpful, this bloats tool descriptions and risks burying key intent for LLM selection. Separate concise intent from detailed usage tips.