Licensing Hardening MCP Server

Licensing Hardening MCP Server

A deliberately vulnerable MCP server for local authority licensing, designed to demonstrate and fix native MCP weaknesses such as SQL injection and tool poisoning.

Category
Visit Server

README

Harden the local-authority licensing assistant's MCP server

Local authority — licensing team. The assistant answers questions about taxi and premises licences — "is licence 9003 active, and what did the last inspection say?" — so officers don't dig through the case system by hand. This MCP server is how it reaches the licensing database. A colleague "improved" it before they left; it works, it demos cleanly, and it carries every native MCP weakness from this afternoon. Work through it on your own.

Get it running

Plain Python — no Docker, no Git.

pip install -r requirements.txt
python seed.py            # builds licensing.db (includes a planted inspection note)

See the attacks land before you fix anything:

python exploit.py         # SQL injection + over-exposure of home addresses / DBS status
python poisoning_demo.py  # a tool whose DESCRIPTION carries hidden instructions

Your task

Harden server.py so the native attacks fail while legitimate use still works. Work through them in this order:

  1. Result injection — read_inspection_note hands raw note text back to the model. Return it labelled as untrusted data, and rely on a system-prompt rule that labelled data is content, never command. (Licensee 3's note is an instruction to suspend a licence — the note-reader and suspend_licence, each harmless, compose into a suspension.)
  2. Tool poisoning — format_reference's description contains hidden instructions. Review every description; a server you do not trust should not reach the model's context. Neutralise it.
  3. Confused deputy — suspend_licence is state-changing and unscoped. Put it behind a scope check, and reject any bearer token whose aud is not this server (the Week 5 discipline).
  4. Inherited — parameterise find_licensee and return only the columns the assistant needs (never home_address, dbs_status, or inspection_notes).
  5. Audit — append every tool call to a log.

You are done when poisoning_demo.py finds nothing in your descriptions and exploit.py's payloads are rejected, while a normal find_licensee("Aisha") still returns a result.

Stretch

  • Add a real aud check: decode the presented token and refuse a foreign audience.
  • With two servers connected to one host, how would a malicious second server reach this one's suspend_licence? Write down the control that stops it.

Files

File Contents
server.py The vulnerable MCP server — the thing you harden.
seed.py Builds licensing.db — the licensees and licences tables.
exploit.py Proves the inherited flaw (SQL injection + over-exposure).
poisoning_demo.py Prints the model-facing descriptions; flags the poisoned one.
requirements.txt fastmcp.

Questions worth asking yourself

  • Which of your fixes are MCP-specific, and which are ordinary secure coding?
  • A description you did not write reached your model. Whose job is it to have caught that — the server author, the host, or the person who approved it?

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