Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add rules/pauljphilp/effectpatterns/compose-api-middlewaregit clone --depth 1 https://github.com/PaulJPhilp/EffectPatternsWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.01004 | $0.01004 |
| Opus 5 | $0.00502 | $0.00502 |
| Sonnet 5 | $0.00201 | $0.00201 |
| Haiku 4.5 | $0.00100 | $0.00100 |
Grade A, and why
compose-api-middleware scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 165 lines — stays where its author put it; the contents beside it link to each section on GitHub.
description: Use Effect composition to build a middleware pipeline that processes requests. globs: "**/*.ts" alwaysApply: true
Compose API Middleware
Rule: Use Effect composition to build a middleware pipeline that processes requests.
Example
import { Effect, Context, Layer, Duration } from "effect"
import { HttpServerRequest, HttpServerResponse } from "@effect/platform"
// ============================================
// 1. Define middleware type
// ============================================
type Handler<E, R> = Effect.Effect<HttpServerResponse.HttpServerResponse, E, R>
type Middleware<E1, R1, E2 = E1, R2 = R1> = <E extends E1, R extends R1>(
handler: Handler<E, R>
) => Handler<E | E2, R | R2>
// ============================================
// 2. Logging middleware
// ============================================
const withLogging: Middleware<never, HttpServerRequest.HttpServerRequest> =
(handler) =>
Effect.gen(function* () {
const request = yield* HttpServerRequest.HttpServerRequest
const startTime = Date.now()
yield* Effect.log(`→ ${request.method} ${request.url}`)
const response = yield* handler
const duration = Date.now() - startTime
yield* Effect.log(`← ${response.status} (${duration}ms)`)
return response
})
// ============================================
// 3. Timing middleware (adds header)
// ============================================
const withTiming: Middleware<never, never> = (handler) =>
Effect.gen(function* () {
const startTime = Date.now()
const response = yield* handler
const duration = Date.now() - startTime
return HttpServerResponse.setHeader(
response,
"X-Response-Time",
`${duration}ms`
)
})
// ============================================
// 4. Error handling middleware
// ============================================
const withErrorHandling: Middleware<unknown, never, never> = (handler) =>
handler.pipe(
Effect.catchAll((error) =>
Effect.gen(function* () {
yield* Effect.logError(`Unhandled error: ${error}`)
return HttpServerResponse.json(
{ error: "Internal Server Error" },
{ status: 500 }
)
})
)
)
// ============================================
// 5. Request ID middleware
// ============================================
class RequestId extends Context.Tag("RequestId")<RequestId, string>() {}
const withRequestId: Middleware<never, never, never, RequestId> = (handler) =>
Effect.gen(function* () {
const requestId = crypto.randomUUID()
const response = yield* handler.pipe(
Effect.provideService(RequestId, requestId)
)
return HttpServerResponse.setHeader(response, "X-Request-Id", requestId)
})
// ============================================
// 6. Timeout middleware
// ============================================
const withTimeout = (duration: Duration.DurationInput): Middleware<never, never> =>
(handler) =>
handler.pipe(
Effect.timeout(duration),
Effect.catchTag("TimeoutException", () =>
Effect.succeed(
HttpServerResponse.json(
{ error: "Request timeout" },
{ status: 504 }
)
)
)
)
// ============================================
// 7. CORS middleware (see separate pattern)
// ============================================
const withCORS = (origin: string): Middleware<never, never> => (handler) =>
Effect.gen(function* () {
const response = yield* handler
return response.pipe(
HttpServerResponse.setHeader("Access-Control-Allow-Origin", origin),
HttpServerResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"),
HttpServerResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization")
)
})
// ============================================
// 8. Compose middleware
// ============================================
const applyMiddleware = <E, R>(handler: Handler<E, R>) =>
handler.pipe(
withLogging,
withTiming,
withRequestId,
withTimeout("30 seconds"),
withCORS("*"),
withErrorHandling
)
// ============================================
// 9. Usage
// ============================================
const myHandler = Effect.gen(function* () {
const requestId = yield* RequestId
yield* Effect.log(`Processing request ${requestId}`)
return HttpServerResponse.json({ message: "Hello!" })
})
const protectedHandler = applyMiddleware(myHandler)
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2d ago First seen · 165 lines · 1,004 tokens per session scan A 249cb59b00ba
compose-api-middleware is a cursor rule published in the GitHub repository PaulJPhilp/EffectPatterns (794 stars, last pushed 2mo ago), licensed MIT. It adds 1,004 tokens to every session, about $0.0050 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other cursor rules, from other repositories
transcreveai
Required handoff contract for nested TranscreveAI executions.
cursorrules
You are an expert software engineer and architect. You are part of a team, but your memory is reset after every session. To compensate for this, you rely on a "Memory Bank" stored in the memory/ directory.
typescript-coding-style
Enforces code style and best practices for TypeScript files.
javascript-typescript-code-style
Rules for JavaScript and TypeScript code style, including modern features, functional patterns, and descriptive naming conventions.
astro-development-guidelines
Enforces specific development guidelines for Astro projects, including TypeScript strictness and TailwindCSS usage.
convex-development---general
Applies general rules for Convex development, emphasizing schema design, validator usage, and correct handling of system fields.