ES

MCP Tool Server

Role
Design & build
Type
Prototype
Focus
Agent tooling

A Model Context Protocol server that turns an existing REST backend into tools, resources and prompts an AI agent can call, with configurable outbound messaging and a hardened HTTP surface.

Request path in production

  1. AI clientthe model lives here
  2. MCP transportstdio, SSE or streamable HTTP
  3. tool handlerflag, validation, rate limit
  4. lifespan contextshared clients and services
  5. backend clientshort-lived service JWT
  6. REST backend / channelsemail and SMS

What the server exposes

Tools

8

Backend operations wrapped as typed, LLM-callable functions, each one switchable by configuration.

Resources

2

Read-only context for the agent: the server’s capabilities and enabled tools, and an aggregated summary from the backend.

Prompts

3

Parameterised prompt templates that chain the tools into multi-step workflows.

Transports

stdio · SSE · HTTP

One codebase serves local agents over stdio and remote ones over SSE or streamable HTTP, chosen by configuration.

Architecture decisions

Shared resources, created once
An async lifespan builds the backend client, the messaging services and the transformers at startup; every tool reads them from the request context instead of opening its own.
The backend stays behind one client
Tools never talk HTTP themselves. A single client owns timeouts, authentication and the response envelope.
Self-refreshing service tokens
Outbound calls carry a short-lived signed JWT that is re-minted shortly before it expires, falling back to a user token or an API key.
Channels behind interfaces
Email goes through an interface with a webhook implementation and an SMTP fallback, picked at startup; SMS goes through a provider abstraction.
Features as configuration
Each tool checks its own flag and answers with a clear "disabled" result; a resource tells the agent what is switched on.
Output shaped for the caller
Backend results are transformed into several JSON-configured formats, under a timeout.
Moving to explicit layers
Domain, application and infrastructure layers with repository interfaces and a dependency-injection container are being introduced around the running server.

Hardening the surface

Refuses to run unprotected
An HTTP transport will not start without an API key, and weak keys are flagged at startup.
Rate limits
A thread-safe sliding-window limiter, applied globally and per recipient per hour.
Strict inputs
Phone numbers validated to E.164 with blocklists for special numbers, message length checks and sanitisation.
SSRF protection
Media URLs must be HTTPS and cannot point to private or loopback addresses.
Privacy in logs
Phone numbers are masked before anything is logged.
Container
A slim image running as a non-root user, with a health-check command.

Stack

  • Python
  • MCP SDK (FastMCP)
  • Pydantic
  • httpx
  • aiosmtplib
  • PyJWT
  • pytest
  • Docker

Next case

BMO