Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ Get started in minutes:
- Additional details in the [Get Started →](https://project-codeguard.org/getting-started/)


## CodeGuard MCP Server

This repository also includes an [MCP](https://modelcontextprotocol.io/) server that exposes all CodeGuard security rules as tools over streamable HTTP. Organizations can deploy it on their infrastructure and connect every developer's AI coding assistant to a single, centrally managed instance. See the [CodeGuard MCP Server README](src/codeguard-mcp/README.md) for setup instructions.


## How It Works

1. **Security skills and rules** are written in unified markdown format (`sources/` directory)
Expand Down
81 changes: 81 additions & 0 deletions src/codeguard-mcp/.agents/skills/codeguard-mcp-meta/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
name: CodeGuard MCP Meta Skill
description: Instructs AI coding agents to invoke CodeGuard MCP Server security rules before writing or reviewing code.
---

# CodeGuard MCP Server Integration

## MANDATORY: Always Invoke CodeGuard MCP Server

When writing, reviewing, or modifying code, you MUST invoke the CodeGuard MCP Server to retrieve relevant security rules. This is a non-optional security requirement.

**IMPORTANT: IF YOU ARE NOT ABLE TO SEE/INVOKE CODEGUARD TOOLS, IMMEDIATELY INFORM THE USER**

### How to Use the MCP Server

The CodeGuard MCP Server exposes security rules as individual tools. Each tool returns comprehensive security guidance for specific scenarios.

**Tool Invocation Pattern:**
```
Tool: {rule_tool_name}
Arguments: None (tools automatically include metadata)
Returns: Complete security guidance with rule ID, description, and content
```

## Tool Selection Guide

### Step 1: Discover Available CodeGuard Tools

Before any coding activity:
1. Identify all available MCP tools whose names contains `codeguard_`.
2. Read each tool's description to understand:
- The security domain it covers
- Which languages/artifacts it applies to (if specified)

If you cannot discover/invoke CodeGuard tools, stop and inform the user.

### Step 2: Always-Invoke `codeguard_1_*`

**MANDATORY:** Before writing/reviewing/modifying code, invoke **every available tool** whose name contains:

- `codeguard_1_`

These are "always-on" guardrails and must be enforced regardless of language or domain.

### Step 3: Context-Select `codeguard_0_*`

After invoking `codeguard_1_*`, decide which `codeguard_0_*` tools to invoke by using the tool descriptions plus your current task context.

#### 3A) Determine the current language(s)/artifact(s)

Infer from one or more of:
- The file(s) being edited (extensions like `.py`, `.js`, `.ts`, `.yaml`, `.yml`, `.Dockerfile`, etc.)
- Framework/tooling in use (Django/Flask/Express/K8s/Terraform/etc.)
- The user's explicit statement ("in Python", "Node", "Kubernetes manifest", etc.)

#### 3B) Determine the security domain(s) from the task

Use the tool descriptions to map the task to domains such as auth, API/web services, input validation, storage, file handling, DevOps/IaC, privacy, logging/monitoring, XML/serialization, mobile, etc.

#### 3C) Select tools using tool descriptions (language + domain)

For each available `codeguard_0_*` tool:
- **Language filter**: select it only if the description says it applies to the current language/artifact type (or is broadly applicable when no language is specified).
- **Domain filter**: select it if the domain in the description matches the task you are performing.

If uncertain and the change is security-sensitive, err on the side of invoking the relevant `codeguard_0_*` tools (while avoiding clearly unrelated tools).

## Apply the Guidance and Document It

When you implement changes:
- Follow the retrieved guidance
- Avoid anti-patterns called out by the rules
- Add minimal security comments where they clarify intent

In your response to the user, explicitly state:
- Which **CodeGuard tools** you invoked (all `codeguard_1_*` plus the selected `codeguard_0_*`)
- A brief note on **how each rule influenced** the implementation

## Tool Invocation Is Not Optional

If you are about to write/review/modify code and you have not invoked CodeGuard tools per this meta rule, stop and invoke them first.
8 changes: 8 additions & 0 deletions src/codeguard-mcp/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# CodeGuard MCP Server configuration
CODEGUARD_HOST=0.0.0.0
CODEGUARD_PORT=8080
CODEGUARD_LOG_LEVEL=INFO
# Transport: "streamable-http" (default) or "stdio" for local dev
CODEGUARD_TRANSPORT=streamable-http
# Override if rules live elsewhere (defaults to sources/core/ in the repo)
# CODEGUARD_RULES_DIR=/path/to/rules
42 changes: 42 additions & 0 deletions src/codeguard-mcp/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ── Build stage ──────────────────────────────────────────────────────
FROM python:3.11-slim AS builder

COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv

WORKDIR /app
ENV UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy

COPY src/codeguard-mcp/pyproject.toml src/codeguard-mcp/uv.lock src/codeguard-mcp/README.md ./src/codeguard-mcp/
RUN cd src/codeguard-mcp && uv sync --locked --no-dev --no-editable

COPY sources/core/ ./sources/core/
COPY src/codeguard-mcp/src/ ./src/codeguard-mcp/src/
COPY src/codeguard-mcp/.agents/ ./src/codeguard-mcp/.agents/

# ── Runtime stage ────────────────────────────────────────────────────
FROM python:3.11-slim

RUN groupadd -r codeguard && useradd -r -g codeguard codeguard

WORKDIR /app

COPY --from=builder /app/src/codeguard-mcp/.venv /app/src/codeguard-mcp/.venv
COPY --from=builder /app/src/codeguard-mcp/src /app/src/codeguard-mcp/src
COPY --from=builder /app/src/codeguard-mcp/.agents /app/src/codeguard-mcp/.agents
COPY --from=builder /app/sources/core /app/sources/core

ENV PATH="/app/src/codeguard-mcp/.venv/bin:$PATH" \
PYTHONUNBUFFERED=1 \
PYTHONPATH=/app/src/codeguard-mcp/src \
CODEGUARD_HOST=0.0.0.0 \
CODEGUARD_RULES_DIR=/app/sources/core

USER codeguard
EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD ["python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/health', timeout=2)"]

ENTRYPOINT ["/app/src/codeguard-mcp/.venv/bin/fastmcp"]
CMD ["run", "src/codeguard-mcp/src/codeguard_mcp/server.py:mcp", "--transport=streamable-http", "--host=0.0.0.0", "--port=8080"]
118 changes: 118 additions & 0 deletions src/codeguard-mcp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# CodeGuard MCP Server

An [MCP](https://modelcontextprotocol.io/) server that exposes [CoSAI CodeGuard](https://project-codeguard.org/) security rules as individual tools over streamable HTTP. Deploy it on your infrastructure and give every AI coding assistant in your organization access to curated, versioned security guidance.

## What It Does

The server reads the **23 security rules** from `sources/core/` in this repository and registers each one as a no-argument MCP tool. AI assistants invoke the tools at code-generation time and apply the returned guidance.

Rules cover: hardcoded credentials, cryptography, authentication & MFA, authorization, input validation, API security, session management, client-side web security, container/K8s/IaC hardening, logging, file uploads, supply chain, mobile security, and more.

## Quick Start

### Run locally with uv

```bash
cd src/codeguard-mcp
uv sync
uv run fastmcp run src/codeguard_mcp/server.py:mcp \
--transport streamable-http --host 0.0.0.0 --port 8080
```

### Docker

```bash
cd src/codeguard-mcp
docker compose up --build
```

## Connect Your IDE

Configure your MCP client to connect to the server:

```json
{
"mcpServers": {
"codeguard": {
"url": "http://localhost:8080/mcp"
}
}
}
```

For org-wide deployment, put the server behind your reverse proxy with TLS + SSO and point every developer's IDE at the internal URL:

```json
{
"mcpServers": {
"codeguard": {
"url": "https://codeguard-mcp.internal.company.com/mcp"
}
}
}
```

## Install the Meta Skill

The meta skill tells your AI assistant *how* to use the CodeGuard tools. It lives at `.agents/skills/codeguard-mcp-meta/SKILL.md` and needs to be installed in your project.

**Option A:** Copy it manually from this repo:

```bash
cp -r src/codeguard-mcp/.agents /path/to/your/project/
```

**Option B:** Download from the running server:

```
GET http://localhost:8080/download/skill
```

This returns a zip containing the `.agents/` directory. Unzip it into your project root.

## How It Works

```
Developer writes code
AI assistant reads the meta skill
Invokes codeguard_1_* tools (always-on guardrails)
Invokes codeguard_0_* tools (context-selected by language + domain)
Applies security guidance to generated code
Documents which rules were applied
```

### Tool Taxonomy

| Prefix | When | Count | Examples |
|--------|------|-------|----------|
| `codeguard_1_*` | **Always** before any code change | 3 | `codeguard_1_hardcoded_credentials`, `codeguard_1_crypto_algorithms` |
| `codeguard_0_*` | **Context-select** by language + domain | 20 | `codeguard_0_input_validation_injection`, `codeguard_0_api_web_services` |

## Configuration

All settings via environment variables (prefix `CODEGUARD_`):

| Variable | Default | Description |
|----------|---------|-------------|
| `CODEGUARD_HOST` | `0.0.0.0` | Bind address |
| `CODEGUARD_PORT` | `8080` | Bind port |
| `CODEGUARD_LOG_LEVEL` | `INFO` | Log level |
| `CODEGUARD_TRANSPORT` | `streamable-http` | `streamable-http` or `stdio` |
| `CODEGUARD_RULES_DIR` | `sources/core/` | Path to rule markdown files |

## Endpoints

| Method | Path | Description |
|--------|------|-------------|
| `POST` | `/mcp` | MCP protocol endpoint |
| `GET` | `/health` | Health check (`{"status": "ok"}`) |
| `GET` | `/download/skill` | Download `.agents/` skill zip |

## License

See the repository root [LICENSE.md](../../LICENSE.md).
21 changes: 21 additions & 0 deletions src/codeguard-mcp/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
services:
codeguard-mcp:
build:
context: ../..
dockerfile: src/codeguard-mcp/Dockerfile
container_name: codeguard-mcp
ports:
- "${CODEGUARD_PORT:-8080}:8080"
environment:
- CODEGUARD_LOG_LEVEL=${CODEGUARD_LOG_LEVEL:-INFO}
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/health', timeout=2)"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
48 changes: 48 additions & 0 deletions src/codeguard-mcp/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[project]
name = "codeguard-mcp"
version = "0.1.0"
description = "MCP Server exposing CoSAI CodeGuard security rules as tools"
readme = "README.md"
license = "Apache-2.0"
requires-python = ">=3.11"
keywords = ["mcp", "security", "codeguard", "cosai", "owasp"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3",
"Topic :: Security",
"Topic :: Software Development :: Quality Assurance",
]
dependencies = [
"fastmcp>=2.0.0",
"pydantic-settings>=2.0",
"pyyaml>=6.0",
]

[dependency-groups]
dev = [
"pytest>=8.0",
"pytest-asyncio>=1.0",
]

[project.scripts]
codeguard-mcp = "codeguard_mcp:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/codeguard_mcp"]

[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"

[tool.ruff]
target-version = "py311"
line-length = 100

[tool.ruff.lint]
select = ["E", "F", "I", "W"]
7 changes: 7 additions & 0 deletions src/codeguard-mcp/src/codeguard_mcp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""CoSAI CodeGuard MCP Server — security rules as MCP tools."""

__version__ = "0.1.0"

from codeguard_mcp.server import main

__all__ = ["main"]
5 changes: 5 additions & 0 deletions src/codeguard-mcp/src/codeguard_mcp/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Allow running with `python -m codeguard_mcp`."""

from codeguard_mcp.server import main

main()
28 changes: 28 additions & 0 deletions src/codeguard-mcp/src/codeguard_mcp/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Configuration via environment variables."""

from __future__ import annotations

from pathlib import Path

from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict


def _project_root() -> Path:
"""Resolve the cosai-project-codeguard repo root from src/codeguard-mcp/src/codeguard_mcp/."""
return Path(__file__).resolve().parent.parent.parent.parent.parent


class Settings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="CODEGUARD_")

HOST: str = "0.0.0.0"
PORT: int = Field(default=8080, ge=1, le=65535)
LOG_LEVEL: str = "INFO"
TRANSPORT: str = "streamable-http"
RULES_DIR: str = str(_project_root() / "sources" / "core")

APP_VERSION: str = "0.1.0"


settings = Settings()
Loading
Loading