MCP server for Forgejo operations
Find a file
Lucas Draney 55d4b0c2ff
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
feat: add DORA query tools for agent reasoning (#31)
2026-06-13 20:05:40 +00:00
docs docs: absorb DORA docs repo into forgejo-mcp/docs/ (#30) 2026-06-13 19:11:28 +00:00
src/forgejo_mcp feat: add DORA query tools for agent reasoning (#31) 2026-06-13 20:05:40 +00:00
tests feat: add DORA query tools for agent reasoning (#31) 2026-06-13 20:05:40 +00:00
.claude-no-enforce Initial commit: SOP-aware MCP server for Forgejo 2026-02-24 10:20:01 -07:00
.woodpecker.yml fix: remove redundant CI when clause + use side_effect in pagination test (#14) 2026-03-14 19:20:22 +00:00
CLAUDE.md docs: add missing update_issue tool, CLAUDE.md symlink, fix auth docs (#27) 2026-06-13 18:19:16 +00:00
pyproject.toml feat: add Woodpecker CI pipeline and ruff config (#2) 2026-03-01 17:32:11 +00:00
README.md docs: absorb DORA docs repo into forgejo-mcp/docs/ (#30) 2026-06-13 19:11:28 +00:00

forgejo-mcp

MCP server wrapping the Forgejo SDK with SOP-aware workflow tools for AI agents.

This is not a 1:1 API wrapper. Tools encode platform conventions:

  • create_issue / create_issue_and_branch — create issues (optionally with a branch named {issue-num}-{slug})
  • update_issue — update an issue's title and/or body
  • submit_pr — creates PR from branch, returns link
  • review_pr — gets diff + metadata for review
  • comment_on_pr — post a comment on a PR
  • merge_approved_pr — squash merges after confirmation
  • set_label — set labels on an issue by name (paginates through all repo labels)
  • comment_on_issue — post a comment on an issue
  • create_repo — create a new repository
  • create_api_token — create a Forgejo API token
  • list_issues / list_prs / list_branches — filtered views
  • get_repo / search_repos — repository lookup

comment_on_issue vs comment_on_pr

These two tools use the same Forgejo API endpoint under the hood (POST /repos/{owner}/{repo}/issues/{index}/comments) because Forgejo treats issues and PRs as the same entity for comments. They are exposed as separate MCP tools for semantic clarity — agents should pick the tool that matches their intent.

Architecture

flowchart LR
    subgraph "Agent Layer"
        A[Claude Code / Agents]
    end
    subgraph "MCP Layer"
        MCP[forgejo-mcp<br/>SOP workflow tools]
    end
    subgraph "SDK Layer"
        SDK[forgejo-sdk<br/>httpx wrapper]
    end
    subgraph "Platform"
        API[Forgejo REST API]
    end

    A -->|MCP protocol| MCP
    MCP --> SDK
    SDK -->|HTTP| API

The SDK does API calls. The MCP layer encodes platform conventions (branch naming, PR templates, review loops). Agents never hit the Forgejo API directly — they go through MCP tools.

Where this fits in the platform

flowchart LR
    subgraph "Action Path"
        A[Agents] --> MCP[forgejo-mcp] --> SDK[forgejo-sdk] --> API[Forgejo API]
    end
    subgraph "Measurement Path"
        API --> EXP[pal-e-dora-exporter]
        WP[Woodpecker API] --> EXP
        EXP --> PROM[Prometheus]
        PROM --> GRAF[Grafana]
    end

Agents act through forgejo-mcp (create issues, merge PRs). Separately, the DORA exporter scrapes the same Forgejo API to measure what happened (deployment frequency, lead time, change failure rate, MTTR). The two paths share the API but are independent — forgejo-mcp is not in the observability pipeline.

DORA Docs

Doc What it covers
Architecture Data flow from Forgejo/Woodpecker through Prometheus to Grafana
Metrics Reference Every Prometheus metric the exporter emits, labels, and example PromQL
Project Tiering Which repos we measure, tier system for Grafana filtering
Grafana Dashboard Current panels, PromQL queries, and planned improvements

Auth

Token auth (preferred) or basic auth. Set in ~/.mcp.json:

{
  "mcpServers": {
    "forgejo": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/forgejo-mcp", "forgejo-mcp"],
      "env": {
        "FORGEJO_URL": "https://forgejo.example.com",
        "FORGEJO_TOKEN": "your-api-token"
      }
    }
  }
}

Falls back to basic auth via FORGEJO_USER + FORGEJO_PASSWORD if FORGEJO_TOKEN is not set.