About Custom Tools MCP Server
Custom Tools MCP Server is an MCP server published by johnjg75dev in the Developer Tools category: a simple, dependency-free way to create custom AI tools in Python and host the **Model Context Protocol (MCP)** server. It has been installed 0 times through Conduid.
Six months or more without a commit doesn't mean the server is broken, but check the open issues (0) before depending on it in production.
Install
npx custom-tools-mcp-serverThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Custom Tools MCP Server
Powered by Claude · Grounded in docs
Security checks
- ·README presentNot checked yet.
- ·License declaredNot checked yet.
- ·Tests presentNot checked yet.
- ·Dependencies pinnedNot checked yet.
- ·No dynamic code executionNot checked yet.
- !Scoped permissionsDoesn't declare a permission scope. Assume it can do anything its process can.
README
Lightweight Python EZ-Tool MCP Server
A simple, dependency-free way to create custom AI tools in Python and host the Model Context Protocol (MCP) server.
This server allows you to expose Python functions as tools to AI models (like Claude Desktop, LM Studio, etc.) using a simple decorator (@mcp_tool). It supports both SSE (Server-Sent Events) for standard clients and Direct HTTP for stateless clients.
🚀 Features
- Decorator-based: Register tools with a simple
@mcp_tooldecorator. - Auto-Documentation: Automatically extracts descriptions from standard Docstrings or
Annotatedtype hints. - Universal Mode: Works with both streaming clients (Claude) and stateless clients (LM Studio).
- No Heavy SDKs: Built with Starlette and Uvicorn.
📦 Installation
- Clone the repository:
git clone https://github.com/yourusername/python-mcp-server.git cd python-mcp-server - Install dependencies:
pip install -r requirements.txt
🛠 Usage
1. Start the Server
Run the server on port 8000:
python main.py
2. Connect your AI Client
Option A: LM Studio
- Open LM Studio.
- Go to the MCP tab (the plug icon).
- Create a new server config (or edit
mcp.json):{ "mcpServers": { "python-tools": { "url": "http://localhost:8000/sse" } } } - Connect. The status should turn Green.
Option B: Claude Desktop
- Edit your Claude config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
- macOS:
- Add the configuration:
{ "mcpServers": { "python-tools": { "command": "uv", "args": [ "run", "--with", "uvicorn", "--with", "starlette", "--with", "sse-starlette", "python", "c:\\path\\to\\python-mcp-server\\main.py" ] } } }
📝 Adding New Tools
To add a new tool, simply create a new Python file in the tools/ folder (e.g., tools/weather.py). The server automatically scans this folder on startup.
You can document your tools in two ways. The server will convert these definitions into the JSON format required by the AI.
Style 1: Standard Docstrings (Google/Sphinx Style)
Best for clean, readable code. The parser automatically extracts parameter descriptions from the Args: block.
from registry import mcp_tool
@mcp_tool
def get_weather(location: str, days: int = 3):
"""
Get the weather forecast for a specific city.
Args:
location: The city to search for (e.g. Paris, London).
days: Number of days to forecast (1-7).
"""
return f"Weather in {location} for {days} days: Sunny, 25C"
Style 2: Annotated Types (Modern)
Best for keeping the description right next to the parameter.
from typing import Annotated
from registry import mcp_tool
@mcp_tool
def calculate_bmi(
weight: Annotated[float, "Weight in Kilograms"],
height: Annotated[float, "Height in Meters"]
):
"""Calculates Body Mass Index."""
return weight / (height ** 2)
What the AI Sees (The Result)
When the server runs, it converts the Python functions above into this JSON Schema. This is what is sent to the AI so it knows how to call your tools.
{
"name": "get_weather",
"description": "Get the weather forecast for a specific city.",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city to search for (e.g. Paris, London)."
},
"days": {
"type": "integer",
"description": "Number of days to forecast (1-7).",
"default": 3
}
},
"required": [
"location"
]
}
}
Note: Since days had a default value (= 3) in Python, it is marked as Optional in the JSON schema automatically.
📄 License
MIT License
README mirrored from the source repository 4 months ago. The original is authoritative.