This server acts as a lightweight HTTP/STDIO gateway that exposes Python functions as discoverable and executable tools under the Model Context Protocol (MCP). It enables remote tool execution via JSON-RPC interface with both stateful and stateless contexts.
Key Capabilities:
Remote Tool Execution: Execute Python functions remotely through HTTP POST requests or STDIO
Tool Discovery: Discover available tools and their specifications via the MCP protocol
Dual Context Support: Maintain state across tool calls (stateful) or access incoming request data like headers and cookies (stateless)
Type-Safe Validation: Uses Pydantic for robust input/output schema validation and serialization
Asynchronous Handling: Provides async request processing via Starlette or FastAPI
Example Tools:
get_weather: Retrieve weather data for specified locations with temperature unit optionsget_time: Fetch current timetool_that_access_request: Access request details like username from headersget_called_tools: Retrieve list of previously called tools using stateful context
Provides a framework for building HTTP-based MCP servers that can be integrated into FastAPI applications, enabling the exposure of Python functions as discoverable tools and prompts
Uses Pydantic models for type-safe data validation and serialization of tool inputs, outputs, and server configurations
Simple HTTP MCP Server Implementation
This project provides a lightweight server implementation for the Model Context Protocol (MCP) over HTTP. It allows you to expose Python functions as tools and prompts that can be discovered and executed remotely via a JSON-RPC interface. It is intended to be used with a Starlette or FastAPI application (see demo).
Table of Contents
Features
MCP Protocol Compliant: Implements the MCP specification for tool and prompts discovery and execution. No support for notifications.
HTTP and STDIO Transport: Uses HTTP (POST requests) or STDIO for communication.
Async Support: Built on
StarletteorFastAPIfor asynchronous request handling.Type-Safe: Leverages
Pydanticfor robust data validation and serialization.Server State Management: Access shared state through the lifespan context using the
get_state_keymethod.Request Access: Access the incoming request object from your tools and prompts.
Authorization Scopes: Support for scope-based authorization using Starlette's authentication system.
Error Handling: Tools can optionally return error messages instead of raising exceptions.
Server Architecture
The library provides a single MCPServer class that uses lifespan to manage
shared state across the entire application lifecycle.
MCPServer
The MCPServer is designed to work with Starlette's lifespan system for
managing shared server state.
Key Characteristics:
Lifespan Based: Uses Starlette's lifespan events to initialize and manage shared server state
Application-Level State: State persists across the entire application lifecycle, not per-request
Flexible: Can be used with any custom context class stored in the lifespan state
Constructor Parameters:
name(str): The name of your MCP serverversion(str): The version of your MCP servertools(tuple[Tool, ...]): Tuple of tools to expose (default: empty tuple)prompts(tuple[Prompt, ...]): Tuple of prompts to expose (default: empty tuple)instructions(str | None): Optional instructions for AI assistants on how to use this server
Example Usage:
Tools
Tools are the functions that can be called by the client.
Basic Tool Example
Define the arguments and output for the tools:
Define the tools:
Instantiate the server:
Tools Without Arguments
You can define tools that don't require any input arguments:
Alternatively, you can use the NoArguments class for better clarity:
Tools with Error Handling
Tools can optionally return error messages instead of raising exceptions:
When return_error_message=True, the tool will return an ErrorMessage model
with the error details instead of raising a ToolInvocationError.
Tools with Authorization Scopes
You can restrict tool access based on authentication scopes:
Note: You need to set up authentication middleware in your Starlette app for scopes to work properly.
Server State Management
The server uses Starlette's lifespan system to manage shared state across the
entire application lifecycle. State is initialized when the application starts
and persists until it shuts down. Context is accessed through the
get_state_key method on the Arguments object.
Example:
Define a context class:
Set up the application with lifespan:
Access the context in your tools:
Request Access
You can access the incoming request object from your tools. The request object is passed to each tool call and can be used to access headers, cookies, and other request data (e.g. request.state, request.scope).
Prompts
You can add interactive templates that are invoked by user choice. Prompts now support lifespan state access, similar to tools.
Basic Prompt Example
Define the arguments for the prompts:
Instantiate the server:
Prompts Without Arguments
You can define prompts that don't require any input arguments:
Alternatively, you can use the NoArguments class:
Prompts with Lifespan State
Prompts with Authorization Scopes
You can restrict prompt access based on authentication scopes:
Note: You need to set up authentication middleware in your Starlette app for scopes to work properly.
STDIO Transport
In addition to HTTP transport, the server supports STDIO transport for communication. This is useful for command-line applications and integrations that communicate through standard input/output.
Using STDIO Transport
The request_headers parameter allows you to pass headers that will be included
in the request context, enabling authentication and other header-based features
even when using STDIO transport.
Authentication and Authorization
The library integrates with Starlette's authentication system to provide scope-based authorization for tools and prompts.
Setting Up Authentication Middleware
How Scopes Work
Authentication Middleware: The middleware authenticates each request and assigns scopes to the user through
AuthCredentials.Tool/Prompt Scopes: When defining tools or prompts, you can specify required scopes using the
scopesparameter.Access Control: The server automatically filters tools and prompts based on the user's granted scopes. Tools and prompts without the required scopes are not visible in listings and cannot be invoked.
Multiple Scopes: If you specify multiple scopes (e.g.,
scopes=("admin", "superuser")), the user needs at least one of those scopes to access the tool or prompt.
API Reference
Tool Class
The Tool class is used to define tools that can be invoked by clients.
Parameters:
func: The function to be invoked. Can be sync or async. The function can either:Accept an
Arguments[TInputs]parameterAccept no parameters
inputs: The Pydantic model class for input validation. Usetype(None)orNoArgumentsfor tools without inputsoutput: The Pydantic model class for output validationreturn_error_message(bool): IfTrue, tool errors returnErrorMessageinstead of raising exceptions (default:False)scopes(tuple[str, ...]): Required authentication scopes for accessing this tool (default: empty tuple)
Properties:
name: The function name (derived fromfunc.__name__)title: A human-readable title (derived from the function name)description: The function's docstringinput_schema: JSON schema for the input parametersoutput_schema: JSON schema for the output
Prompt Class
The Prompt class is used to define prompts that can be invoked by clients.
Parameters:
func: The function to be invoked. Can be sync or async. The function can either:Accept an
Arguments[TArguments]parameterAccept no parameters
Must return
tuple[PromptMessage, ...]
arguments_type: The Pydantic model class for argument validation. Usetype(None)orNoArgumentsfor prompts without argumentsscopes(tuple[str, ...]): Required authentication scopes for accessing this prompt (default: empty tuple)
Properties:
name: The function name (derived fromfunc.__name__)title: A human-readable title (derived from the function name)description: The function's docstringarguments: Tuple ofPromptArgumentobjects defining the prompt's arguments
Arguments Class
The Arguments class is passed to tool and prompt functions to provide access
to inputs, request, and state.
Parameters:
request: The StarletteRequestobjectinputs: The validated input/argument data (type depends on the Tool/Prompt definition)
Methods:
get_state_key(key: str, _object_type: type[TKey]) -> TKey: Access a value from the lifespan state. RaisesServerErrorif the key doesn't exist.
NoArguments Class
An empty Pydantic model that can be used as a clearer alternative to
type(None) when defining tools or prompts without arguments.
Installation
Install the package using pip or uv:
or
License
This project is licensed under the MIT License. See the LICENSE file for details.
Related MCP Servers
- -securityFlicense-qualityThis is an MCP server that facilitates building tools for interacting with various APIs and workflows, supporting Python-based development with potential for customizable prompts and user configurations.Last updated -
- AsecurityAlicenseAqualityA server that provides a persistent Python REPL environment through the MCP protocol, allowing execution of Python code, variable management, and package installation.Last updated -330MIT License
- -security-license-qualityA Python implementation of the MCP server that enables AI models to connect with external tools and data sources through a standardized protocol, supporting tool invocation and resource access via JSON-RPC.Last updated -1
- -securityFlicense-qualityA Python template for building Model Context Protocol (MCP) servers that expose tools via JSON-RPC, enabling secure and scalable context and tool invocation for language models.Last updated -