Files
gadfly-mcp/CLAUDE.md
T
steve f92e54e3ed
CI / test (push) Successful in 10m10s
feat: gadfly-mcp — MCP server for grading gadfly-reports findings
Thin, stateless stdio MCP server (official Go SDK) that exposes a gadfly-reports store to an MCP client (e.g. Claude). Tools: list_findings, record_finding_grade, scoreboard (grader forced to claude). Launch via 'go run ...@latest' — nothing to install. Core logic tested against httptest, no daemon required.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 23:55:24 -04:00

2.3 KiB

gadfly-mcp — Developer Guide

A stdio MCP server exposing the gadfly-reports findings store to an MCP client (e.g. Claude). It is a thin, stateless HTTP client to the store — it never opens SQLite and never imports the store's package.

This is a public, vibe-coded project (built largely by an AI agent). Keep that honest in the README; it's homelab-grade.

Shape

  • Single main.go (package main) at the repo root, so the launch path is just go run gitea.stevedudenhoeffer.com/steve/gadfly-mcp@latest — no cmd/ subpath. This is the whole point: the client compiles + caches it on demand; nothing to install or manage.
  • Uses the official Go MCP SDK (github.com/modelcontextprotocol/go-sdk): mcp.NewServermcp.AddTool[In,Out] (input schemas inferred from struct + jsonschema tags) → server.Run(ctx, &mcp.StdioTransport{}).
  • Config: --store flag (default $GADFLY_REPORTS_URL, else http://localhost:8090); bearer token from $GADFLY_REPORTS_TOKEN, sent on every request when set.

Contract with gadfly-reports

The store's HTTP/JSON API is the contract — its README is the source of truth. This client mirrors only the subset it needs with small local structs (exportRow, modelStat, gradeReq, …). If you change a field here, check it against gadfly-reports' server.go/store.go. Endpoints used: GET /export, POST /findings/{id}/grade, GET /scoreboard.

Three tools: list_findings, record_finding_grade, scoreboard. The grader is always forced to "claude". The store holds no points; ranking by points/value-per-minute is a client concern — say so in the scoreboard tool description.

Tests

The core logic (groupFindings / listFindings / recordGrade / scoreboard) is factored free of MCP types and tested against an httptest.Server, so tests need no real daemon. Keep it that way — add a test when you add a tool or change the grouping/filtering.

go build ./...
go vet ./...
gofmt -l .        # must be empty
go test -race ./...

When making changes

  • Keep this a thin client: no SQLite, no business logic the store should own.
  • Keep the launch path a root package main (don't move it under cmd/), so go run …@latest stays the one-liner the README documents.