Skip to main content
Glama
jspmern

remote-mcp-server

by jspmern

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

  1. Project Overview

  2. Architecture & Diagram

  3. Key Features

  4. Installation & Setup

  5. Core Concepts

  6. Components Breakdown

  7. API Endpoints

  8. Usage Examples

  9. 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 creation

  • express: HTTP server framework

  • zod: Runtime type validation

  • dotenv: 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

  1. Edit TypeScript files in src/

  2. Nodemon watches for changes

  3. Auto-compiles TypeScript

  4. Auto-reloads Node.js process

  5. 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:

  1. Set environment variables on server

  2. Run build:

    npm run build
  3. Start server:

    npm start
  4. 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

F
license - not found
-
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jspmern/remote_mcp_server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server