Skip to main content
An MCP server is a program that gives Claude tools it can call, and people who use Claude see it as a connector. In this quickstart you write one in about 50 lines of JavaScript with no build step: a server with a single roll_dice tool that runs on your machine, which you then connect to Claude Code, Anthropic’s command-line coding tool, and watch Claude call. At the end you have a working server you understand line by line, ready to grow into your own product’s tools, wrap in a plugin, or host for people on claude.ai. This quickstart is for developers who haven’t built an MCP server before and want to see every piece working before they add authentication, hosting, and real tools.

Before you begin

Check that you have each of these:
  • Node.js 18 or later: run node --version to check. The steps on this page were verified with Node.js 22
  • npm: included with Node.js
  • Claude Code: install Claude Code and sign in. You use it in the last part to connect to the server and call the tool, and claude -p needs a signed-in account to send the prompt
  • Two terminal windows: one keeps the server running while you run commands in the other

Create the project

The project is a folder with a package.json and two dependencies: the MCP TypeScript SDK, which also works from plain JavaScript, and zod, which the SDK uses to describe tool inputs.
1

Make a folder for the server

In your terminal, create a folder named mcp-quickstart and move into it. Every later command on this page runs from this folder:
2

Create package.json

Create a default package.json, then set "type": "module" in it so Node.js treats the project’s files as ES modules:
3

Install the SDK

Install the SDK and zod. You don’t install a web framework separately, because the SDK depends on Express and gives you a ready-made app for it:
To confirm what installed, run npm ls --depth=0. The output lists the two packages and their versions:
This page was verified with those versions.

Write the server

The whole server is one file. Create server.mjs in the mcp-quickstart folder and paste in the code below. The highlighted lines matter most: the McpServer that Claude connects to, the registerTool call that describes roll_dice and its inputs, and the /mcp route that receives each request over Streamable HTTP.
server.mjs
Each part of the file has one job:
  • McpServer: the object that speaks MCP. Its name and version are what a client sees when it connects
  • registerTool: adds roll_dice. A tool is a function your server offers to Claude, and Claude decides when to call it from the description. The inputSchema tells the client that sides is a whole number from 2 to 100 and that count is optional and defaults to 1
  • The handler: rolls the dice and returns one text block. Whatever you put in content is the tool result Claude reads
  • The /mcp route: the SDK’s Express app listens on 127.0.0.1:3000, and each POST to /mcp is one MCP request. The server keeps no session between requests, which is the simplest shape and enough for tools like this one
  • The listen callback: prints the address when the server is up, or the reason and exits if the port is already in use

Run and test the server

Before you involve Claude, start the server and send it MCP requests yourself with curl, so you know it works on its own.
1

Start the server

In your first terminal, from the mcp-quickstart folder, start the server:
It prints the address it’s listening on and keeps running:
Leave this terminal open. If you see failed to listen on 3000 instead, another program is using the port. Stop that program and run the command again.
2

List the server's tools

In your second terminal, ask the server what tools it has. This is the same tools/list request Claude sends when it connects. The Accept header is required, and the server answers 406 Not Acceptable without it:
The reply is one server-sent event whose data line lists roll_dice with the title, description, and input schema you wrote. The inputSchema object is shortened to ... here:
3

Call the tool

Call roll_dice directly with three 20-sided dice, which is the tools/call request Claude sends when it uses the tool:
The data line carries the text your handler returned, with your own random rolls:

Connect the server to Claude Code

With the server answering on its own, register it with Claude Code and have Claude call the tool from a prompt. Run these commands in your second terminal from the mcp-quickstart folder, because claude mcp add saves the server for the current project folder by default, and Claude Code only sees it when you run from that same folder.
1

Add the server to Claude Code

Register the server under the name quickstart, with the HTTP transport and the local URL:
Claude Code confirms where it saved the entry:
2

Check the connection

List your servers. Claude Code connects to each one to check its health:
A working server shows as connected:
If it shows an error instead, check that node server.mjs is still running in the first terminal.
3

Ask Claude to roll dice

Send Claude one prompt with claude -p, which runs a single prompt without opening an interactive session and prints the answer. Claude Code names MCP tools mcp__<server>__<tool>, so your tool is mcp__quickstart__roll_dice, and --allowedTools lets Claude call it without stopping to ask you:
Claude calls your server and reports the rolls it got back:
4

Confirm the tool ran

To see the tool call itself rather than Claude’s summary of it, run the same prompt with streaming JSON output. --output-format stream-json needs --verbose alongside it:
The output is one JSON object per line, and other tool calls can appear before yours. Look for the tool_use block whose name is mcp__quickstart__roll_dice, carrying the arguments Claude chose, and the tool_result block after it carrying your server’s text, shown here with the surrounding fields removed:
In an interactive claude session you can ask the same thing in your own words. Without --allowedTools, Claude Code asks for your permission before it calls roll_dice.

Put the server in front of claude.ai users

Claude Code reached your server because both run on your machine. When someone adds a connector by URL on claude.ai, in the Claude desktop and mobile apps, or in Cowork, Claude connects to it from Anthropic’s infrastructure over the internet, so a localhost address isn’t reachable from there. To use this server on those surfaces, you host it at a public HTTPS URL and people add that URL as a connector. Once the server has a public URL, these pages cover each step:

Clean up

When you’re done, stop the server by pressing Ctrl+C in the first terminal. Then, from the mcp-quickstart folder, remove the entry from Claude Code:
Claude Code confirms with Removed MCP server "quickstart" from local config.

Next steps