A minimal Model Context Protocol server template for Render. Fork it, add your own tools, and deploy.
- A working MCP server using the official TypeScript SDK with Streamable HTTP transport
- Bearer token authentication via
MCP_API_TOKEN(auto-generated on deploy) - One example tool (
hello) to show the pattern - A
/healthendpoint for Render's health checks - A
render.yamlBlueprint for one-click deployment - An
AGENTS.mdso AI coding assistants can scaffold new tools for you
Note: This template deploys on the free plan by default. Free services spin down after 15 minutes of inactivity, causing cold starts of 30-60 seconds on the next request. MCP clients may time out during this delay. For reliable use, upgrade to a paid plan in the Render Dashboard — the Starter plan keeps your service running continuously.
git clone https://github.com/render-examples/mcp-server-typescript.git
cd mcp-server-typescript
npm install
npm run build
npm startThe server starts on http://localhost:10000. The MCP endpoint is at /mcp.
npm install
npm testThe server authenticates requests using a bearer token. Render's Blueprint auto-generates a random MCP_API_TOKEN on first deploy.
To find your token after deploying, go to Render Dashboard > your service > Environment and copy the MCP_API_TOKEN value.
Clients must include the token in the Authorization header:
Authorization: Bearer YOUR_TOKEN
When MCP_API_TOKEN is not set (e.g., during local development), authentication is disabled and all requests are allowed through.
After the initial deploy, the token is yours to manage:
- Rotate it by updating
MCP_API_TOKENin the Render Dashboard under Environment. The service restarts automatically with the new value. - Generate a new token with any of these:
openssl rand -base64 32node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"- A password manager's generator (1Password, Bitwarden, etc.)
- Don't commit tokens to source control. Use environment variables or
.envfiles (which are in.gitignore). - For multi-user or production setups, consider upgrading to OAuth 2.1.
After deploying to Render, your MCP endpoint is available at:
https://your-service-name.onrender.com/mcp
Add to your project's .cursor/mcp.json:
{
"mcpServers": {
"my-mcp-server": {
"url": "https://your-service-name.onrender.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}Add to your Claude Desktop config:
{
"mcpServers": {
"my-mcp-server": {
"type": "streamable-http",
"url": "https://your-service-name.onrender.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}codex mcp add --transport streamable-http \
--url https://your-service-name.onrender.com/mcp \
--header "Authorization: Bearer YOUR_TOKEN" \
my-mcp-serverOr add to .codex/config.toml:
[mcp_servers.my-mcp-server]
url = "https://your-service-name.onrender.com/mcp"
http_headers = { Authorization = "Bearer YOUR_TOKEN" }Add tools inside the createServer() function in src/app.ts:
server.registerTool(
"fetch-weather",
{
description: "Get the current weather for a city",
inputSchema: {
city: z.string(),
units: z.string().default("celsius"),
},
},
async ({ city, units }) => ({
content: [{ type: "text", text: `Weather for ${city} in ${units}` }],
}),
);The description is what MCP clients show to LLMs. Always write a clear one.
This repo includes an
AGENTS.mdfile. If you use an AI coding assistant (Cursor, Copilot, Codex, Windsurf, etc.), you can ask it to "add a new tool" and it will follow the conventions inAGENTS.mdautomatically.
src/app.ts App setup: tools, auth middleware, routes
src/server.ts Entrypoint: imports app and starts listening
package.json Dependencies and scripts
tsconfig.json TypeScript compiler configuration
render.yaml Render Blueprint for deployment
.env.example Environment variable reference
tests/server.test.ts Test suite (auth, health, tool calls)
vitest.config.ts Vitest configuration
AGENTS.md Instructions for AI coding assistants
CLAUDE.md Pointer to AGENTS.md for Claude Code