Security-Hardened MCP Server

Security-Hardened MCP Server

A TypeScript MCP server with strict schema validation and security guards, currently implementing echo, get_time, hash_text, uuid_generate, and json_validate tools.

Category
Visit Server

README

Security-Hardened MCP Server

A TypeScript Model Context Protocol server built to be defensible in an interview: every security control is backed by an adversarial test or a committed artifact, or it is listed as an open finding. Built on the official @modelcontextprotocol/sdk (Streamable HTTP + stdio), Express 5, and Zod.

Status: M1 (schema validation) — strict input rejection and output validation are proven (T05 CLOSED): every registered tool's inputSchema is a .strict() Zod object fed directly to the SDK, so unknown/extra keys, wrong types, and out-of-range values are rejected against the raw JSON-RPC arguments, and output is strict-validated before it leaves the server. Authentication, scopes, rate limiting, and the remaining eight tools are still open — all other threat-model rows remain OPEN.

Architecture

requestId → originCheck → bodyLimit → auth → httpRateLimit → concurrencyCap
          → StreamableHTTPServerTransport → McpServer dispatch
              → withGuards: authz → rate limit → arg cap → timeout
                → output validate → sanitize → audit

(As of M1, withGuards steps 4/6/7/9 — arg byte cap, output validate, sanitize, and structured error mapping — are live. The Express-layer middleware chain above McpServer dispatch is still ordered stubs beyond requestId and body parsing.)

Tools (12 planned)

Tool Scope Demonstrates Status
echo echo:call connectivity / baseline Implemented
get_time time:read Implemented
hash_text hash:compute Implemented
uuid_generate uuid:generate Implemented
json_validate json:validate hostile-schema handling (schema-of-death) Implemented
text_summarize_stats text:analyze Not yet implemented
unit_convert unit:convert Not yet implemented
url_metadata url:read SSRF defense (T06/T07) Not yet implemented
math_eval math:eval AST sandbox (T09) Not yet implemented
password_strength password:analyze Not yet implemented
regex_test regex:test ReDoS defense (T08) Not yet implemented
kv_store kv:read / kv:write per-principal isolation (T10) Not yet implemented

Threat model

See docs/THREAT-MODEL.md. T05 is CLOSED as of M1; all other rows remain OPEN.

How to run

Prerequisites: Node 22 (nvm use), Docker.

npm ci

# HTTP (Streamable HTTP on :3000)
MODE=http PORT=3000 npm run dev
curl -s localhost:3000/healthz            # -> {"status":"ok"}

# stdio (JSON-RPC over stdin/stdout; logs go to stderr)
npm run build
MODE=stdio node dist/index.js

# Docker
docker build -t security-hardened-mcp-server:latest .
docker run --rm -e MODE=http -p 3000:3000 security-hardened-mcp-server:latest
# or: docker compose up --build

Inspect with MCP Inspector:

# HTTP: run the server, then open the Inspector and connect Streamable HTTP to
#   http://localhost:3000/mcp
npx @modelcontextprotocol/inspector
# stdio: Inspector launches the server itself
MODE=stdio npx @modelcontextprotocol/inspector node dist/index.js

Known limitations (M1)

  • Still no authentication, no scopes, no rate limiting — withGuards steps 1–3 are TODO(M2)/TODO(M3); per-tool authorization (scope enforcement) lands in M2.
  • The per-tool arg byte-cap control (withGuards step 4) exists and is unit-tested, but its dedicated adversarial proof, T04, lands in M3.
  • 5 of 12 tools implemented (echo, get_time, hash_text, uuid_generate, json_validate); the remaining seven, and threat-model rows T06–T15, land in M2–M4.
  • Not deployed; single-host only.

M1 Claim Audit

Resume phrase Artifact Verdict
"12 authenticated tools" 5 of 12 tools exist (echo, get_time, hash_text, uuid_generate, json_validate); no auth yet — withGuards steps 1–2 are TODO(M2), calls run with principal: null NOT YET
"schema validation" Strict input rejection is genuine and server-side: register() feeds the SDK .strict() objects, so unknown/extra keys, wrong types, missing required fields, out-of-range values, and deeply-nested payloads are rejected against the RAW arguments; output is strict-validated (step 6); json_validate caps a hostile schema's depth/size; errors are internal-detail-free (step 9). T05_schema_rejection.test.ts is green and fails when strict registration or the complexity guard is removed (delete-the-control drill recorded). PROVEN
"rate limiting" none yet (M3); withGuards step 3 + rateLimit.ts do not exist NOT YET
"load-tested to 50+ concurrent" none yet (M5) NOT YET

"Schema validation" is now the one PROVEN phrase; the other three remain NOT YET as scoped. The per-tool arg byte-cap control (step 4) is implemented and unit-tested but its full adversarial proof is T04 (M3), so it is not yet claimed as an independently-proven line.

Recommended Servers

playwright-mcp

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.

Official
Featured
TypeScript
Magic Component Platform (MCP)

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.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

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.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

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.

Official
Featured
TypeScript
Kagi MCP Server

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.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

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.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured