Getting Started
A quick guide to get started using tmcp
You have two ways to setup your project with tmcp to start building your MCP server:
Using the cli
Run the CLI
pnpm create tmcp
npm init tmcp
yarn create tmcp
bun create tmcp
Follow the wizard 🧙🏻
The wizard will guide you towards the creation of a tmcp project. It will ask you for where do you want to create your project, which JSON schema adapter you want to use, which transport you want to use and if you want to include helpers to authenticate your MCP servers.
It will also ask you if you want to have an example MCP server that will create a file with the minimal boilerplate (using srvx in case you are building an HTTP server).
┌ 🚀 Welcome to create-tmcp!
│
◇ Where should we create your TMCP project?
│ my-awesome-mcp
│
◇ Which schema adapter would you like to use?
│ Valibot (Recommended)
│
◇ Which transports would you like to include?
│ STDIO, HTTP
│
◇ Would you like to include OAuth 2.1 authentication?
│ Yes
│
◇ Would you like to include an example MCP server?
│ Yes
│
◇ Where should we place the example server?
│ src/index.js
│
◇ Would you like to automatically install dependencies?
│ Yes
│
◇ Which package manager would you like to use?
│ pnpm (Recommended)
│
◇ Project created successfully!
│
◇ Next steps: ───────╮
│ │
│ cd my-awesome-mcp │
│ pnpm run dev │
│ │
├─────────────────────╯
│
└ Happy coding! 🎉
That's it
That's it, cd into your folder and start building your awesome mcp server!
Info
The installer will create a package.json with the latest version of the required dependencies. If you want you can also run the boilerplate CLI in an existing project and it merge with your existing package.json.
Manual installation
tmcp is very composable: what this means is that each functionality it's separated in it's own package so you only get the bare minimum dependencies depending on what you are building.
So to setup a project manually you need to follow some steps:
Install `tmcp`
pnpm add tmcp
npm i tmcp
yarn add tmcp
bun add tmcp
Choose a validation library
There are several adapters to convert from your validation library to JSON schema (the required format for the MCP protocol):
- Valibot
- Zod (v3 and v4)
- Arktype
- Effect
once you have picked your dependency install the validation library AND the relative tmcp adapter
pnpm add valibot @tmcp/adapter-valibot
npm i valibot @tmcp/adapter-valibot
yarn add valibot @tmcp/adapter-valibot
bun add valibot @tmcp/adapter-valibot
Pick your transport
The core tmcp library is just a JSON-rpc server...to communicate you need to install an adapter. You can pick between three different adapters
- STDIO: used to build local servers that can be published on
npmand communicate overstdinandstdout - HTTP: used to build remote servers. You can deploy them anywhere node/bun/deno run and use Streamable HTTP to communicate with your MCP client.
- SSE: also used to build remote servers. This transport is officially deprecated in the MCP spec so you should default to HTTP if possible.
pnpm add @tmcp/transport-stdio
npm i @tmcp/transport-stdio
yarn add @tmcp/transport-stdio
bun add @tmcp/transport-stdio
(Optional) Install the Auth helper
If you plan to use authentication for your MCP server tmcp you will need to act as an Authorization server. This can be challenging and that's why tmcp ships with a package dedicated to authentication. You can install it like this
pnpm add @tmcp/auth
npm i @tmcp/auth
yarn add @tmcp/auth
bun add @tmcp/auth
And use it in your transport.
(Optional) Install the Session manager helper
Building a remote MCP server at scale means either serverless or a distributed environment and that doesn't go well with the in-memory default behaviour of MCP servers. To ease that experience tmcp provides a session manager abstraction that solves two problems:
- when sending back notifications from the server (or if you are using the SSE transport) the handle of the SSE stream could be in a different server than the one receiving the POST request that triggers it
- all the information about the current MCP client (like client capabilities, client info, resources subscriptions) are stored in a different server than the one receiving the current POST request.
A session manager exports two classes that uses an external system (redis, postgres, cloudflare durable objects) to store this information and as a pub/sub dispatcher. Pick your player, install it like this:
pnpm add @tmcp/session-manager-redis
npm i @tmcp/session-manager-redis
yarn add @tmcp/session-manager-redis
bun add @tmcp/session-manager-redis
And use it in your transport.