Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

McpServer: middleware and visibility can't use per-request services from HttpRouter middleware under layerHttp

Abierto
#9,854 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
55/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
typescript

Línea de trabajo

Start with MiddlewareLayer and its McpRequest.From<"Requires", ...> layer type, then compare how middleware requirements are handled by layerHttp, layer, and layerStdio. The report says the runtime already forwards these dependencies through layerHttp; verify the behavior with the described visibility and tool-call cases. Done when middleware and visibility can use HttpRouter per-request services through layerHttp, while unmet requirements remain visible for layer and layerStdio.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

On v4/next-minor (pkg.pr.new 7ce7d03), tools can depend on per-request services provided by HttpRouter middleware: layerHttp converts the remaining McpRequest.From<"Requires", R> into HttpRouter.Request.From<"Requires", R>. MCP middleware and visibility checks can't. MiddlewareLayer turns any requirement outside TransportServices into MissingRequestDependencies, so it can only be satisfied by .combine or the transport.

class CurrentUser extends Context.Service<CurrentUser, { readonly id: number }>()("CurrentUser") {}

// HTTP auth stays at the HTTP layer: OAuth discovery and refresh need a 401 with WWW-Authenticate,
// and MCP middleware never runs for initialize/ping
const Auth = HttpRouter.middleware<{ provides: CurrentUser }>()(/* bearer token -> user */)

const Policy = McpServer.visibility(
  Effect.succeed(({ target }) =>
    Effect.gen(function* () {
      const user = yield* CurrentUser
      return canUse(user, target)
    })
  )
)

Policy.layer
// ^? MissingRequestDependencies<CurrentUser>, although Auth provides CurrentUser to every request under layerHttp

The workaround is an MCP middleware that re-provides what is already on the fiber:

const Bridge = McpServer.middleware<{ provides: CurrentUser }>()((effect) =>
  Effect.gen(function* () {
    const user = yield* Effect.serviceOption(CurrentUser)
    if (Option.isNone(user)) return yield* Effect.die(new Error("missing HTTP auth"))
    return yield* effect.pipe(CurrentUser.provide(user.value))
  })
)

Policy.combine(Bridge).layer

Doing the authentication itself in a combined MCP middleware would mean resolving the token and user a second time on every request.

Proposal

Drop the conditional and always put the per-request requirements in the layer input, as registrations already do. layerHttp then forwards them to HttpRouter, while layer / layerStdio still surface them as unmet requirements:

type MiddlewareLayer<Config extends MiddlewareConfig, R> = Layer.Layer<
  McpRequest.From<"Requires", Config["provides"]>,
  Config["layerError"],
  R | Config["layerRequires"] | McpRequest.From<"Requires", Config["requires"]>
>

The runtime already handles this. With only the .d.ts patched and the bridge removed, through layerHttp + HttpRouter.toWebHandler:

  • tools/list hides the tool the policy rejects
  • the visible tool receives CurrentUser
  • calling the hidden tool returns -32602 Tool '…' not found

Trade-off: an unmet requirement then shows up as a missing layer requirement at the server instead of the named MissingRequestDependencies at .layer. Happy to open a PR if this direction is fine.

Lenguaje dominante
TypeScript
Estrellas
16.7k
Forks
808
Merge medio
11 h 24 min
PR fusionados (30 d)
848

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Effect-TS/effect

Todos los issues de Effect-TS/effect

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.