# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview mc-proxy is a Layer 4 TLS SNI proxy and router for Metacircular Dynamics services. It reads the SNI hostname from incoming TLS ClientHello messages and proxies the raw TCP stream to the matched backend. It does not terminate TLS. A global firewall (IP, CIDR, GeoIP country blocking) is evaluated before routing. See `ARCHITECTURE.md` for full design. ## Build Commands ```bash make all # vet → lint → test → build make mc-proxy # build the binary with version injection make build # compile all packages make test # run all tests make vet # go vet make lint # golangci-lint ``` Run a single test: ```bash go test ./internal/sni -run TestExtract ``` ## Architecture - **Module path**: `git.wntrmute.dev/kyle/mc-proxy` - **Go with CGO_ENABLED=0**, statically linked, Alpine containers - **No API surface yet** — config-driven via TOML; gRPC admin API planned for future MCP integration - **No auth** — this is pre-auth infrastructure; services behind it handle their own MCIAS auth - **No database** — routes and firewall rules are in the TOML config; SQLite planned for dynamic route management - **Config**: TOML via `go-toml/v2`, runtime data in `/srv/mc-proxy/` - **Testing**: stdlib `testing` only, `t.TempDir()` for isolation - **Linting**: golangci-lint v2 with `.golangci.yaml` ## Package Structure - `internal/config/` — TOML config loading and validation - `internal/sni/` — TLS ClientHello parser; extracts SNI hostname without consuming bytes - `internal/firewall/` — global blocklist evaluation (IP, CIDR, GeoIP via MaxMind GeoLite2); thread-safe GeoIP reload - `internal/proxy/` — bidirectional TCP relay with half-close propagation and idle timeout - `internal/server/` — orchestrates listeners → firewall → SNI → route → proxy pipeline; graceful shutdown ## Signals - `SIGINT`/`SIGTERM` — graceful shutdown (drain in-flight connections up to `shutdown_timeout`) - `SIGHUP` — reload GeoIP database without restart ## Critical Rules - mc-proxy never terminates TLS and never modifies the byte stream. - Firewall rules are always evaluated before any routing decision. - SNI matching is exact and case-insensitive. - Blocked connections get a TCP RST — no error messages, no TLS alerts.