remote-mcp-server
A TypeScript-based MCP remote server with HTTP transport, token authentication, and support for tools, prompts, and resources.
README
MCP Remote Server
A TypeScript-based Model Context Protocol (MCP) remote server built with Express.js that provides tools, prompts, and resources over HTTP. This server demonstrates how to create an MCP server with HTTP transport, authentication middleware, and various MCP capabilities.
Table of Contents
- Project Overview
- Architecture & Diagram
- Key Features
- Installation & Setup
- Core Concepts
- Components Breakdown
- API Endpoints
- Usage Examples
- Development & Deployment
Project Overview
This project is an MCP Remote Server that exposes AI capabilities through HTTP endpoints. It uses the Model Context Protocol SDK to create a server that can be consumed by AI clients. The server provides:
- Tools: Functions that AI models can call to retrieve data
- Prompts: Reusable prompt templates for AI interactions
- Resources: Static or dynamic data resources accessible to clients
- Authentication: Token-based authentication for secure access
Architecture & Diagram
System Architecture Diagram
┌─────────────────────────────────────────────────────────────────┐
│ Client (AI Model/App) │
└────────────────────────────┬────────────────────────────────────┘
│ HTTP Request
▼
┌─────────────────────────────────────────────────────────────────┐
│ Express.js Server (Port 3000) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌─────────────────────────────┐ │
│ │ Middleware │ │ Route Handlers │ │
│ ├──────────────────┤ ├─────────────────────────────┤ │
│ │ • express.json │ │ • GET / (Hello) │ │
│ │ • authMiddleware │ │ • POST /mcp (MCP) │ │
│ └──────────────────┘ └─────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ MCP Server (StreamableHTTPServerTransport) │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────┐ │ │
│ │ │ Registered Tools │ │ │
│ │ │ • get_my_student_information │ │ │
│ │ │ └─> Returns student data from fakeData array │ │ │
│ │ └───────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────┐ │ │
│ │ │ Registered Prompts │ │ │
│ │ │ • greeting_template │ │ │
│ │ │ └─> Generates dynamic greeting messages │ │ │
│ │ └───────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────┐ │ │
│ │ │ Registered Resources │ │ │
│ │ │ • company-policy │ │ │
│ │ │ └─> Company work hours and leave policies │ │ │
│ │ └───────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Request Flow Diagram
Client Request with Bearer Token
│
▼
Express.js
│
├─► authMiddleware
│ ├─► Extract token from header
│ ├─► Compare with MCP_TOKEN env var
│ ├─► If valid: next()
│ └─► If invalid: 401 Unauthorized
│
┌────┴────┐
▼ │
Valid Invalid
│ │
▼ ▼
Route Error
Handler Response
│
├─► GET / → "Hello TypeScript"
│
└─► POST /mcp
├─► Create StreamableHTTPServerTransport
├─► Create MCP Server
├─► Connect server to transport
└─► Handle MCP Request/Response
Key Features
| Feature | Description |
|---|---|
| MCP Integration | Full Model Context Protocol SDK integration for tool/prompt/resource registration |
| Express.js | Lightweight HTTP server framework for handling requests |
| Authentication | Token-based Bearer token authentication middleware |
| Tools | AI-callable functions to retrieve student information |
| Prompts | Reusable prompt templates with dynamic variable substitution |
| Resources | Static resources like company policies accessible to clients |
| TypeScript | Full type safety with TypeScript for robust development |
| Environment Config | Uses dotenv for sensitive configuration management |
| Zod Validation | Schema validation for input parameters |
Installation & Setup
Prerequisites
- Node.js (v16+)
- npm or yarn
Step 1: Install Dependencies
npm install
This installs:
@modelcontextprotocol/sdk: MCP SDK for server creationexpress: HTTP server frameworkzod: Runtime type validationdotenv: Environment variable management
Step 2: Environment Configuration
Create a .env file in the root directory:
MCP_TOKEN=your_secret_token_here
This token is used for Bearer token authentication.
Step 3: Build TypeScript
npm run build
This compiles TypeScript files from src/ to build/
Step 4: Run the Server
Development Mode (with auto-reload):
npm run dev
Production Mode:
npm start
Server will start on http://localhost:3000
Core Concepts
1. Express Server Setup
Express is a minimal HTTP framework that handles incoming requests and routes them to appropriate handlers.
Code Explanation:
import express from "express";
const app = express();
app.use(express.json()); // Middleware to parse JSON request bodies
What happens:
- Creates an Express application instance
- Adds JSON body parser middleware to automatically parse incoming JSON
- All subsequent middleware and route handlers have access to parsed request body
Visual Flow:
Request → Parse JSON Body → Available in req.body → Route Handler
2. Authentication Middleware
Middleware intercepts requests before they reach route handlers to perform security checks.
Code Explanation:
export function authMiddleware(
req: Request,
res: Response,
next: NextFunction
) {
const token = req.headers.authorization;
if (token !== `Bearer ${process.env.MCP_TOKEN}`) {
return res.status(401).json({ message: "Unauthorized" });
}
next(); // Allow request to proceed
}
How it works:
1. Extract token from Authorization header
Example: "Bearer abc123def456"
2. Compare with environment variable MCP_TOKEN
3. Decision:
├─► Match? → Call next() → Continue to route handler
└─► No match? → Send 401 Unauthorized → Stop execution
Example Request:
# ✅ Valid request (has correct token)
curl -H "Authorization: Bearer your_secret_token_here" http://localhost:3000/mcp
# ❌ Invalid request (no token or wrong token)
curl http://localhost:3000/mcp
# Response: 401 - Unauthorized
3. MCP Server Creation
The createServer() function initializes the MCP server and registers all available capabilities.
Code Structure:
function createServer() {
// Step 1: Instantiate MCP Server
const server = new McpServer({
name: "remote-mcp-server",
version: "1.0.0",
});
// Step 2: Register tools, prompts, resources
server.registerTool(...);
server.registerPrompt(...);
server.registerResource(...);
return server; // Step 3: Return configured server
}
Purpose:
- Creates a new MCP server instance
- Registers all available tools, prompts, and resources
- Returns the server for connection to HTTP transport
4. HTTP Transport
StreamableHTTPServerTransport handles the HTTP layer for MCP communication.
Code Explanation:
app.post("/mcp", async (req, res) => {
// Step 1: Create HTTP transport layer
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
// Step 2: Create MCP server
const server = createServer();
// Step 3: Connect server to transport
await server.connect(transport);
// Step 4: Process incoming HTTP request
await transport.handleRequest(req, res, req.body);
});
Process Flow:
HTTP POST /mcp
│
▼
Create Transport ──► Register handlers for streaming
│
▼
Create MCP Server ──► Setup tools/prompts/resources
│
▼
Connect ──► Server connects to transport layer
│
▼
Handle Request ──► Transport processes MCP protocol
│
▼
Send Response ──► HTTP Response back to client
Components Breakdown
Sample Data Structure
The server includes mock student data:
const fakeData = [
{
"id": 1,
"name": "Rahul Sharma",
"age": 21,
"address": "Mumbai, Maharashtra",
"course": "B.Tech",
"role": "Student"
},
// ... 9 more student records
];
This data is used by tools to simulate real database queries.
Tools Registration
Tools are functions that AI models can call to perform actions or retrieve data.
Tool: get_my_student_information
Purpose: Retrieve a limited number of student records
Code:
server.registerTool(
"get_my_student_information", // Tool name
{
description: "Get student information", // Description for AI model
inputSchema: {
limit: z.string(), // Parameter: limit as string
},
},
async ({ limit }) => ({ // Handler function
content: [
{
type: "text",
text: JSON.stringify(
fakeData.slice(0, parseInt(limit) || 5) // Return up to 'limit' records, default 5
),
},
],
})
);
Execution Flow:
AI Model Call
│
├─► Tool Name: get_my_student_information
├─► Input: { limit: "3" }
│
▼
Handler Function
│
├─► Parse limit: parseInt("3") = 3
├─► Get slice: fakeData.slice(0, 3)
├─► Convert to JSON string
│
▼
Return Response
│
└─► {
content: [{
type: "text",
text: "[student1, student2, student3]"
}]
}
Example Usage:
// AI Model calls the tool
const result = await client.callTool("get_my_student_information", {
limit: "2"
});
// Response:
{
content: [{
type: "text",
text: '[{"id":1,"name":"Rahul Sharma","age":21,...},{"id":2,"name":"Priya Singh","age":22,...}]'
}]
}
Prompt Templates
Prompts are reusable message templates that AI models can use for consistent interactions.
Prompt: greeting_template
Purpose: Generate personalized greeting messages
Code:
server.registerPrompt(
"greeting_template", // Prompt name
{
description: "A template prompt for greeting", // Description
argsSchema: {
name: z.string() // Required parameter: name
}
},
async ({ name }) => ({ // Handler with parameter
messages: [
{
role: "assistant",
content: {
type: "text",
text: `Hello, ${name}! Welcome to the MCP Local Server.` // Dynamic message
}
}
]
})
);
How It Works:
Request Prompt: greeting_template
│
├─► Input Parameter: { name: "Alice" }
│
▼
Template Processing
│
├─► Substitute ${name} with "Alice"
├─► Generate message: "Hello, Alice! Welcome to the MCP Local Server."
│
▼
Return Message
│
└─► {
messages: [{
role: "assistant",
content: {
type: "text",
text: "Hello, Alice! Welcome to the MCP Local Server."
}
}]
}
Use Cases:
- Greeting users with their name
- Generating consistent opening messages
- Personalizing AI responses
Resources
Resources are static or dynamically generated data that AI models can access.
Resource: company-policy
Purpose: Provide company policies to AI models
Code:
server.registerResource(
"company-policy", // Resource name
"company://policy", // Resource URI
{}, // Input schema (empty = no parameters)
async () => ({ // Handler function
contents: [
{
uri: "company://policy", // Resource identifier
text: `
Work Hours: 9 AM to 6 PM
Casual Leave: 12
Sick Leave: 8
`
}
]
})
);
Access Pattern:
Request Resource: company-policy
│
▼
Retrieve Resource Data
│
├─► Work Hours: 9 AM to 6 PM
├─► Casual Leave: 12 days
└─► Sick Leave: 8 days
│
▼
Return to Client
│
└─► AI model now has access to policies
Use Cases:
- Company policies and guidelines
- Knowledge bases
- Reference documents
- Configuration data
API Endpoints
1. Health Check Endpoint
Endpoint: GET /
Description: Simple health check to verify server is running
Response:
200 OK
Body: "Hello TypeScript"
Example:
curl http://localhost:3000/
# Response: Hello TypeScript
2. MCP Endpoint
Endpoint: POST /mcp
Authentication: Required (Bearer token)
Description: Main MCP protocol handler for tools, prompts, and resources
Request Headers:
Authorization: Bearer {MCP_TOKEN}
Content-Type: application/json
Request Body Structure:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_my_student_information",
"arguments": {
"limit": "3"
}
}
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "[...student data...]"
}
]
}
}
Example:
curl -X POST http://localhost:3000/mcp \
-H "Authorization: Bearer your_secret_token_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_my_student_information",
"arguments": { "limit": "2" }
}
}'
Usage Examples
Example 1: Call Tool via MCP
Scenario: AI model wants to retrieve 2 student records
Request:
curl -X POST http://localhost:3000/mcp \
-H "Authorization: Bearer your_secret_token_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_my_student_information",
"arguments": { "limit": "2" }
}
}'
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "[{\"id\":1,\"name\":\"Rahul Sharma\",\"age\":21,...},{\"id\":2,\"name\":\"Priya Singh\",\"age\":22,...}]"
}
]
}
}
Example 2: Use Prompt Template
Scenario: AI model wants to greet a user with their name
Request:
curl -X POST http://localhost:3000/mcp \
-H "Authorization: Bearer your_secret_token_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "prompts/get",
"params": {
"name": "greeting_template",
"arguments": { "name": "Rajesh" }
}
}'
Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"messages": [
{
"role": "assistant",
"content": {
"type": "text",
"text": "Hello, Rajesh! Welcome to the MCP Local Server."
}
}
]
}
}
Example 3: Access Resource
Scenario: AI model needs to retrieve company policies
Request:
curl -X POST http://localhost:3000/mcp \
-H "Authorization: Bearer your_secret_token_here" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "resources/read",
"params": {
"uri": "company://policy"
}
}'
Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"contents": [
{
"uri": "company://policy",
"text": "Work Hours: 9 AM to 6 PM\n\nCasual Leave: 12\n\nSick Leave: 8"
}
]
}
}
Development & Deployment
Project Structure
mcp_remote_server/
├── src/
│ ├── index.ts # Main server file
│ └── middlware/
│ └── auth.ts # Authentication middleware
├── build/
│ ├── index.js # Compiled main file
│ └── middlware/
│ └── auth.js # Compiled middleware
├── package.json # Project dependencies
├── tsconfig.json # TypeScript configuration
└── README.md # This file
Build Process
TypeScript Files (src/)
│
▼
TypeScript Compiler (tsc)
│
▼
JavaScript Files (build/)
│
▼
Node.js Runtime
Build Command:
npm run build
This runs the TypeScript compiler and outputs JavaScript to the build/ directory.
Scripts
| Script | Command | Purpose |
|---|---|---|
build |
tsc |
Compile TypeScript to JavaScript |
start |
node build/index.js |
Run compiled server |
dev |
nodemon --watch src... |
Development mode with auto-reload |
Development Workflow
- Edit TypeScript files in
src/ - Nodemon watches for changes
- Auto-compiles TypeScript
- Auto-reloads Node.js process
- Test changes immediately
Environment Variables
Create .env file:
# Server Configuration
PORT=3000
# Authentication
MCP_TOKEN=your_very_secret_token_here_change_in_production
Security: Never commit .env to version control. Add to .gitignore:
.env
.env.local
Deployment
Production Deployment Steps:
- Set environment variables on server
- Run build:
npm run build - Start server:
npm start - Use process manager (pm2, systemd, etc.):
pm2 start build/index.js --name "mcp-server"
Docker Deployment:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY build/ ./build/
ENV MCP_TOKEN=your_token_here
EXPOSE 3000
CMD ["node", "build/index.js"]
Summary
This MCP Remote Server demonstrates:
✅ HTTP-based MCP Protocol - Communicate with AI models over HTTP ✅ Tool Registration - Create callable functions for AI ✅ Prompt Templates - Reusable message patterns ✅ Resources - Access to data and policies ✅ Authentication - Secure access with Bearer tokens ✅ Type Safety - Full TypeScript support ✅ Easy Development - Hot-reload with Nodemon
References
Last Updated: June 4, 2026
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.
Neon Database
MCP server for interacting with Neon Management API and databases
E2B
Using MCP to run code via e2b.
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.