This document provides instructions for developers who want to contribute to the GG MCP Server project.
- Install Python 3.13 or higher
- Install uv (required for package management)
- Clone the repository:
git clone https://github.com/GitGuardian/ggmcp.git cd ggmcp - Install dependencies:
uv sync --dev
- Install pre-commit hooks:
pre-commit install && pre-commit install --hook-type pre-push
This project uses pre-commit to ensure code quality and security standards. The hooks are
configured in .pre-commit-config.yaml and include:
On every commit:
- Ruff - Automatically lints and formats Python code
- Commitizen - Validates commit message format
- GitGuardian ggshield - Scans for secrets in staged files
On every push:
- Commitizen-branch - Validates branch naming conventions
- GitGuardian ggshield-push - Scans all commits being pushed for secrets
The hooks will automatically run before commits/pushes and will block the operation if any issues are found. You can also run the hooks manually:
# Run all hooks on all files
pre-commit run --all-files
# Run a specific hook
pre-commit run ruff --all-filesggmcp/
├── src/
│ ├── server.py # Main MCP server entry point
│ ├── gitguardian/ # GitGuardian Honeytoken tool
│ │ ├── __init__.py
│ │ ├── client.py # API client for GitGuardian
│ │ └── tools.py # Tool implementation
│ └── [other_tools]/ # Additional tools will be added here
├── tests/ # Test suite
│ ├── test_gitguardian_client.py
│ └── ...
├── pyproject.toml # Project configuration and dependencies
├── README.md # Main documentation
└── DEVELOPMENT.md # This file
To add a new tool to the MCP server:
- Create a new directory in
src/for your tool - Implement your tool following the MCP Tools specification
- Register your tool in
src/server.py - Add unit tests for your tool
- Update the README.md to document your tool
# src/example/tools.py
from fastmcp import Request, Response, Tool
from typing import Dict, Any
class ExampleTool(Tool):
"""Example tool implementation."""
def __init__(self):
"""Initialize the tool."""
pass
def schema(self) -> Dict[str, Any]:
"""Define the schema for the tool."""
return {
"name": "example_tool",
"description": "Example tool description",
"parameters": {
"type": "object",
"required": ["param1"],
"properties": {
"param1": {
"type": "string",
"description": "First parameter"
}
}
}
}
async def execute(self, request: Request) -> Response:
"""Execute the tool."""
param1 = request.data.get("param1")
result = f"Processed: {param1}"
return Response(
status="success",
data={"result": result}
)
# List of tools to be exported
tools = [ExampleTool()]Then register the tool in src/server.py:
# src/server.py
from example.tools import tools as example_tools
# Register the tools
for tool in example_tools:
mcp.tool(tool)The GitGuardian MCP server supports two authentication modes:
For desktop applications using stdio transport, OAuth authentication is available:
ENABLE_LOCAL_OAUTH=true developer-mcp-serverThis will:
- Open a browser for OAuth authentication
- Store the token locally in
~/.gitguardian/ - Reuse the token across sessions
For server deployments using HTTP/SSE transport, use per-request PAT authentication:
MCP_PORT=8080 MCP_HOST=127.0.0.1 developer-mcp-serverClients must provide authentication via the Authorization header:
Authorization: Bearer <your-personal-access-token>
Important: You cannot use both modes simultaneously. The server will raise an error if both MCP_PORT and ENABLE_LOCAL_OAUTH=true are set.
For all transport modes, you can provide a PAT via environment variable:
GITGUARDIAN_PERSONAL_ACCESS_TOKEN=<your-pat> developer-mcp-serverThe project supports optional dependencies (extras) for additional features:
# Install with specific extras during development
uv sync --extra sentry
# Install all optional dependencies
uv sync --all-extras
# Add an optional dependency to the project
uv add --optional sentry sentry-sdkWhen running the server with uvx from Git, you can include optional dependencies:
# Include extras using the #egg syntax
uvx --from 'git+https://github.com/GitGuardian/ggmcp.git@main#egg=secops-mcp-server[sentry]' secops-mcp-server
# Or install the optional dependency separately
uv pip install sentry-sdk
uvx --from git+https://github.com/GitGuardian/ggmcp.git@main secops-mcp-server- sentry: Adds Sentry SDK for error tracking and performance monitoring
- Core package:
gg-api-core[sentry] - Available in:
developer-mcp-server[sentry],secops-mcp-server[sentry] - Implementation:
gg_api_core/src/gg_api_core/sentry_integration.py - Used for: Production error monitoring and alerting
- See individual package READMEs for configuration details
- Core package:
Run tests using uv (OAuth is disabled by default in tests):
ENABLE_LOCAL_OAUTH=false uv run pytestRun tests with verbose output:
ENABLE_LOCAL_OAUTH=false uv run pytest -vRun tests with coverage:
uv run pytest --cov=packages --cov-report=htmlCreate test files in the tests/ directory that match the pattern test_*.py.
This project uses ruff for linting and formatting. While pre-commit hooks will automatically run ruff on your staged
files, you can also run it manually:
# Check for linting issues
ruff check src tests
# Auto-fix linting issues
ruff check --fix src tests
# Format code
ruff format src testsNote: Pre-commit hooks will automatically run ruff on your staged files when you commit, so you usually don't need to run it manually.
This project includes Cursor IDE rules in the .cursor/rules directory that enforce coding standards:
- Don't use uvicorn or fastapi with MCP - MCP has its own server implementation, external web servers are not needed
- Use pyproject.toml with uv - Modern Python projects should use pyproject.toml with uv for dependency management
These rules help maintain consistent code quality and follow best practices for MCP development.
When adding a new tool, please document it in the README.md following the same structure as existing tools. Include:
- A brief description of the tool
- Required environment variables or configuration
- Tool usage examples
- Parameter descriptions
- Response format
- Integration examples with LLMs
- Any important notes or warnings
- Create a new branch for your feature or fix (ensure it follows the naming convention enforced by commitizen-branch)
- Make your changes, adding tests and documentation
- Ensure all tests pass and linting issues are fixed
- Commit your changes with properly formatted commit messages (enforced by commitizen pre-commit hook)
- Push your changes (pre-push hooks will scan for secrets and validate branch names)
- Submit a pull request with a clear description of your changes
Note: The pre-commit and pre-push hooks will automatically check your code quality, commit messages, and scan for secrets before allowing commits and pushes.
This project uses semantic versioning. To release a new version:
- Update the version in
pyproject.toml - Update the CHANGELOG.md file
- Tag the release in git
- Build and publish the package
This project leverages Python 3.13's modern features:
- Built-in type annotations: Use
dict[str, Any]instead of importingDictfrom typing - Union types with pipe operator: Use
str | Noneinstead ofOptional[str] - No need for most typing imports: Many typing constructs are now built into Python
Example:
# Python 3.13 style
def process_data(items: list[str], config: dict[str, Any] | None = None) -> dict[str, Any]:
# Implementation
return {"result": True}
# Instead of the older style:
from typing import Dict, List, Optional, Any
def process_data(items: List[str], config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
# Implementation
return {"result": True}