Integrations
Loads environment variables from .env files for server configuration, enabling customization of transport types, HTTP settings, authentication, and logging options.
Provides HTTP request utilities through the 'serviceRequest' function in httpUtils.ts, supporting authenticated API requests with OAuth2 or API key authentication, retries, and response validation.
Implements the HTTP transport layer using Express to handle POST requests to the /mcp endpoint, process JSON-RPC messages, and support stateless request handling.
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
execute
function 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
.env
and 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:Copy
- Install dependencies:This will install both production dependencies (e.g.,Copy
@modelcontextprotocol/sdk
,express
,axios
) and development dependencies (e.g.,typescript
,ts-node
,jest
) as defined inpackage.json
. - Ensure the
@modelcontextprotocol/sdk
package (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
dotenv
inruntimeConfig.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:
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.ts
loads environment variables usingdotenv
to ensure configuration settings (e.g.,TRANSPORT_TYPE
,HTTP_PORT
) are available. - Dependencies Initialization: Uses
createDependencies
to set up shared dependencies like the logger andConfigService
. - Transport Configuration: The transport (
HttpTransport
orStdioTransport
) is configured viaruntimeConfig
based on theTRANSPORT_TYPE
setting. - Server Initialization: Creates an
MCPServer
instance 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:This runsCopy
tsc
to generate thedist/
folder with compiled JavaScript files. - Start the server:This executesCopy
node dist/index.js
to run the compiled server. - For
http
, the server listens onhttp://localhost:3000/mcp
(port and host configurable viaHTTP_PORT
andHTTP_HOST
). - For
stdio
, the server reads from and writes to the console.
- Build the project to compile TypeScript to JavaScript:
- Development Mode:
- Run the server directly with TypeScript using
ts-node
:This executesCopyts-node src/index.ts
, allowing for faster iteration without a build step.
- Run the server directly with TypeScript using
Notes
- Ensure environment variables or
runtimeConfig
settings 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:
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/list
request to the server and validating the response. - Dependencies:
- Uses
axios
to send HTTP POST requests to the server.
- Uses
- Functionality:
- Sends a JSON-RPC 2.0 request to
http://localhost:3000/mcp
withmethod: '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
id
matches the request (id: 1
). - The response contains a
result
field with the expectedtools
key.
- 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_TYPE
set to'http'
:Copy - Run the test script:This executesCopy
ts-node src/scripts/testHttpTransport.ts
.
Combined Start and Test
To start the server and run the HTTP test in one command:
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:Copy
- Failure Case (Invalid Response Format): If the response format is unexpected, the script logs:Copy
- Failure Case (Request Fails): If the request fails (e.g., server not running), the script logs:Copy
Notes
- The script assumes the server is running on
http://localhost:3000/mcp
. Adjust theendpoint
in the script ifHTTP_PORT
orHTTP_HOST
is different. - Ensure tools like
CalculatorTool
are registered to see them in thetools/list
response.
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_process
to spawn themcp-inspector
process and execute browser-opening commands. - Uses
axios
to check if the MCP Inspector Web UI is reachable. - Leverages dependency injection via
createDependencies()
to accessConfigService
for port configuration.
- Uses
- Functionality:
- Spawns the
mcp-inspector
process usingnpx mcp-inspector node dist/index.js
, inheriting stdio for console output. - Implements
waitUntilInspectorIsReady
to 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 build
to generatedist/index.js
). - Run the MCP Inspector script:This executesCopy
ts-node src/scripts/start-mcp-inspector.ts
.
Combined Build and Inspector
To build the project and launch the MCP Inspector in one command:
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_PORT
is 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:
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:
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 usingdotenv
to 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 theDependencies
interface, providing alogger
(using Winston) and aConfigService
instance. ThecreateDependencies
function dynamically configures logging transports based ontransportType
(stderr forstdio
, stdout for others, plus a file logcombined.log
), and exports a singletonlogger
for global use.
src/core/server/
transports/
http/
server.ts
: ImplementsHttpTransport
, a stateless HTTP transport using Express. It handlesPOST /mcp
requests, processes JSON-RPC messages with optional Bearer token authentication, stores responses in aResponseMap
, and supports sending responses asynchronously. It relies on dependency-injectedDependencies
for 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 theBaseTransport
interface and abstractAbstractTransport
class, extending the SDK’sTransport
interface. It specifies methods (start
,send
,close
,isRunning
) and event handlers (onmessage
,onerror
,onclose
) for transport implementations, providing a common contract forHttpTransport
andStdioTransport
.transportFactory.ts
: ImplementsTransportFactory
, a static class that creates instances ofHttpTransport
orStdioTransport
based on theTransportConfig
type (e.g.,'http'
or'stdio'
). It uses dependency injection withDependencies
to provide logging and configuration, throwing an error for unsupported transport types.
mcpServer.ts
: ImplementsMCPServer
, the core server class that integrates the MCP SDK’sServer
with a transport (HttpTransport
orStdioTransport
). It initializes the server, sets up aRequestHandler
with aToolRegistry
, connects the transport, and handles message passing, errors, and responses using dependency-injectedDependencies
for logging.requestHandler.ts
: ImplementsRequestHandler
, which registers handlers fortools/list
andtools/call
requests 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-injectedDependencies
for logging.
src/core/toolManagement/
toolFactory.ts
: ImplementsToolFactory
, a class that creates instances of tools (e.g.,calculatorTool
) using dependency injection withDependencies
. It defines a genericToolConstructor
type and handles instantiation errors with logging.toolRegistry.ts
: ImplementsToolRegistry
, a class that manages tool registration and retrieval. It usesToolFactory
to 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/list
request 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 accessConfigService
for port configuration and handles platform-specific browser opening.
src/tools/
types/
ITool.ts
: Defines theITool
interface for tools, specifyingname
,description
,schema
(Zod type),jsonSchema
, and theexecute
method for processing JSON-RPCCallToolRequest
. ExportsDependencies
for tool implementations.baseTool.ts
: Implements an abstractBaseTool
class that reduces boilerplate, handles dependency injection withDependencies
, and automatically converts Zod schemas to JSON schemas usingzod-to-json-schema
for introspection, documentation, and UI generation.index.ts
: ExportstoolClasses
as 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, includingserviceRequest
for making authenticated HTTP requests (OAuth2 or API key) with retries and timeout handling,getAuthToken
for fetching and caching OAuth2 tokens,buildQueryString
for creating query strings, andvalidateResponse
for response validation. It integrates withConfigService
for 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 anMCPServer
instance 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
MCPServer
setup (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
MCPServer
with 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
.env
file or passed directly to the process. - Check
ConfigService
logs 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_LEVEL
environment variable matches expected levels (e.g.,'info'
,'debug'
). - For
stdio
transport, ensure logs are directed to stderr as intended; checkcombined.log
for 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
TransportFactory
fails, verifyTRANSPORT_TYPE
matches a supported type ('http'
or'stdio'
) in the configuration.
- For
- Request Handling Issues:
- If
tools/list
ortools/call
requests fail, checkToolRegistry
for registered tools. - Validate tool arguments against the schema in
CallToolRequestSchema
to avoidValidationError
. - Ensure authentication tokens are provided if required by tools.
- If
- Tool Management Issues:
- If tools fail to load, verify
toolClasses
insrc/tools/index.ts
includes valid tool implementations. - Check
ToolFactory
logs for instantiation errors and ensureDependencies
are 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.js
exists by runningnpm run build
before 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
serviceRequest
fails, verify theauthType
,authEndpoint
,clientId
,clientSecret
, orapiKey
settings 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.js
script 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_PORT
orHTTP_HOST
is different). - Check for registered tools in
ToolRegistry
; an emptytools
array may indicate a tool loading issue.
- If the
- Testing Issues:
- If
npm test
fails, ensure Jest is configured correctly withts-jest
for TypeScript support, and verify that test files exist. - If
npm run mcp:inspector
ornpm run mcp:dev
fails, check that@modelcontextprotocol/inspector
is installed and the server is compiled (dist/index.js
exists).
- If
- Formatting Issues:
- If
npm run format:check
reports issues, runnpm run format
to 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.
This server cannot be installed
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.
Related MCP Servers
- AsecurityFlicenseAqualityA starter template for building Model Context Protocol servers that can be integrated with Cursor or Claude Desktop, allowing developers to create custom tools and extensions for AI assistants.Last updated -1289TypeScript
- -securityAlicense-qualityA TypeScript implementation of a Model Context Protocol server that provides a frictionless framework for developers to build and deploy AI tools and prompts, focusing on developer experience with zero boilerplate and automatic tool registration.Last updated -6TypeScriptMIT License
- -securityFlicense-qualityA TypeScript framework for building Model Context Protocol (MCP) servers with automatic discovery and loading of tools, resources, and prompts.Last updated -67TypeScript
- -securityFlicense-qualityA Model Context Protocol implementation for managing and serving AI prompts with a TypeScript-based architecture in a monorepo structure.Last updated -28,526,5832TypeScript