MCP-SERVER-TEMPLATE
A TypeScript-based starter template for building Model Context Protocol servers that enables AI assistants to dynamically call tools, interpret prompts, and manage resources through modular architecture with support for multiple transport methods.
README
MCP-SERVER-TEMPLATE
Welcome to MCP-SERVER-TEMPLATE, a template project for implementing a Model Context Protocol (MCP) server using the official TypeScript SDK. This project provides a foundation for building stateless and stateful MCP servers, with support for different transport mechanisms such as HTTP and standard I/O (stdio).
Table of Contents
- Overview
- Prerequisites
- Installation
- Configuration
- Running the Server
- Testing
- Code Formatting
- Project Structure
- Troubleshooting
- Contributing
- License
- Acknowledgments
Overview
This project, MCP-SERVER-TEMPLATE, is a TypeScript-based starter template for building Model Context Protocol (MCP) servers using the official SDK. The server acts as an interface between user queries and tool execution, enabling AI assistants and external systems to dynamically call tools, interpret prompts, and manage resources in a modular and extensible way.
Key Capabilities
- Modular Architecture: The project is divided into clear modules for configuration, transport management, tool registration, server orchestration, and utility helpers—promoting separation of concerns and ease of maintenance.
- Transport Abstraction: Built-in support for multiple transport types including:
- HTTP (Stateless): Each request spins up a new MCP server instance for full isolation and compliance with RESTful practices.
- STDIO (Stateful): For desktop or CLI-based integrations requiring persistent communication.
- Easily extendable to future transports such as SSE or WebSocket via a unified interface and factory pattern.
- Dependency Injection: A custom DI system injects services like configuration and logging into tools and transport layers—ensuring testability and decoupling.
- Tool System: Tools are isolated classes that define:
- A unique name and description
- A Zod schema for input validation
- An
executefunction to handle business logic - Auto-generated JSON schema for external introspection
- Prompt & Resource Extensibility: Scaffolding is included to support prompt templates and dynamic resource fetching, allowing future integration with LLMs for prompt orchestration or retrieval-augmented generation (RAG) use cases.
- Built-in Testing & Debugging:
- MCP Inspector: GUI for visualizing tool calls, input/output flows, and live debugging.
- HTTP Test Script: Sends JSON-RPC requests to test endpoint responses.
- Unit Tests: Jest-based testing framework for tool and utility logic.
- Configurable & Secure: Easily adjustable through
.envand runtime configuration files for:- Auth credentials and API keys
- Server ports and transport options
- Logging levels and session behaviors
Use Cases
This template is ideal for:
- Building conversational MCP servers
- Creating a backend to manage callable tools for LLM-based workflows
Whether you're prototyping an LLM toolchain, integrating with proprietary systems, or preparing a scalable production MCP assistant backend—this project offers a ready-to-extend and thoroughly structured solution.
Prerequisites
- Node.js (version 18.x or later recommended)
- npm (Node Package Manager)
- Git (for cloning the repository)
Installation
-
Clone the repository:
git clone xxxx cd mcp-server-template -
Install dependencies:
npm installThis will install both production dependencies (e.g.,
@modelcontextprotocol/sdk,express,axios) and development dependencies (e.g.,typescript,ts-node,jest) as defined inpackage.json. -
Ensure the
@modelcontextprotocol/sdkpackage (version^1.10.1) is installed, as it is the core dependency for MCP functionality.
Configuration
The project uses a configuration system managed through environment variables and two key files in src/core/config/. Settings are defined in ConfigService and runtimeConfig, allowing customization of transport types, logging, and external API integrations.
Configuration Options
- Environment Variables (loaded via
dotenvinruntimeConfig.ts):TRANSPORT_TYPE: Sets the transport mechanism ('http'or'stdio', default:'stdio').HTTP_PORT: Port for the HTTP server (default:3000).HTTP_HOST: Host for the HTTP server (default:localhost).SESSION_SUPPORT: Enables/disables session support (default:'true').LOG_LEVEL: Logging level (e.g.,'info','debug', default:'info').MCP_INSPECTOR_PORT: Port for MCP inspector (default:6274).
Example Configuration
Set environment variables in a .env file:
TRANSPORT_TYPE=http
HTTP_PORT=3000
HTTP_HOST=localhost
LOG_LEVEL=debug
Running the Server
The server is started via the entry point src/index.ts, which orchestrates the initialization and startup process using dependency injection and configuration settings.
Startup Process
- Environment Setup:
index.tsloads environment variables usingdotenvto ensure configuration settings (e.g.,TRANSPORT_TYPE,HTTP_PORT) are available. - Dependencies Initialization: Uses
createDependenciesto set up shared dependencies like the logger andConfigService. - Transport Configuration: The transport (
HttpTransportorStdioTransport) is configured viaruntimeConfigbased on theTRANSPORT_TYPEsetting. - Server Initialization: Creates an
MCPServerinstance with the configured transport and dependencies. - Server Start: Asynchronously starts the server, handling any fatal errors by logging and exiting with a failure code.
Starting the Server
-
Production Mode:
-
Build the project to compile TypeScript to JavaScript:
npm run buildThis runs
tscto generate thedist/folder with compiled JavaScript files. -
Start the server:
npm startThis executes
node dist/index.jsto run the compiled server. -
For
http, the server listens onhttp://localhost:3000/mcp(port and host configurable viaHTTP_PORTandHTTP_HOST). -
For
stdio, the server reads from and writes to the console.
-
-
Development Mode:
- Run the server directly with TypeScript using
ts-node:
This executesnpm run devts-node src/index.ts, allowing for faster iteration without a build step.
- Run the server directly with TypeScript using
Notes
- Ensure environment variables or
runtimeConfigsettings are correctly set before starting the server. - Check the console output for logs (controlled by
LOG_LEVEL) to verify the server started successfully.
Testing
The project includes several scripts to test the server, debug its behavior, and verify functionality using automated tests and the MCP Inspector.
Unit Tests
Run unit tests using Jest to verify the functionality of individual components:
npm test
This executes jest, running all tests defined in the project (e.g., testing tools, utilities, or server logic). Ensure test files are set up with Jest and ts-jest for TypeScript support.
HTTP Transport Test
A test script is provided for the HTTP transport to verify basic functionality of the MCP server.
Script Details (src/scripts/testHttpTransport.js)
- Purpose: Tests the HTTP transport by sending a JSON-RPC
tools/listrequest to the server and validating the response. - Dependencies:
- Uses
axiosto send HTTP POST requests to the server.
- Uses
- Functionality:
- Sends a JSON-RPC 2.0 request to
http://localhost:3000/mcpwithmethod: 'tools/list',id: 1, and appropriate headers. - Validates the response to ensure:
- The response adheres to JSON-RPC 2.0 (
jsonrpc: '2.0'). - The response
idmatches the request (id: 1). - The response contains a
resultfield with the expectedtoolskey.
- The response adheres to JSON-RPC 2.0 (
- Logs a success message with the response data if valid, or an error with the received data if the format is unexpected.
- Sends a JSON-RPC 2.0 request to
- Error Handling:
- Catches and logs any request failures (e.g., network errors, server not running) with the error message.
Running the Test
- Ensure the server is running with
TRANSPORT_TYPEset to'http':npm start - Run the test script:
This executesnpm run test:httpts-node src/scripts/testHttpTransport.ts.
Combined Start and Test
To start the server and run the HTTP test in one command:
npm run mcp:http
This runs npm run start & npm run test:http, starting the server in the background and immediately running the HTTP test script.
Expected Output
- Success Case: If the server responds correctly, the script logs:
✅ HTTP transport responded correctly to tools/list Response: { "tools": [ { "name": "calculator_tool", "description": "Performs basic arithmetic operations: add, subtract, multiply, divide.", "inputSchema": {...} } ] } - Failure Case (Invalid Response Format): If the response format is unexpected, the script logs:
❌ Response received, but unexpected format Received: {...} - Failure Case (Request Fails): If the request fails (e.g., server not running), the script logs:
❌ HTTP request failed: <error message>
Notes
- The script assumes the server is running on
http://localhost:3000/mcp. Adjust theendpointin the script ifHTTP_PORTorHTTP_HOSTis different. - Ensure tools like
CalculatorToolare registered to see them in thetools/listresponse.
MCP Inspector Debugging
The MCP Inspector is a powerful tool for debugging and monitoring the MCP server, providing a Web UI to inspect server state and interactions.
Script Details (src/scripts/mcpInspectorScript.ts)
- Purpose: Launches the MCP Inspector, waits for its Web UI to be ready, and opens it in a browser for debugging the MCP server locally using stdio transport.
- Dependencies:
- Uses
child_processto spawn themcp-inspectorprocess and execute browser-opening commands. - Uses
axiosto check if the MCP Inspector Web UI is reachable. - Leverages dependency injection via
createDependencies()to accessConfigServicefor port configuration.
- Uses
- Functionality:
- Spawns the
mcp-inspectorprocess usingnpx mcp-inspector node dist/index.js, inheriting stdio for console output. - Implements
waitUntilInspectorIsReadyto poll the Web UI (default port:6274, configurable viaMCP_INSPECTOR_PORT) with retries (20 attempts, 500ms delay). - Opens the Web UI in a platform-specific browser:
- macOS:
open - Windows:
start - Linux:
xdg-open
- macOS:
- Logs a launch summary table with URLs:
- MCP Inspector UI:
http://localhost:6274(or configured port) - MCP Proxy Server:
http://localhost:6277
- MCP Inspector UI:
- Spawns the
- Error Handling:
- Retries if the Web UI isn’t immediately available.
- Throws an error and exits if the inspector fails to start after retries.
- Kills the inspector process on failure and logs a message to manually check or restart.
Running the MCP Inspector
- Ensure the server is compiled (e.g.,
npm run buildto generatedist/index.js). - Run the MCP Inspector script:
This executesnpm run mcp:inspectorts-node src/scripts/start-mcp-inspector.ts.
Combined Build and Inspector
To build the project and launch the MCP Inspector in one command:
npm run mcp:dev
This runs npm run build && npm run mcp:inspector, ensuring the project is compiled before starting the inspector.
Debugging Tips
- Use the MCP Inspector UI to monitor server requests, tool calls, and responses.
- Check the console output for startup logs or errors if the inspector fails to launch.
- Verify
MCP_INSPECTOR_PORTis not in use by another service.
Code Formatting
The project uses Prettier to maintain consistent code formatting across all files.
Format Code
To format all files in the project:
npm run format
This executes prettier --write ., automatically formatting all supported files (e.g., .ts, .js, .json).
Check Formatting
To check if all files adhere to the Prettier formatting rules:
npm run format:check
This executes prettier --check ., reporting any files that do not conform to the formatting rules without modifying them.
Project Structure
-
src/core/config/-
configService.ts: ImplementsConfigService, a class for managing server configuration. It loads settings from environment variables with defaults for transport type, HTTP server settings, logging level, API URLs (e.g., MealDB), authentication credentials, and MCP inspector port. -
runtimeConfig.ts: Defines runtime configuration usingdotenvto load environment variables. It sets up transport configuration (transportType, port) and authentication strategy (authStrategy,tokenSecret,username,password).
-
-
src/core/dependencies/dependencies.ts: Implements dependency injection with theDependenciesinterface, providing alogger(using Winston) and aConfigServiceinstance. ThecreateDependenciesfunction dynamically configures logging transports based ontransportType(stderr forstdio, stdout for others, plus a file logcombined.log), and exports a singletonloggerfor global use.
-
src/core/server/-
transports/-
http/ -
server.ts: ImplementsHttpTransport, a stateless HTTP transport using Express. It handlesPOST /mcprequests, processes JSON-RPC messages with optional Bearer token authentication, stores responses in aResponseMap, and supports sending responses asynchronously. It relies on dependency-injectedDependenciesfor logging and configuration.stdio/
-
server.ts: ImplementsStdioTransport, a transport using the SDK’sStdioServerTransport. It manages stdin/stdout communication, starts and closes the transport, and handles message sending with error logging via dependency-injectedDependencies.-
baseTransport.ts: Defines theBaseTransportinterface and abstractAbstractTransportclass, extending the SDK’sTransportinterface. It specifies methods (start,send,close,isRunning) and event handlers (onmessage,onerror,onclose) for transport implementations, providing a common contract forHttpTransportandStdioTransport. -
transportFactory.ts: ImplementsTransportFactory, a static class that creates instances ofHttpTransportorStdioTransportbased on theTransportConfigtype (e.g.,'http'or'stdio'). It uses dependency injection withDependenciesto provide logging and configuration, throwing an error for unsupported transport types.
-
-
-
mcpServer.ts: ImplementsMCPServer, the core server class that integrates the MCP SDK’sServerwith a transport (HttpTransportorStdioTransport). It initializes the server, sets up aRequestHandlerwith aToolRegistry, connects the transport, and handles message passing, errors, and responses using dependency-injectedDependenciesfor logging. -
requestHandler.ts: ImplementsRequestHandler, which registers handlers fortools/listandtools/callrequests using the MCP SDK. It lists available tools and executes tool calls with validated arguments (via Zod), supporting authentication tokens and throwing errors for invalid tools (ToolNotFoundError) or arguments (ValidationError). It uses dependency-injectedDependenciesfor logging.
-
-
src/core/toolManagement/-
toolFactory.ts: ImplementsToolFactory, a class that creates instances of tools (e.g.,calculatorTool) using dependency injection withDependencies. It defines a genericToolConstructortype and handles instantiation errors with logging. -
toolRegistry.ts: ImplementsToolRegistry, a class that manages tool registration and retrieval. It usesToolFactoryto instantiate tools fromtoolClasses, stores them in aMap, and provides methods to register, get, and list tools with their metadata (name, description, input schema). It logs loading status and errors via dependency-injectedDependencies. -
errors.ts: Defines custom error classes for tool management, includingToolNotFoundError(thrown when a requested tool isn’t registered) andValidationError(thrown when tool arguments fail validation, e.g., via Zod). -
types.ts: Defines TypeScript types for transport and authentication configurations. IncludesTransportType('stdio','sse','http'),TransportConfig(with options for SSE or HTTP and authentication),SSETransportConfig(port, CORS, auth),HttpStreamTransportConfig(port, response mode, CORS, session, resumability, auth), andAuthConfig(strategy, credentials).
-
-
src/prompts/: Directory for prompt templates (currently empty, reserved for future implementation). -
src/resources/: Directory for resource management (currently empty, reserved for future implementation). -
src/scripts/-
testHttpTransport.js: Test script for the HTTP transport to verify basic functionality by sending atools/listrequest and validating the response. -
mcpInspectorScript.ts: Script to launch the MCP Inspector, wait for its Web UI to be ready, and open it in a browser for debugging the MCP server. It uses dependency injection to accessConfigServicefor port configuration and handles platform-specific browser opening.
-
-
src/tools/-
types/-
ITool.ts: Defines theIToolinterface for tools, specifyingname,description,schema(Zod type),jsonSchema, and theexecutemethod for processing JSON-RPCCallToolRequest. ExportsDependenciesfor tool implementations. -
baseTool.ts: Implements an abstractBaseToolclass that reduces boilerplate, handles dependency injection withDependencies, and automatically converts Zod schemas to JSON schemas usingzod-to-json-schemafor introspection, documentation, and UI generation. -
index.ts: ExportstoolClassesas an array of tool constructors (e.g.,CalculatorTool) for dynamic loading by theToolRegistry, allowing easy extension with new tools. -
calculatorTool.ts: ImplementsCalculatorTool, a concrete tool that performs basic arithmetic operations (add,subtract,multiply,divide) with input validation via Zod, error handling (e.g., division by zero usingHttpError), and logging via dependency-injectedDependencies.
-
-
utils/-
httpUtils.ts: Provides utility functions for HTTP operations, includingserviceRequestfor making authenticated HTTP requests (OAuth2 or API key) with retries and timeout handling,getAuthTokenfor fetching and caching OAuth2 tokens,buildQueryStringfor creating query strings, andvalidateResponsefor response validation. It integrates withConfigServicefor configuration. -
index.ts: Exports utility functions for use in tools and other components.
-
-
-
src/index.ts: Entry point to start the MCP server. Loads environment variables usingdotenv, initializes dependencies withcreateDependencies, creates anMCPServerinstance with the transport fromruntimeConfig, and starts the server asynchronously, handling fatal errors by logging and exiting.
Troubleshooting
-
"Server not initialized" Error:
- Ensure handlers are registered and capabilities are set in the
MCPServersetup (viaRequestHandler). - Verify the transport is connected immediately before handling each request (for HTTP).
- Use the stateless approach (new server per request) if the error persists with a reused server.
- Ensure handlers are registered and capabilities are set in the
-
Performance Issues:
- Creating a new server per request may impact performance under high load. Consider reusing a single
MCPServerwith session management if needed, but test thoroughly.
- Creating a new server per request may impact performance under high load. Consider reusing a single
-
Configuration Issues:
- Ensure environment variables are correctly set in a
.envfile or passed directly to the process. - Check
ConfigServicelogs to verify loaded settings if external API integrations (e.g., MealDB, OMDB) fail.
- Ensure environment variables are correctly set in a
-
Logging Issues:
- Verify
LOG_LEVELenvironment variable matches expected levels (e.g.,'info','debug'). - For
stdiotransport, ensure logs are directed to stderr as intended; checkcombined.logfor file-based logs.
- Verify
-
Transport Issues:
- For
HttpTransport, ensure the port is available and no conflicting services are running. - For
StdioTransport, check stdin/stdout availability if no messages are processed. - If
TransportFactoryfails, verifyTRANSPORT_TYPEmatches a supported type ('http'or'stdio') in the configuration.
- For
-
Request Handling Issues:
- If
tools/listortools/callrequests fail, checkToolRegistryfor registered tools. - Validate tool arguments against the schema in
CallToolRequestSchemato avoidValidationError. - Ensure authentication tokens are provided if required by tools.
- If
-
Tool Management Issues:
- If tools fail to load, verify
toolClassesinsrc/tools/index.tsincludes valid tool implementations. - Check
ToolFactorylogs for instantiation errors and ensureDependenciesare properly injected.
- If tools fail to load, verify
-
MCP Inspector Issues:
- If the MCP Inspector fails to start, verify
MCP_INSPECTOR_PORT(default:6274) is not in use. - Ensure
dist/index.jsexists by runningnpm run buildbefore launching the script. - Check console output for errors during startup, such as network issues or missing dependencies.
- If the MCP Inspector fails to start, verify
-
HTTP Request Issues:
- If
serviceRequestfails, verify theauthType,authEndpoint,clientId,clientSecret, orapiKeysettings inConfigService. - Check for network issues or server errors (5xx) that may trigger retries.
- Ensure the request URL and method are correct, and validate the response schema with
validateResponse.
- If
-
HTTP Transport Test Issues:
- If the
testHttpTransport.jsscript fails, ensure the server is running withTRANSPORT_TYPE='http'and listening onhttp://localhost:3000/mcp. - Verify the port and host match the script’s
endpoint(adjust ifHTTP_PORTorHTTP_HOSTis different). - Check for registered tools in
ToolRegistry; an emptytoolsarray may indicate a tool loading issue.
- If the
-
Testing Issues:
- If
npm testfails, ensure Jest is configured correctly withts-jestfor TypeScript support, and verify that test files exist. - If
npm run mcp:inspectorornpm run mcp:devfails, check that@modelcontextprotocol/inspectoris installed and the server is compiled (dist/index.jsexists).
- If
-
Formatting Issues:
- If
npm run format:checkreports issues, runnpm run formatto automatically fix formatting, or manually adjust the files to match Prettier’s rules.
- If
Contributing
Feel free to submit issues or pull requests on the GitHub repository. Contributions to improve the server implementation, add new features, or optimize performance are welcome!
License
This project is licensed under the ISC License. See the LICENSE file for details.
Acknowledgments
- Built using the
@modelcontextprotocol/sdk - Inspired by examples in the typescript-sdk repository.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.