@typia/mcp
v13.2.0
Published
MCP (Model Context Protocol) integration for typia
Maintainers
Readme
@typia/mcp

MCP (Model Context Protocol) server integration for typia.
createMcpServer turns a single typia controller into an MCP server. Every tool's input schema, output schema, and argument validation derives from the TypeScript types and JSDoc — no hand-written JSON schema or Zod shape anywhere. Every tool call is coerced and validated by typia, and validation failures go back to the model as self-correction feedback, exactly the loop the MCP spec recommends.
- Tools: every class method, with
inputSchema,outputSchema, andstructuredContentreflected from the types - Instructions: the reflected class/interface JSDoc, shipped through the handshake
- OpenAPI:
HttpLlm.controller()documents serve the same way — every operation becomes a tool calling the real endpoint, andinfo.versionbecomes the server version - Zero extra dependencies: nothing at runtime beyond what
typiaalready installs, plus the MCP SDK as a peer
Setup
npm install @typia/mcp @modelcontextprotocol/sdk typia
npm install -D ttsc typescript@rcBuild with ttsc, or run TypeScript directly with ttsx.
Usage
createMcpServer(controller, options?) — pass a typia.llm.controller (or an HttpLlm.controller over an OpenAPI document), connect a transport. Every method of the class becomes an MCP tool; the controller's name is the server name and its class JSDoc becomes the handshake instructions. Pass the deployed application's version through options.version; when omitted, the handshake version is the OpenAPI info.version for HTTP controllers and "1.0.0" otherwise.
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { createMcpServer } from "@typia/mcp";
import typia from "typia";
/** Arithmetic tools. */
class Calculator {
/** Add two numbers. */
add(p: { x: number; y: number }): { value: number } {
return { value: p.x + p.y };
}
}
const server = createMcpServer(
typia.llm.controller<Calculator>("calculator", new Calculator()),
{ version: "2.3.4" },
);
await server.connect(new StdioServerTransport());Every typed tool result ships once, as structuredContent. The MCP spec also recommends a duplicate serialized-JSON text block for clients that ignore outputSchema — but that doubles the payload, and a size-capped client counts both copies. So the fallback is opt-in:
const server = createMcpServer(controller, { textFallback: true });Results with no structured representation (void methods, errors) always keep their text content.
Validation feedback
If the LLM provides invalid arguments, the tool returns the input annotated with // ❌ markers so the model can self-correct:
{
"name": "John",
"age": "twenty", // ❌ [{"path":"$input.age","expected":"number"}]
"email": "not-an-email", // ❌ [{"path":"$input.email","expected":"string & Format<\"email\">"}]
"hobbies": "reading" // ❌ [{"path":"$input.hobbies","expected":"Array<string>"}]
}Guide documents: https://typia.io/docs/utilization/mcp
