# MCP Tools Documentation
This document provides comprehensive documentation for the four MCP tools exposed by Dynamic Grounding for GitHub Copilot.
## Overview
All tools are built using the MCP (Model Context Protocol) and integrate with Google's Gemini AI to provide intelligent code analysis and search capabilities. Each tool returns results along with quota status information to help track API usage.
## Tool Handlers
### 1. search_codebase
**Purpose:** Search through code files using natural language queries.
**Use Cases:**
- Find implementations of specific patterns
- Locate error handling code
- Search for API usages
- Discover similar code sections
**Input Schema:**
```json
{
"query": "string (required)",
"files": [
{
"path": "string (required)",
"content": "string (required)"
}
]
}
```
**Output Schema:**
```json
{
"query": "original search query",
"files_searched": "number of files searched",
"results": "structured search results with file paths, line numbers, explanations, and code snippets",
"quota_status": "current API quota status message"
}
```
**Example Request:**
```json
{
"query": "Find all async functions that make HTTP requests",
"files": [
{
"path": "src/api.rs",
"content": "use reqwest::Client;\n\nasync fn fetch_data() -> Result<String> {\n let client = Client::new();\n let response = client.get(\"https://api.example.com\").send().await?;\n Ok(response.text().await?)\n}"
},
{
"path": "src/client.rs",
"content": "async fn download(url: &str) -> Vec<u8> {\n reqwest::get(url).await.unwrap().bytes().await.unwrap().to_vec()\n}"
}
]
}
```
**Example Response:**
```json
{
"query": "Find all async functions that make HTTP requests",
"files_searched": 2,
"results": "Found 2 async functions making HTTP requests:\n\n1. **src/api.rs:3** - `fetch_data()`\n - Uses reqwest::Client for GET requests\n - Proper error handling with Result return type\n ```rust\n async fn fetch_data() -> Result<String> {\n let client = Client::new();\n let response = client.get(\"https://api.example.com\").send().await?;\n Ok(response.text().await?)\n }\n ```\n\n2. **src/client.rs:1** - `download()`\n - Uses reqwest::get convenience function\n - Note: Uses unwrap() which could panic\n ```rust\n async fn download(url: &str) -> Vec<u8> {\n reqwest::get(url).await.unwrap().bytes().await.unwrap().to_vec()\n }\n ```",
"quota_status": "Quota OK: 14/15 RPM (93%), 1450/1500 RPD (97%)"
}
```
---
### 2. analyze_files
**Purpose:** Analyze relationships and dependencies across multiple files to answer questions about code architecture and design.
**Use Cases:**
- Understand how components interact
- Discover dependency relationships
- Analyze data flow between modules
- Identify architectural patterns
**Input Schema:**
```json
{
"question": "string (required)",
"files": [
{
"path": "string (required)",
"content": "string (required)"
}
]
}
```
**Output Schema:**
```json
{
"question": "original question",
"files_analyzed": "number of files analyzed",
"analysis": "detailed analysis with relationships, dependencies, and answer",
"quota_status": "current API quota status message"
}
```
**Example Request:**
```json
{
"question": "How does the quota tracker prevent API rate limit violations?",
"files": [
{
"path": "src/quota.rs",
"content": "pub struct QuotaTracker {\n rpm_window: RollingWindow,\n rpd_window: RollingWindow,\n}\n\nimpl QuotaTracker {\n pub fn check_quota(&self) -> Result<QuotaStatus> {\n let rpm_usage = self.rpm_window.count();\n if rpm_usage >= 14 { /* block */ }\n Ok(QuotaStatus { ... })\n }\n}"
},
{
"path": "src/gemini.rs",
"content": "pub struct GeminiClient {\n quota_tracker: Arc<QuotaTracker>,\n}\n\nimpl GeminiClient {\n pub async fn generate_content(&self, prompt: &str) -> Result<Response> {\n let status = self.quota_tracker.check_quota()?;\n // Make API call\n }\n}"
}
]
}
```
**Example Response:**
```json
{
"question": "How does the quota tracker prevent API rate limit violations?",
"files_analyzed": 2,
"analysis": "The quota tracker prevents rate limit violations through a multi-layered approach:\n\n**Architecture:**\n1. **QuotaTracker** maintains rolling time windows for RPM and RPD limits\n2. **GeminiClient** holds an Arc reference to QuotaTracker for shared state\n\n**Prevention Mechanism:**\n1. Before each API call, `generate_content()` calls `check_quota()`\n2. The quota checker counts recent requests in rolling windows\n3. If usage >= 14 RPM (93% of 15 RPM limit), it blocks further requests\n4. Returns an error to prevent the API call from proceeding\n\n**Key Design Decisions:**\n- Uses Arc for thread-safe sharing across async tasks\n- Proactive blocking at 93% to provide safety margin\n- Check happens synchronously before async API call\n- Rolling windows automatically expire old entries\n\nThis design ensures the client never exceeds Google's limits, trading some throughput for reliability.",
"quota_status": "Quota OK: 13/15 RPM (87%)"
}
```
---
### 3. ask_about_code
**Purpose:** Ask questions about specific code sections with provided context to get detailed explanations.
**Use Cases:**
- Explain how a function works
- Understand complex algorithms
- Clarify API usage patterns
- Learn about code conventions
**Input Schema:**
```json
{
"context": "string (required) - code snippet or context",
"question": "string (required)"
}
```
**Output Schema:**
```json
{
"question": "original question",
"answer": "detailed explanation based on context",
"quota_status": "current API quota status message"
}
```
**Example Request:**
```json
{
"context": "impl Drop for SecureString {\n fn drop(&mut self) {\n unsafe {\n let bytes = self.inner.as_bytes_mut();\n for b in bytes {\n std::ptr::write_volatile(b, 0);\n }\n }\n }\n}",
"question": "Why is this Drop implementation using unsafe code and write_volatile?"
}
```
**Example Response:**
```json
{
"question": "Why is this Drop implementation using unsafe code and write_volatile?",
"answer": "This `Drop` implementation for `SecureString` uses unsafe code to securely erase sensitive data from memory:\n\n**Why unsafe?**\nTo get mutable access to the string's internal bytes, we need `as_bytes_mut()`, which requires unsafe because it could violate Rust's borrowing rules if the String is shared.\n\n**Why write_volatile?**\n`write_volatile` prevents compiler optimizations from removing the zeroing operation. Without it, the compiler might optimize away the zeroing as \"dead code\" since the memory is about to be freed anyway. Using `write_volatile` guarantees the memory is actually overwritten with zeros.\n\n**Security Purpose:**\nThis ensures that sensitive data (like API keys) is erased from RAM before deallocation, preventing:\n- Memory dumps from exposing secrets\n- Other processes reading freed memory\n- Swap files containing sensitive data\n\nThis is a common pattern for handling cryptographic keys and passwords where you want to ensure the data doesn't linger in memory after use.",
"quota_status": "Quota OK: 12/15 RPM (80%)"
}
```
---
### 4. summarize_directory
**Purpose:** Get a high-level overview of a directory's structure, purpose, architecture, and key components.
**Use Cases:**
- Onboard to new codebases
- Understand project organization
- Identify entry points
- Discover main functionality
**Input Schema:**
```json
{
"directory_structure": "string (required) - tree-like structure",
"files": [
{
"path": "string (required)",
"content": "string (required)"
}
]
}
```
**Output Schema:**
```json
{
"directory": "original directory structure",
"files_included": "number of files analyzed",
"summary": "comprehensive overview with architecture, components, patterns, and entry points",
"quota_status": "current API quota status message"
}
```
**Example Request:**
```json
{
"directory_structure": "src/\n main.rs\n lib.rs\n api_key.rs\n gemini.rs\n quota.rs\n mcp_server.rs\n tools.rs\n error.rs",
"files": [
{
"path": "src/lib.rs",
"content": "pub mod api_key;\npub mod gemini;\npub mod quota;\npub mod mcp_server;\npub mod tools;\n\npub use gemini::GeminiClient;"
},
{
"path": "src/main.rs",
"content": "#[tokio::main]\nasync fn main() -> Result<()> {\n let client = GeminiClient::new(...);\n let server = MCPServer::new(client);\n server.run().await\n}"
}
]
}
```
**Example Response:**
```json
{
"directory": "src/\n main.rs\n lib.rs\n ...",
"files_included": 2,
"summary": "## Dynamic Grounding for GitHub Copilot\n\n**Overall Purpose:**\nMCP (Model Context Protocol) server that integrates Google's Gemini AI with GitHub Copilot to provide enhanced codebase search and analysis capabilities.\n\n**Architecture:**\n- **Binary Entry Point:** `main.rs` - Sets up async runtime and starts MCP server\n- **Library Core:** `lib.rs` - Public API exposing key components\n- **Modular Design:** Separation of concerns across focused modules\n\n**Key Components:**\n\n1. **API Integration (`gemini.rs`)**\n - HTTP client for Gemini API\n - Handles authentication and requests\n - Exports: `GeminiClient`\n\n2. **Quota Management (`quota.rs`)**\n - Tracks API rate limits (RPM, RPD, TPM)\n - Prevents quota violations\n\n3. **Security (`api_key.rs`)**\n - Secure API key management\n - Memory-safe credential handling\n\n4. **Protocol (`mcp_server.rs`)**\n - MCP protocol implementation\n - Stdio-based communication\n\n5. **Tools (`tools.rs`)**\n - MCP tool handlers for code search and analysis\n\n**Technology Stack:**\n- Async runtime: Tokio\n- HTTP: Reqwest\n- Protocol: Model Context Protocol (MCP)\n- AI: Google Gemini API\n\n**Entry Points:**\n- Binary: `main()` in `main.rs`\n- Library: Public exports in `lib.rs`\n\n**Notable Patterns:**\n- Arc-based shared state for thread-safety\n- Result-based error handling\n- Module re-exports for clean public API\n- Async/await throughout",
"quota_status": "Quota OK: 11/15 RPM (73%)"
}
```
---
## Quota Status Messages
All tool responses include a `quota_status` field showing current API usage:
**Format:** `"Quota {STATUS}: {RPM_USAGE}/{RPM_LIMIT} RPM ({RPM_PERCENT}%), {RPD_USAGE}/{RPD_LIMIT} RPD ({RPD_PERCENT}%)"`
**Status Types:**
- `OK` - Usage below warning threshold (< 80%)
- `WARNING` - Usage above 80% but below 95%
- `CRITICAL` - Usage at or above 95% (requests may be blocked)
**Examples:**
```
"Quota OK: 5/15 RPM (33%), 200/1500 RPD (13%)"
"Quota WARNING: 13/15 RPM (87%), 1300/1500 RPD (87%)"
"Quota CRITICAL: 15/15 RPM (100%), 1450/1500 RPD (97%)"
```
## Error Handling
All tools use consistent error handling:
**Success Response:**
```json
{
"content": [
{
"type": "text",
"text": "{json_result}"
}
],
"isError": false
}
```
**Error Response:**
```json
{
"content": [
{
"type": "text",
"text": "Error description"
}
],
"isError": true
}
```
**Common Error Types:**
- Missing required parameters
- Invalid parameter formats
- Gemini API errors (authentication, rate limits, etc.)
- Empty file arrays
- Quota exceeded
## Usage with GitHub Copilot
These tools are automatically available to GitHub Copilot when the MCP server is running. Copilot can invoke them to enhance its understanding of your codebase and provide better suggestions.
**Typical Workflow:**
1. User asks Copilot a question about the codebase
2. Copilot identifies relevant files
3. Copilot calls appropriate MCP tool with file contents
4. Tool uses Gemini AI to analyze and respond
5. Copilot incorporates results into its response
## Performance Considerations
- **Token Limits:** Gemini 2.0 Flash has a 2M token context window
- **File Limits:** `summarize_directory` automatically limits to first 10 files
- **Quota Tracking:** Local tracking prevents API overuse
- **Async Operations:** All tools are fully async for performance
## Best Practices
1. **search_codebase:** Provide focused file sets rather than entire codebase
2. **analyze_files:** Include only files relevant to the question
3. **ask_about_code:** Provide sufficient context but avoid massive code dumps
4. **summarize_directory:** Limit to key representative files (10 max)
## Testing
All tools include unit tests:
```bash
cargo test tools::tests
```
To test individual tools:
```bash
cargo test tools::tests::test_tool_creation
```