Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

You can build a small Model Context Protocol (MCP) server in Node.js 22 by creating an ES-module project, registering a tool with an input schema and handler, and serving it over stdio. The official TypeScript SDK v2 guide requires Node.js 20 or later, so Node.js 22 meets its stated runtime minimum; the guide does not report a separate Node.js 22-specific test. This walkthrough follows the v2 package and API generation.

What this server does

An MCP server exposes capabilities that an MCP host or client can use. This example adds one tool: it accepts a name and returns a greeting. The SDK checks tool input against the declared schema before calling the handler.

The example follows the official TypeScript SDK v2 first-server tutorial. Use documentation that matches the package you install: v1 and v2 have different package names and API examples, so their snippets should not be combined.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Set up the project

The v2 tutorial uses ES modules and runs TypeScript directly with tsx, without a separate build step. From a new project directory, initialize npm, configure the project as an ES module, and install the required packages:

npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/server zod
npm install --save-dev tsx

The package and runtime choices here follow the official v2 setup. Node.js 22 satisfies the guide’s stated Node.js 20-or-later requirement, but that minimum is not a report of a dedicated Node.js 22 compatibility test.

Create a tool and serve it over stdio

Create src/server.ts and register a tool with a name, description, Zod input schema, and handler. Then pass the server factory to serveStdio:

import { McpServer, serveStdio } from "@modelcontextprotocol/server";
import { z } from "zod";

const server = new McpServer({
  name: "greeting-server",
  version: "1.0.0",
});

server.registerTool(
  "greet",
  {
    description: "Return a greeting for a person",
    inputSchema: {
      name: z.string().min(1).describe("The person's name"),
    },
  },
  async ({ name }) => ({
    content: [{ type: "text", text: `Hello, ${name}!` }],
  }),
);

await serveStdio(() => server);

The schema requires a non-empty string. If a client supplies input that does not satisfy the declared schema, the SDK rejects it before the handler runs. The handler returns the tool result as MCP text content.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep standard output reserved for protocol traffic. The official tutorial warns: “stdout is the protocol channel. Log with console.error — one console.log corrupts the JSON-RPC stream.” Send diagnostic messages to stderr with console.error; do not print banners, debugging output, or other text to stdout.

Launch and exercise the server

Run the TypeScript entry point with tsx:

npx tsx src/server.ts

For an interactive check, use MCP Inspector to connect to the server over stdio and invoke greet. Configure the Inspector to launch the command above, then provide a non-empty name value. A successful call returns the greeting as text; an empty or missing name fails schema validation rather than being passed to the handler.

Choose a transport for how clients connect

Stdio is the straightforward choice when an MCP host launches the server as a local process. If you need one remotely reachable endpoint for multiple clients, the v2 tutorial says the same server factory can be served over HTTP. The deployment shape and who owns the connection determine which transport fits:

Transport Typical deployment shape Guidance in the SDK material
stdio A local process launched by the host The v2 first-server tutorial uses this approach.
Streamable HTTP A remotely reachable server endpoint The v1 server guide describes it as the modern remote transport.
HTTP+SSE Older HTTP-based integrations The v1 guide presents it for backwards compatibility.

Those HTTP transport details come from the v1 documentation; follow the server guide for the SDK generation you are actually using rather than transplanting a v1 example into a v2 project.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Keep the SDK generation consistent

The official repository describes v2 as the stable SDK release line implementing the 2026-07-28 specification. It also says v1.x will continue to receive bug fixes and security updates for at least six months after v2’s release. Because the generations use different package names and APIs, check the matching documentation before copying setup commands or code.

For a first local server, the v2 path above gives you the essential pieces: a runtime and module setup, one schema-validated tool, a stdio launch, and an Inspector call. Move to a remote transport only when your clients need to reach a server endpoint rather than have a host start a local process.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.