First real port of the MCP chassis library — abort-criterion check for
spike S3 of the 2026-05 homelab architecture review.
Changes:
- Drop internal/auth/jwt.go (~79 LOC) — chassis provides JWTValidator
with identical signature.
- Drop internal/auth/bearer.go (~42 LOC) — chassis BearerMiddleware
has the same static-or-JWT semantics plus an optional WWW-Authenticate
resource_metadata challenge (consumed via new resourceMetadataURL arg).
- Drop internal/auth/bearer_test.go — same scenarios are covered in
the chassis bearer_test.go now.
- main.go: import chassis as `chassisauth`, build resourceMetadataURL
only when both DexIssuerURL + MCPResourceURL are set, replace the
inline /.well-known/oauth-protected-resource handler with the chassis
ProtectedResourceHandler.
internal/auth/caller.go (oauth2-proxy header → context) stays — chassis
out-of-scope.
Net LOC change: -~150 LOC duplicated infra + a 5-LOC import.
go.mod gains gitea.d-ma.be/mathias/mcp-chassis v0.1.0 (jwx/v2 + testify
already transitive, no new top-level deps).
Verifies abort criterion: one PR, one binary's worth of port, task check
green (lint + test + vet + govulncheck clean). Per the S3 spike spec,
this clears the chassis to continue. Next port: hyperguild/ingestion
(brain-mcp), filed as a follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes#27.
PROJECT.md
- Git section: TBD as the convention. Commit to main, one logical
change per commit, `task check` locally before push, CI is the
quality gate. PRs only for the parallel-agent exception.
- Agent rule 6: rewritten to match.
.gitea/workflows/cd.yml
- Drop the pull_request trigger — vestigial under TBD.
- Drop the `if: github.event_name != 'pull_request'` guard on the
build job (now always true since pull_request no longer fires).
Tag pushes still build (no version gating regression).
- Deploy `if` left alone — already correctly limits deploy to
main pushes, skipping tag-push builds.
.githooks/pre-push (new)
- Runs `task check` before every push. Set up via `task setup:hooks`,
which sets core.hooksPath to the in-repo .githooks dir.
Taskfile.yml
- New `setup:hooks` task to install the pre-push hook on a fresh
clone.
README.md
- Quickstart section showing `task setup:hooks` + the TBD policy.
Derived adapters regenerated via `task context:sync` and committed
in the same commit (single-commit invariant).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Upstream .context/PROJECT.md gained a branch-protection rule + an
extra agent instruction. Pure regeneration via scripts/context-sync.sh
to make task check pass before force-push.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Derived adapters drifted from canonical root .context/AGENT.md after
the pgvector default change landed upstream. Pure regeneration via
scripts/context-sync.sh, no manual edits. Required to make task check
pass before the feature commits on this branch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- internal/auth/jwt.go: JWTValidator via lestrrat-go/jwx/v2, JWKS auto-refresh
- internal/auth/bearer.go: replace Gitea PAT validation with JWT->static->default chain
- internal/gitea/client.go: always use service PAT; remove TokenFromContext lookup
- internal/config/config.go: add DexIssuerURL, MCPAudience, MCPResourceURL, StaticToken
- cmd/gitea-mcp/main.go: wire validator, fix /.well-known to return real AS list
- bearer_test.go: rewrite for new API