Codex CLI for tRPC v11 Development: Type-Safe APIs, TanStack Integration, and MCP-Bridged Agent Workflows
Codex CLI for tRPC v11 Development: Type-Safe APIs, TanStack Integration, and MCP-Bridged Agent Workflows
tRPC v11 shipped with streaming responses, FormData support, SSE subscriptions, and a revamped TanStack Query integration1. Combined with TanStack Start reaching Release Candidate status2, the TypeScript full-stack ecosystem now offers end-to-end type safety from database to component without code generation. Codex CLI slots neatly into this stack: its TypeScript-native sandbox, MCP server support, and agent skills system let you scaffold routers, generate Zod schemas, and even expose tRPC procedures as MCP tools — all from the terminal.
This article covers the practical integration points between Codex CLI and the tRPC v11 + TanStack ecosystem, including project setup, agent skills, the trpc-mcp bridge, and production workflow patterns.
Why tRPC Suits Agent-Driven Development
tRPC’s core promise — types are the contract3 — aligns with how coding agents work best. When an agent modifies a server procedure, TypeScript immediately surfaces every callsite that breaks. No OpenAPI spec drift, no generated client staleness, no runtime schema mismatch. The compiler becomes the agent’s guardrail.
Key tRPC v11 features that matter for agent workflows:
- Shorthand router syntax — plain objects as sub-routers reduce boilerplate the agent must generate1
httpBatchStreamLink— streaming query responses let agents process large datasets incrementally1- FormData and binary inputs —
octetInputParserhandles file uploads without custom middleware1 - SSE subscriptions — real-time features via
httpSubscriptionLinkwithout WebSocket complexity1 - TanStack Query v5 integration — native
QueryOptions/MutationOptionsinterfaces replace the classic wrapper API4
Project Setup with Codex CLI
Scaffolding a tRPC + TanStack Start Project
# Create a TanStack Start project with tRPC
npx create-start-app my-app --template with-trpc-react-query
cd my-app
# Initialise Codex CLI configuration
codex init
Add tRPC-specific guidance to your AGENTS.md:
## tRPC Conventions
- All procedures use Zod v3 input/output validators
- Business logic lives in `src/server/services/`, not in procedure handlers
- Use `TRPCError` with appropriate HTTP codes, never raw `throw`
- Procedures are thin: validate → delegate → return
- Router files map 1:1 to domain entities in `src/server/routers/`
Configuring Codex CLI for Type-Safe Workflows
In your project-scoped .codex/config.toml, set the sandbox to permit TypeScript compilation checks:
[sandbox]
allow_commands = [
"npx tsc --noEmit",
"npx vitest run",
"npm run build",
]
[model]
default = "o3"
This ensures Codex CLI runs the TypeScript compiler after every mutation, catching type errors before they propagate.
The tRPC Agent Skill
A dedicated tRPC agent skill is available for Codex CLI5, encoding best practices directly into the agent’s instruction set:
# Install the tRPC skill
codex skills add trpc
The skill instructs the agent to:
- Initialise tRPC with
initTRPC.create()and define context factories for session and database access - Create
publicProcedureandprotectedProcedurebases with middleware chains - Validate all inputs with Zod schemas
- Use
TRPCErrorwith appropriate codes for error handling - Extract business logic into service functions5
When you prompt Codex CLI to add a new API endpoint, the skill ensures the generated code follows these conventions automatically.
Bridging tRPC and MCP with trpc-mcp
The trpc-mcp library6 lets you expose tRPC procedures as MCP tools, creating a bridge between your API layer and any MCP-compatible agent — including Codex CLI itself.
graph LR
A[tRPC Router] -->|trpc-mcp| B[MCP Server]
B -->|stdio/SSE| C[Codex CLI]
C -->|Type-safe calls| A
D[Other MCP Clients] -->|stdio/SSE| B
Setting Up trpc-mcp
Install and configure the bridge:
npm install trpc-mcp
// src/server/mcp.ts
import { initTRPC } from "@trpc/server";
import { McpMeta, createMcpServer } from "trpc-mcp";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const t = initTRPC.meta<McpMeta>().create();
const appRouter = t.router({
getUser: t.procedure
.meta({ openapi: { enabled: true, description: "Fetch user by ID" } })
.input(z.object({ id: z.string().uuid() }))
.output(z.object({ name: z.string(), email: z.string() }))
.query(({ input }) => userService.findById(input.id)),
createInvoice: t.procedure
.meta({ openapi: { enabled: true, description: "Create a new invoice" } })
.input(z.object({
customerId: z.string().uuid(),
items: z.array(z.object({
description: z.string(),
amount: z.number().positive(),
})),
}))
.mutation(({ input }) => invoiceService.create(input)),
});
const server = createMcpServer({
name: "my-api",
version: "1.0.0",
router: appRouter,
});
const transport = new StdioServerTransport();
await server.connect(transport);
Each procedure annotated with meta({ openapi: { enabled: true } }) becomes a callable MCP tool6. Zod schemas translate directly to MCP tool input schemas — no manual mapping required.
Registering with Codex CLI
codex mcp add my-api -- npx tsx src/server/mcp.ts
Now Codex CLI can invoke your tRPC procedures as MCP tools during development sessions, enabling patterns like:
- Querying your API to understand data shapes before writing frontend components
- Creating test fixtures via mutation tools
- Validating business logic against live (or local) data
TanStack Integration Patterns
TanStack Query v5 with tRPC v11
The new TanStack Query integration4 uses native QueryOptions rather than wrapping useQuery:
// src/hooks/useUser.ts
import { trpc } from "~/utils/trpc";
// v11 style — uses native TanStack Query options
export function useUser(id: string) {
return trpc.getUser.useQuery({ id });
}
// Prefetching in a TanStack Start loader
export const Route = createFileRoute("/users/$userId")({
loader: async ({ params, context }) => {
await context.trpc.getUser.ensureQueryData({ id: params.userId });
},
component: UserPage,
});
Codex CLI understands this pattern and will generate loaders with proper prefetching when you ask it to “add a user detail page with server-side data loading”.
TanStack Start Server Functions
TanStack Start’s server functions2 complement tRPC for cases where a full procedure is overkill:
// src/server/functions/sendEmail.ts
import { createServerFn } from "@tanstack/start";
import { z } from "zod";
export const sendWelcomeEmail = createServerFn()
.validator(z.object({ userId: z.string().uuid() }))
.handler(async ({ data }) => {
const user = await db.user.findUnique({ where: { id: data.userId } });
await emailService.sendWelcome(user);
return { sent: true };
});
The guidance in AGENTS.md should clarify when to use tRPC (shared API layer, multiple consumers) versus server functions (page-specific logic, form actions).
Streaming and Real-Time Patterns
tRPC v11’s streaming capabilities1 open up agent-assisted real-time feature development:
Streaming Query Responses
// Server: streaming a large dataset
const logsRouter = t.router({
streamLogs: t.procedure
.input(z.object({ since: z.date() }))
.query(async function* ({ input }) {
const cursor = db.logs.findStream({ since: input.since });
for await (const batch of cursor) {
yield batch;
}
}),
});
// Client: consuming the stream
const { data } = trpc.streamLogs.useQuery(
{ since: yesterday },
{ trpcOptions: { httpBatchStreamLink: true } }
);
SSE Subscriptions
// Server: real-time notifications
const notificationsRouter = t.router({
onNewMessage: t.procedure
.input(z.object({ channelId: z.string() }))
.subscription(async function* ({ input }) {
for await (const msg of messageStream(input.channelId)) {
yield msg;
}
}),
});
When building these patterns with Codex CLI, the agent handles the boilerplate — generator functions, Zod validators, client-side subscription hooks — while you focus on the business logic.
Testing with Codex CLI
tRPC’s type safety extends to testing. Codex CLI can generate type-safe test suites:
codex "Generate vitest tests for the invoiceRouter covering
create, list, and getById procedures. Use createCallerFactory
for direct procedure testing without HTTP."
The generated tests follow tRPC v11 conventions:
// src/server/routers/__tests__/invoice.test.ts
import { createCallerFactory } from "@trpc/server";
import { appRouter } from "../root";
import { createTestContext } from "~/test/helpers";
const createCaller = createCallerFactory(appRouter);
describe("invoiceRouter", () => {
it("creates an invoice with valid input", async () => {
const ctx = await createTestContext({ userId: "test-user" });
const caller = createCaller(ctx);
const result = await caller.createInvoice({
customerId: "cust-123",
items: [{ description: "Consulting", amount: 500 }],
});
expect(result.id).toBeDefined();
expect(result.total).toBe(500);
});
});
Workflow: Full-Stack Feature with Codex CLI
A typical feature addition follows this flow:
sequenceDiagram
participant Dev as Developer
participant Codex as Codex CLI
participant TS as TypeScript Compiler
participant Tests as Vitest
Dev->>Codex: "Add invoice PDF export endpoint"
Codex->>Codex: Read AGENTS.md + tRPC skill
Codex->>Codex: Add procedure to invoiceRouter
Codex->>Codex: Add Zod input/output schemas
Codex->>TS: npx tsc --noEmit
TS-->>Codex: Type check passes
Codex->>Codex: Generate React component + loader
Codex->>TS: npx tsc --noEmit
TS-->>Codex: Type check passes
Codex->>Codex: Generate vitest test
Codex->>Tests: npx vitest run
Tests-->>Codex: All tests pass
Codex-->>Dev: Feature complete, 4 files changed
The TypeScript compiler runs after each mutation step, catching type mismatches immediately. This is the core advantage of tRPC in agent workflows — the type system acts as a continuous verification layer.
Production Considerations
Router Organisation at Scale
For large applications, structure routers by domain:
src/server/routers/
├── root.ts # mergeRouters entry point
├── user.ts
├── invoice.ts
├── notification.ts
└── _app.ts # type export for client
Codex CLI’s codebase understanding means it will place new procedures in the correct domain router and update the root merge automatically.
MCP Tool Exposure Policies
Not every procedure should be an MCP tool. Use the meta.openapi.enabled flag selectively:
- Enable for read-heavy queries and idempotent mutations useful during development
- Disable for destructive operations (delete, bulk update) and sensitive endpoints (auth, billing)
- Consider a separate
dev-mcp.tsentrypoint that exposes a wider set of tools than production
Type Export Strategy
Export the router type for client consumption:
// src/server/routers/_app.ts
export type AppRouter = typeof appRouter;
This single type export is what makes the entire client type-safe. Codex CLI preserves this pattern when refactoring routers.
Citations
-
Announcing tRPC v11 — tRPC blog, March 2025. Covers streaming, FormData, SSE subscriptions, shorthand syntax, and TanStack Query v5 support. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
TanStack Start v1 Release Candidate — TanStack blog, September 2025. Type-safe routing, server functions, TanStack Query integration, no vendor lock-in. ↩ ↩2
-
tRPC — Move Fast and Break Nothing — Official tRPC documentation. End-to-end type-safe APIs without code generation. ↩
-
Introducing the new TanStack React Query integration — tRPC blog. Native QueryOptions/MutationOptions interfaces replacing the classic wrapper API. ↩ ↩2
-
tRPC Agent Skill — Terminal Skills marketplace. Agent skill encoding tRPC best practices for procedure creation, Zod validation, and error handling. ↩ ↩2
-
trpc-mcp — Serve tRPC routes as an MCP server — GitHub. MIT-licensed bridge converting annotated tRPC procedures to MCP tools via stdio transport. ↩ ↩2