fix(mcp): scaffold middleware order mirrors web.New (Recover first, UUID v7)

This commit is contained in:
2026-08-08 21:56:27 -06:00
parent e1802e4c25
commit 87c5eda1bc
6 changed files with 45 additions and 9 deletions
+11
View File
@@ -6,6 +6,17 @@ This module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html
---
## [1.3.2] — 2026-08-08
Patch. Scaffold/wire middleware order now mirrors `web.New`.
### Changed
- Generated wire (and the wire builtin example) apply middleware in `web.New`'s order —
`Recover` outermost, a time-ordered UUID v7 request ID (`newRequestID`), then
`RequestLogger` — with the env-gated allow-all CORS as the only deliberate divergence.
Previously the scaffold put `RequestID` before `Recover` and used a v4 request ID.
## [1.3.1] — 2026-08-08
Patch. Correct the `web.allowedorigins-removed` rule message and migration docs to name the
+1 -1
View File
@@ -1,6 +1,6 @@
# einherjar/mcp
[![version](https://img.shields.io/badge/version-v1.3.1-5C4EE5?style=flat-square)](https://code.nochebuena.dev/einherjar/mcp)
[![version](https://img.shields.io/badge/version-v1.3.2-5C4EE5?style=flat-square)](https://code.nochebuena.dev/einherjar/mcp)
[![license](https://img.shields.io/badge/license-AGPL--3.0-22863A?style=flat-square)](LICENSE)
[![go](https://img.shields.io/badge/Go-1.26+-00ADD8?style=flat-square&logo=go&logoColor=white)](https://go.dev)
+1 -1
View File
@@ -23,7 +23,7 @@ import (
const (
serverName = "einherjar-mcp"
serverVersion = "v1.3.1"
serverVersion = "v1.3.2"
)
func main() {
+3 -3
View File
File diff suppressed because one or more lines are too long
+14 -2
View File
@@ -277,10 +277,13 @@ func Run() error {
srv := server.New(logger, cfg.Server,
server.WithMiddleware(
mw.RequestID(uuid.NewString),
// Recover outermost, time-ordered request ID, then logging — same order
// as web.New. corsMW (env-gated allow-all) sits before auth so preflight
// OPTIONS short-circuit without hitting the auth middleware.
mw.Recover(logger),
corsMW,
mw.RequestID(newRequestID),
mw.RequestLogger(logger),
corsMW,
authjwt.AuthMiddleware(logger, signer, publicPaths),
authmw.EnrichmentMiddleware(logger, &claimsEnricher{}),
),
@@ -298,6 +301,15 @@ func Run() error {
return lc.Run()
}
// newRequestID returns a time-ordered UUID v7 (falling back to v4), matching web.New.
func newRequestID() string {
id, err := uuid.NewV7()
if err != nil {
return uuid.NewString()
}
return id.String()
}
```
## Feature hook
+15 -2
View File
@@ -143,10 +143,13 @@ func Run() error {
srv := server.New(logger, cfg.Server,
server.WithMiddleware(
mw.RequestID(uuid.NewString),
// Same stack and order as web.New — Recover outermost, time-ordered
// request ID, then logging. The only deliberate difference is the
// env-gated allow-all CORS (corsMW) above, which web.New does not offer.
mw.Recover(logger),
corsMW,
mw.RequestID(newRequestID),
mw.RequestLogger(logger),
corsMW,
),
)
@@ -158,6 +161,16 @@ func Run() error {
return lc.Run()
}
// newRequestID returns a time-ordered UUID v7 (falling back to v4 on error),
// matching web.New's request-ID generator.
func newRequestID() string {
id, err := uuid.NewV7()
if err != nil {
return uuid.NewString()
}
return id.String()
}
`
const tplHealth = `package wire