Skip to content

LOUST-PRO/TaxonRouter

Repository files navigation

TaxonRouter

Dual-binary GitHub automation for real operators.

TaxonRouter is an Apache 2.0 open-source toolkit that brings together:

  1. taxonrouter-mcp — MCP stdio server for programmatic GitHub ProjectsV2 management (cards, fields, options)
  2. taxonrouter-auto-tagger — webhook daemon that classifies PRs and auto-applies labels + project fields

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    TaxonRouter (go.mod)                     │
│                                                             │
│  pkg/                                                       │
│    domain/      — shared pure types (no I/O)               │
│    github/      — shared GraphQL client (JWT+gh fallback)  │
│    rules/       — table-driven classifier (pure, I/O-free)  │
│                                                             │
│  internal/                                                   │
│    mcp/         — MCP tool handlers + stdio transport       │
│    classifier/  — PR classification engine (rules + LLM)      │
│    apply/       — GitHub write-back pipeline                 │
│    webhook/     — webhook receiver with HMAC verify          │
│    adapter/     — rules + hybrid rules+LLM engine           │
│    llm/         — LLM providers (OpenAI / Anthropic)        │
│                                                             │
│  cmd/                                                       │
│    taxonrouter-mcp/           — MCP binary                  │
│    taxonrouter-auto-tagger/   — webhook daemon binary        │
└─────────────────────────────────────────────────────────────┘

Quick Start

Binary install

go install github.com/LOUST-PRO/TaxonRouter/cmd/taxonrouter-mcp@latest
go install github.com/LOUST-PRO/TaxonRouter/cmd/taxonrouter-auto-tagger@latest

MCP server (taxonrouter-mcp)

# Configure project ID
mkdir -p ~/.config/taxonrouter-mcp
cat > ~/.config/taxonrouter-mcp/config.toml <<'EOF'
project_id = "PVT_your_project_id_here"
default_limit = 20
max_limit = 100
cache_ttl = "5m"
EOF

# Run
taxonrouter-mcp

Environment variables:

Variable Description
GITHUB_APP_ID GitHub App ID (enables JWT auth)
GITHUB_APP_INSTALLATION_ID GitHub App installation ID
GITHUB_APP_PRIVATE_KEY_FILE Path to .pem private key
GITHUB_TOKEN PAT fallback (if no App credentials)
LZT_GITHUB_PROJECTS_CONFIG Override config file path

Auto-tagger daemon (taxonrouter-auto-tagger)

# Environment
export WEBHOOK_SECRET="your_hmac_secret"
export GITHUB_TOKEN="ghp_your_token"
export GITHUB_PROJECT_NUMBER="42"
export LLM_PROVIDER="anthropic"   # or "openai" or "none" (rules-only)
export LLM_API_KEY="sk-ant-..."
export PORT="3013"

# Run
taxonrouter-auto-tagger

Health endpoints:

  • GET /healthz — liveness
  • GET /readyz — readiness + classifier smoke check
  • GET /admin/suggestions?since=RFC3339 — manual review queue

GitHub App vs PAT

GitHub App (recommended for production):

export GITHUB_APP_ID=123456
export GITHUB_APP_INSTALLATION_ID=987654
export GITHUB_APP_PRIVATE_KEY_FILE=/path/to/app.private-key.pem

JWT auth is ~50ms faster per call and supports fine-grained repo permissions.

PAT (fallback):

export GITHUB_TOKEN="ghp_..."

MCP Tools (taxonrouter-mcp)

Read tools (intent: read)

Tool Description
cards_list List project cards with field values. limit 1-100.
field_options Get field metadata + option list. Cached 5min.

Write tools (intent: mutate)

Tool Description
cards_add_existing Add a PR/issue to project by node ID.
current_fields Read current field values on a card (drift detection).
cards_update_fields Update fields. Accepts option names ("In Progress") or IDs ("47fc9ee4").

Field name mapping (auto-tagger)

Classifier output (e.g. Effort: S-hours) is mapped to project field names via env:

GITHUB_PROJECT_FIELD_MAPPING="Effort:Size,Phase:Status"
GITHUB_PROJECT_FIELD_VALUE_MAPPING="Size:S-hours=S,Size:M-hours=M"

GitHub Actions Integration

Self-hosted runner (persistent daemon)

Run taxonrouter-auto-tagger as a systemd service on your self-hosted runner:

sudo systemctl enable taxonrouter-auto-tagger

The daemon listens for webhook events from GitHub and applies classification automatically.

GitHub-hosted (event-driven via Actions)

For GitHub-hosted runners that don't support persistent processes, use the taxonrouter-mcp with GitHub Actions:

# .github/workflows/taxonrouter.yml
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  classify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.25'
      - run: go install github.com/LOUST-PRO/TaxonRouter/cmd/taxonrouter-mcp@latest
      - env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          WEBHOOK_SECRET: ${{ secrets.WEBHOOK_SECRET }}
      - run: taxonrouter-mcp
        # Connect via Claude Code MCP broker or direct stdio

Deployment

Docker

FROM gcr.io/distroless/static:nonroot
COPY taxonrouter-auto-tagger /taxonrouter-auto-tagger
COPY taxonrouter-mcp /taxonrouter-mcp
ENTRYPOINT ["/taxonrouter-auto-tagger"]

Systemd service

[Unit]
Description=TaxonRouter Auto-Tagger
After=network.target

[Service]
ExecStart=/usr/local/bin/taxonrouter-auto-tagger
Environment="PORT=3013"
Environment="WEBHOOK_SECRET=..."
EnvironmentFile=/etc/taxonrouter/env
Restart=always
RestartSec=5s

[Install]
WantedBy=multi-user.target

Security

  • HMAC-SHA256 webhook signature verification
  • PEM key permission check at startup (0600 required)
  • Field/project IDs validated via allowlist regex before any GraphQL call
  • Read-only MCP tools are invisible in read intent; write tools require mutate intent
  • No secrets in logs; all credentials from environment

License

Apache 2.0 — see LICENSE

About

Dual-binary GitHub automation: MCP server + webhook auto-tagger

Resources

License

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages