Skip to main content
Glama
dhaanish597

Security-Hardened MCP Server

by dhaanish597

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.

-
license - not tested
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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/dhaanish597/Security-Hardened-MCP-Server'

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