LLM APIs and MCP in JavaScript Cheat Sheet

Call Claude from Node.js with the official TypeScript SDK, then build and connect MCP servers. Covers streaming, tool use, structured output, and error handling. You can also download the information as a printable cheat sheet:

Free Bonus: LLM APIs and MCP in JavaScript Cheat Sheet

Get the LLM APIs and MCP in JavaScript Cheat Sheet (PDF), a printable reference to Claude API calls in Node.js, streaming, tool use, structured output, retries, and building MCP servers and clients:

LLM APIs and MCP in JavaScript Cheat Sheet

Want a guided path instead of a reference? Start learning at realjs.com.

Setup and API Keys

  • Never hard-code keys: use env vars or a git-ignored .env
  • new Anthropic() reads ANTHROPIC_API_KEY
Language: Shell Filename: Install and Load Your Key
$ npm install @anthropic-ai/sdk
$ echo 'ANTHROPIC_API_KEY=sk-ant-...' > .env
$ node --env-file=.env app.ts
Language: TypeScript Filename: Create a Client
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();
const MODEL = "claude-sonnet-5-5";

Call Claude

  • max_tokens is required, system is top-level
  • content is an array of typed blocks
  • Stateless: resend the history, with assistant turns
Language: TypeScript Filename: Send a Message With a System Prompt
const msg = await client.messages.create({
  model: MODEL,
  max_tokens: 1024,
  system: "Answer in one line.",
  messages: [
    { role: "user", content: "Hi" },
  ],
});
msg.content[0];
// { type: "text", text: "Hello!" }
msg.stop_reason;          // "end_turn"

Streaming

  • Streaming avoids timeouts on long outputs
  • for await (const ev of stream) gives raw events
Language: TypeScript Filename: Print Tokens as They Arrive
const stream = client.messages.stream({
  model: MODEL,
  max_tokens: 1024,
  messages: [
    { role: "user", content: "Hi" },
  ],
});
stream.on("text", (t) => {
  process.stdout.write(t);
});
const final = await stream.finalMessage();

Structured Output

  • Schema in, validated object out
  • parsed_output is null if no text came back
  • Invalid JSON throws: check stop_reason
Language: TypeScript Filename: Parse Into a Zod Schema
import { z } from "zod";
import { zodOutputFormat }
  from "@anthropic-ai/sdk/helpers/zod";

const Code = z.object({
  functionName: z.string(),
  code: z.string(),
});
const msg = await client.messages.parse({
  model: MODEL,
  max_tokens: 1024,
  messages: [
    { role: "user", content: "Add" },
  ],
  output_config: {
    format: zodOutputFormat(Code),
  },
});
msg.parsed_output?.functionName;  // "add"

Errors and Retries

  • Retries (default 2) cover 429, 5xx, timeouts
  • Backoff is automatic, per request or client
Language: TypeScript Filename: Tune and Catch
const c = new Anthropic({
  maxRetries: 4,
  timeout: 30_000,
});
try {
  await c.messages.create(params, {
    maxRetries: 0,
  });
} catch (err) {
  if (err instanceof Anthropic.APIError) {
    console.log(err.status);   // 429
  } else throw err;
}

Tool Use

  • The model never runs code: it asks, you run
  • stop_reason: "tool_use" means a call is pending
  • Return failures with is_error: true
Language: TypeScript Filename: Describe a Tool With JSON Schema
const tools: Anthropic.Tool[] = [{
  name: "get_weather",
  description: "Get a city's weather",
  input_schema: {
    type: "object",
    properties: { city: { type: "string" } },
    required: ["city"],
  },
}];
Language: TypeScript Filename: Loop Until Claude Answers
const messages: Anthropic.MessageParam[] = [
  { role: "user", content: "Weather?" },
];
for (let step = 0; step < 10; step++) {
  const msg = await client.messages.create({
    model: MODEL, max_tokens: 1024,
    tools, messages,
  });
  messages.push({
    role: "assistant", content: msg.content,
  });
  if (msg.stop_reason !== "tool_use") break;
  const results = msg.content
    .filter((b) => b.type === "tool_use")
    .map((b) => ({
      type: "tool_result" as const,
      tool_use_id: b.id,
      content: run(b.name, b.input),
    }));
  messages.push({
    role: "user", content: results,
  });
}

Build an MCP Server

  • npm install @modelcontextprotocol/sdk zod
  • Tools act, resources expose data, prompts are templates
  • On stdio, log with console.error, never console.log
  • Running .ts directly needs Node 22.18+
Language: TypeScript Filename: Expose a Tool
import { McpServer } from
  "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from
"@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "weather", version: "1.0.0",
});
server.registerTool(
  "get_weather",
  {
    description: "Get a city's weather",
    inputSchema: { city: z.string() },
  },
  async ({ city }) => {
    const text = `Sunny in ${city}`;
    return {
      content: [{ type: "text", text }],
    };
  },
);
const transport = new StdioServerTransport();
await server.connect(transport);

Connect to an MCP Server

Language: TypeScript Filename: Call Tools From Node.js
import { Client } from
"@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from
"@modelcontextprotocol/sdk/client/stdio.js";

const mcp = new Client({
  name: "demo", version: "1.0.0",
});
await mcp.connect(new StdioClientTransport({
  command: "node", args: ["server.ts"],
}));
const { tools } = await mcp.listTools();
await mcp.callTool({
  name: "get_weather",
  arguments: { city: "Oslo" },
});
// { content: [{ type: "text",
//   text: "Sunny in Oslo" }] }
Language: TypeScript Filename: Hand MCP Tools to Claude
const claudeTools = tools.map((t) => ({
  name: t.name,
  description: t.description,
  input_schema: t.inputSchema,
}));
Language: Shell Filename: Register With Claude Code
$ claude mcp add weather -- node server.ts
Language: JSON Filename: Claude Desktop Config
{
  "mcpServers": {
    "weather": {
      "command": "node",
      "args": ["/abs/path/server.ts"]
    }
  }
}

You can download this information as a printable cheat sheet:

Free Bonus: LLM APIs and MCP in JavaScript Cheat Sheet

Get the LLM APIs and MCP in JavaScript Cheat Sheet (PDF), a printable reference to Claude API calls in Node.js, streaming, tool use, structured output, retries, and building MCP servers and clients:

LLM APIs and MCP in JavaScript Cheat Sheet