1. Conduid
  2. Other
  3. Typegen
MCP server · Other

Typegen

Unclaimed last commit 6 months ago other
30Low

Scored 6 months ago · breakdown

About Typegen

Typegen is an MCP server published by pontusab in the Other category.

The repository has 12 stars and 0 forks, with the last commit 6 months ago. Six months or more without a commit doesn't mean the server is broken, but check the open issues before depending on it in production.

Install

From source
git clone https://github.com/pontusab/mcp-typegen

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Typegen

Powered by Claude · Grounded in docs

I know everything about Typegen. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

  • ✓README presentThe repository ships documentation.

5 checks have not been run yet.

README

mcp-typegen

MCP is the source of truth. mcp-typegen is the projection. Generate typed TypeScript from any MCP server. One file per tool, organized by server — so your LLM can write code against it.

npm CI

What it is

  • A CLI + library that turns any MCP server into a typed servers/<name>/<tool>.ts tree
  • Protocol-native — uses @modelcontextprotocol/sdk as the only source of truth
  • Codegen only — zero runtime, zero sandbox coupling

Why you want this

// Before: 150k tokens of tool definitions in your prompt, one brittle call per tool
const txns = await callTool("transactions_list", { limit: 100 });

// After: autocomplete, typecheck, one file per tool, ~2k tokens to the LLM
import { transactionsList } from "./servers/midday";
const txns = await transactionsList({ limit: 100 });

Inspired by Anthropic's "code execution with MCP" — their published result was 150,000 tokens → 2,000 tokens (98.7% reduction) via progressive disclosure. mcp-typegen is the primitive that makes that pattern one command away for any TS codebase.

30-second quickstart

npx mcp-typegen --url https://api.example.com/mcp -o ./servers
import { callMCPTool } from "./servers/client";
import { listFiles } from "./servers/gdrive";

const files = await listFiles({ folderId: "root" });

Then open servers/client.ts and wire callMCPTool to your MCP transport — reference implementation below.

MCP is the source of truth

Your MCP server already defines every tool's name, input schema, output schema, and description. That's the contract. mcp-typegen does one job: project that contract into the shape an LLM writes code against.

  • The server changes → you regenerate → broken calls won't compile. Zero drift.
  • No SDK tax. Ship an MCP server, every TS codebase gets a typed client for free.
  • No proprietary schema (unlike Composio, LangChain tools, hand-rolled OpenAPI adapters).
  • Protocol-native. Same output works with any LLM, any AI SDK, any sandbox.
  • Grows with MCP. When resources/prompts/sampling mature, existing servers light up — no re-integration.

If it's not in MCP, it's not our problem. If it is in MCP, you already have it.

flowchart LR
  Server["Any MCP server (source of truth)"] -->|introspect| Typegen[mcp-typegen]
  Typegen -->|projection 1| Types[Typed TS per tool]
  Typegen -->|projection 2| Catalog[Progressive-disclosure catalog]
  Typegen -->|projection 3| Docs[Per-tool TSDoc]
  Types --> LLM[LLM writing code]
  Catalog --> LLM
  LLM --> Call[callMCPTool]
  Call --> Server

How it works

  1. Connect to any MCP server with the official SDK (@modelcontextprotocol/sdk).
  2. listTools (with full cursor pagination) to get every tool's JSON schema.
  3. Each tool becomes a single TypeScript file with typed Input / Output interfaces and an exported async function.
  4. Each server folder gets an index.ts that re-exports every tool.
  5. Optionally emit a progressive-disclosure catalog (catalog.json or catalog.md) that the LLM reads first.

Output shape

<out>/
├── client.ts                 # callMCPTool<T>() stub — user implements
├── catalog.json              # optional (--catalog json)
├── catalog.md                # optional (--catalog markdown)
└── servers/
    ├── gdrive/
    │   ├── getDocument.ts
    │   ├── listFiles.ts
    │   └── index.ts          # re-exports
    └── salesforce/
        ├── updateRecord.ts
        ├── query.ts
        └── index.ts

Each tool file:

// servers/gdrive/getDocument.ts
import { callMCPTool } from "../../client.js";

export interface GetDocumentInput {
  documentId: string;
  fields?: string;
}
export interface GetDocumentOutput {
  content: string;
}

/** Read a document from Google Drive. */
export async function getDocument(input: GetDocumentInput): Promise<GetDocumentOutput> {
  return callMCPTool<GetDocumentOutput>("gdrive_getDocument", input);
}

Recipes

I want to… See
Run a complete code agent end-to-end examples/full-agent/
Use with Claude Code or any FS-capable runtime examples/claude-code/
Adapt for an ambient sandbox (secure-exec, Workers) examples/secure-exec-flatten/
Implement callMCPTool against my transport below
Wire the generated tree into an LLM prompt examples/full-agent/

API

Install:

bun add -d mcp-typegen
# or
npm install --save-dev mcp-typegen

Use programmatically:

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { generate } from "mcp-typegen";

const client = new Client({ name: "my-app", version: "1.0.0" }, { capabilities: {} });
await client.connect(myTransport);

const { files, tools } = await generate({
  servers: { midday: client },
  catalog: { format: "markdown" },
});

// `files` is a `relative-path -> content` map. Write it however you like.
for (const [path, content] of Object.entries(files)) {
  await writeFile(resolve("./generated", path), content);
}

generate(options)

