HTTP & MCP
The two non-gRPC surfaces that share the h2c port: httpcompat builds the HTTP/JSON gateway from grpc-gateway, and mcp exposes annotated RPCs as MCP tools an AI agent can call. Both dial the gRPC server over the in-process loopback, so both inherit the same interceptor chain.
Fetch the module first: go get github.com/yshengliao/gortexa@v0.28.3. Every snippet below is compile-verified against v0.28.3.
httpcompat
Section titled “httpcompat”Builds a ServeMux whose error handler funnels through apperr, with a protojson marshaler and forwarding of Authorization and X-Request-Id onto fixed metadata keys; Grpc-Metadata-* spellings that would collide with a trusted key (including the peer-IP key) are refused.
import ( "github.com/yshengliao/gortexa/apperr" "github.com/yshengliao/gortexa/httpcompat")
gateway := httpcompat.NewServeMux(apperr.Default)// register grpc-gateway handlers against gateway + the loopback connhandler := httpcompat.MaxBodyBytes(gateway) // caps the body at 1 MiBhandler = httpcompat.CORS(handler, cfg.Server)OpenAPIRoute(next, cfg, specPath) mounts an OpenAPI spec.
Exposes RPCs annotated with gortexa.ai.v1 as MCP tools, dispatched over the loopback through the same interceptor chain.
import ( "github.com/yshengliao/gortexa/apperr" "github.com/yshengliao/gortexa/mcp")
descs, err := mcp.ServiceDescriptors("resource.v1.ResourceService")if err != nil { return err}bridge, err := mcp.NewBridge(conn, descs, apperr.Default, cfg.Observ)if err != nil { return err}bridge.SetAllowedOrigins(cfg.Server.CORSOrigins)app.SetMCPHandler(bridge.Handler())Export tool schemas offline with mcp.ExportSchemas(format, descs), where format is mcp / openai / gemini.
Related
Section titled “Related”- HTTP/JSON transport: gateway routing, headers and limits
- MCP transport: endpoint behaviour and AI tool schemas
- Core concepts: single-port multiplexing and the shared chain