Option Type Default Description
servers Record<string, Client> — Map of folder name -> connected MCP client
clientImportPath string "../../client.js" Where each tool file imports callMCPTool from
indexFiles boolean true Emit per-server index.ts
sanitize (name: string) => string built-in Override tool-name → identifier mapping
header string auto-warning File banner prepended to each emitted file
catalog CatalogOptions undefined Emit progressive-disclosure sidecar

Executor (types-only)

For sandbox authors. mcp-typegen ships zero runtime — this type is a shape to target:

import type { Executor, ExecuteResult } from "mcp-typegen";

interface ExecuteResult {
  result: unknown;
  error?: string;
  logs?: string[];
}
interface Executor {
  execute(
    code: string,
    fns: Record<string, (...args: unknown[]) => Promise<unknown>>,
  ): Promise<ExecuteResult>;
}

Mirrors Cloudflare's codemode Executor so sandboxes can be swapped.

CLI

Flag Description
--url <url> Connect over HTTP (streamable, falls back to SSE)
--stdio "<command>" Spawn an MCP server over stdio
--config <path> Read .mcp.json / .cursor/mcp.json / .vscode/mcp.json
--folder <name> Folder name for single-server usage (default: default)
-o, --out <dir> Output directory (default: ./servers-gen)
--catalog <fmt> Emit catalog sidecar: json or markdown
--detail <level> Catalog detail: names | summary | full
--header <K:V> HTTP header (repeatable)
--client-import <p> Override client import path in tool files
--no-index Skip emitting per-server index.ts

Examples

# single MCP server over HTTP
npx mcp-typegen --url https://api.midday.ai/mcp -o ./servers

# stdio-transported server
npx mcp-typegen --stdio "npx -y @modelcontextprotocol/server-memory" --folder memory -o ./servers

# multi-server from config
npx mcp-typegen --config .mcp.json -o ./servers

# with progressive-disclosure catalog
npx mcp-typegen --config .mcp.json --catalog markdown -o ./servers

# with auth header
npx mcp-typegen --url https://api.midday.ai/mcp --header "Authorization:Bearer $TOKEN" -o ./servers

Implementing callMCPTool

client.ts is emitted with a stub — you replace the body with a call to your MCP transport. Reference implementation for a stdio server:

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

let cached: Client | undefined;

async function getClient(): Promise<Client> {
  if (cached) return cached;
  const client = new Client({ name: "agent", version: "0.0.0" }, { capabilities: {} });
  const transport = new StdioClientTransport({
    command: "npx",
    args: ["-y", "@modelcontextprotocol/server-memory"],
  });
  await client.connect(transport);
  cached = client;
  return client;
}

export async function callMCPTool<T = unknown>(name: string, args: object): Promise<T> {
  const client = await getClient();
  const result = await client.callTool({ name, arguments: args as Record<string, unknown> });
  if (result.isError) {
    const text = Array.isArray(result.content)
      ? result.content.map((c) => (c as { text?: string }).text ?? "").join("\n")
      : "Tool call failed";
    throw new Error(text);
  }
  if (result.structuredContent !== undefined) return result.structuredContent as T;
  const first = Array.isArray(result.content) ? result.content[0] : undefined;
  const text = first && typeof first === "object" && "text" in first ? (first as { text?: string }).text : undefined;
  if (!text) return null as T;
  try { return JSON.parse(text) as T; } catch { return text as T; }
}

For HTTP or SSE transports, swap StdioClientTransport for StreamableHTTPClientTransport / SSEClientTransport.

CI workflow

# .github/workflows/codegen-check.yml
- run: bun run mcp-typegen --config .mcp.json -o ./servers
- run: git diff --exit-code servers/

If an MCP server changed and you forgot to regenerate, CI fails.

FAQ

How is this different from @cloudflare/codemode? Portable. No Workers coupling. Filesystem-tree output, not ambient global. Ship zero runtime, ship zero AI SDK wrapper.

How is this different from mcp-client-gen? Optimized for LLM code-mode, not human SDK ergonomics. Ships the progressive-disclosure catalog + Executor contract. Multi-server out of the box.

Does it ship a sandbox? No. See examples/full-agent/ for a node:vm recipe you can copy and adapt.

Does it support resources and prompts? Not in v0.1. Tools only. Track GitHub issues for updates.

Zod / runtime validation? Out of scope. Bring your own validator — the JSON Schema is preserved in the catalog if you need it.

Why no ambient .d.ts mode? Opinionated on Anthropic's filesystem shape. A ~30-line flatten recipe in examples/secure-exec-flatten/ covers ambient consumers.

How do I wire it into CI? npx mcp-typegen --config .mcp.json -o ./servers + git diff --exit-code step. Done.

Does it work with stdio servers? Yes, --stdio "node my-server.js".

Authentication? Bring a configured Client (with auth) when using generate() as a library. CLI accepts --header for HTTP transports.

Is the Executor type required? No. It's a shape to target for sandbox authors, not coupled to generate().

Not this package's job

  • Not a sandbox (ship zero executor implementations)
  • Not an agent framework (no LLM orchestration)
  • Not an AI SDK wrapper
  • Not an OAuth helper (bring a configured Client)
  • Not runtime validation (Zod, Ajv — your choice)
  • Not an ambient .d.ts emitter (opinionated on filesystem-tree)

License

MIT © Pontus Abrahamsson

README copy captured when this server was indexed; it may lag the repository. The original is authoritative.

Questions

About Typegen

How do I install Typegen?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Typegen safe to use with an AI agent?

Its trust score is 30 out of 100 (low). It passes 1 of the 1 static security checks run so far. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Typegen still maintained?

The last commit was 6 months ago. That's long enough that you should check whether the maintainer is responding to issues before depending on it.