toolregistry MCP server
Commit Nov 11, 2026Expose custom Python functions as tools through OpenAPI or Model Context Protocol interfaces for LLM function-calling.
Also known as Oaklight/toolregistry-server
- Stars
- 1
- Tools
- —
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Nov 11, 2026
- License
- MIT
What is toolregistry MCP?
toolregistry exposes custom Python functions as tools through OpenAPI or Model Context Protocol interfaces for LLM function-calling.
Summary generated from the project's README
About toolregistry MCP server
Exposing custom Python functions as tools for LLM function-calling is the primary function of toolregistry-server. Developers can register Python modules, classes, or existing MCP and OpenAPI services into a central registry and then serve them through either an OpenAPI interface using FastAPI or a Model Context Protocol interface via stdio, SSE, or HTTP transports.
Users can manage these tools through a command line interface or programmatically using the App class. The server supports unified Bearer token authentication and allows for deployment profiles that filter tools based on tags. For example, a remote profile can automatically disable tools tagged as FILE_SYSTEM, DESTRUCTIVE, or PRIVILEGED. When using the regex extra, the server provides bounded execution for pattern matching to ensure request validation remains within specific time limits.
What you can do with it
- 1Convert Python functions to API toolsTransform local Python code into a RESTful service that an LLM can call via OpenAPI.
- 2Protect against regex timeoutsEnsure that complex pattern matching during request validation does not hang the server.
Written from the project's README. Every use case is checked against a quote from it.
README
View on GitHubtoolregistry-server
Define custom tools and serve them via OpenAPI or MCP interfaces. Built on ToolRegistry.
Overview
toolregistry-server lets you register Python functions as tools and expose them as services through multiple protocols. It provides:
- Registry Builder: Protocol-agnostic config loading and source registration (
registry_builder) - Protocol Adapters:
OpenAPIAdapter(FastAPI/REST) andMCPAdapter(Model Context Protocol) - App Orchestration:
Appclass for building registries and dispatching to any adapter; subclassprepare_registry()for custom registries - Authentication: Unified Bearer token support (
auth.load_tokens) - CLI:
toolregistry-server openapi/toolregistry-server mcpwith--config,--profile, and more
Ecosystem
| Package | Description | PyPI | TestPyPI | Docs |
|---|---|---|---|---|
| toolregistry | Core library — tool registration, schema generation, execution | Docs | ||
| toolregistry-server | Server adapters — expose tools via OpenAPI & MCP | Docs | ||
| toolregistry-hub | Ready-to-use tools — calculator, web search, file ops, etc. | Docs |
toolregistry (core)
↓
toolregistry-server (tool server)
↓
toolregistry-hub (tool collection + server config)
Installation
# Base (RouteTable, registry_builder, auth)
pip install toolregistry-server
# OpenAPI server (vendored httpserver, no extra needed)
pip install toolregistry-server
# With the ASGI gateway backend (FastAPI + uvicorn)
pip install toolregistry-server[gateway]
# With MCP support
pip install toolregistry-server[mcp]
# With bounded execution of spec-supplied regexes (optional)
pip install toolregistry-server[regex]
# Full
pip install toolregistry-server[all]
The regex extra is not part of all. Without it, spec-supplied
pattern / patternProperties are not executed during request validation;
with it, every match is bounded (50 ms per match, 250 ms per request by
default) and a timeout answers 500. See the OpenAPI guide.
Quick Start
Programmatic — OpenAPI server
from toolregistry import ToolRegistry
from toolregistry_server import RouteTable
from toolregistry_server.adapters.openapi import OpenAPIAdapter
registry = ToolRegistry()
@registry.register
def greet(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"
route_table = RouteTable(registry)
adapter = OpenAPIAdapter(route_table)
adapter.run(host="0.0.0.0", port=8000)
Programmatic — MCP server
import asyncio
from toolregistry import ToolRegistry
from toolregistry_server import RouteTable
from toolregistry_server.adapters.mcp import MCPAdapter
registry = ToolRegistry()
# ... register tools ...
route_table = RouteTable(registry)
adapter = MCPAdapter(route_table)
adapter.run(transport="stdio") # blocking
# or: asyncio.run(adapter.run_async(transport="sse", host="0.0.0.0", port=8000))
High-level — App class
from toolregistry_server.app import App
# From a config file
App().serve_openapi(config_path="tools.yaml", host="0.0.0.0", port=8000)
App().serve_mcp(config_path="tools.yaml", transport="stdio")
# From a pre-built registry
from toolregistry import ToolRegistry
registry = ToolRegistry()
# ... register tools ...
App().serve_openapi(registry=registry, port=9000)
Custom App subclass
Override prepare_registry to add built-in tools, hooks, or metadata:
from toolregistry_server.app import App
class MyApp(App):
def prepare_registry(self, **kwargs):
from toolregistry import ToolRegistry
registry = ToolRegistry()
registry.register(my_builtin_tool)
# optionally apply user config on top
if kwargs.get("config_path"):
from toolregistry_server import apply_config, load_config
apply_config(registry, load_config(kwargs["config_path"]))
return registry
MyApp().serve_openapi(host="0.0.0.0", port=8000)
CLI
# OpenAPI server from config file
toolregistry-server openapi --config tools.yaml --port 8000
# MCP server (stdio)
toolregistry-server mcp --config tools.yaml --transport stdio
# MCP server (SSE)
toolregistry-server mcp --config tools.yaml --transport sse --port 8000
# With deployment profile (disables network/filesystem tools)
toolregistry-server openapi --config tools.yaml --profile remote
# With Bearer token auth
toolregistry-server openapi --config tools.yaml --tokens /path/to/tokens.txt
Config File
JSONC and YAML are both supported. Three source types: python, mcp, openapi.
mode: denylist # or "allowlist"
disabled: [] # namespaces to exclude (denylist mode)
tools:
# Python module — all public functions
- type: python
module: my_package.tools
namespace: my_tools
# Python class
- type: python
class: my_package.Calculator
namespace: calculator
# MCP server (stdio subprocess)
- type: mcp
transport: stdio
command: ["python", "-m", "my_mcp_server"]
namespace: mcp_tools
# MCP server (SSE / streamable-http)
- type: mcp
transport: http
url: http://localhost:8080/mcp
namespace: remote_mcp
# OpenAPI endpoint
- type: openapi
url: https://api.example.com/openapi.json
namespace: external_api
auth:
type: bearer
token_env: EXTERNAL_API_TOKEN
See examples/config.yaml and examples/config.jsonc for full examples.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ registry_builder │
│ load_config · apply_config · register_*_source │
│ apply_profile · PROFILE_DISABLE_TAGS │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ RouteTable │
│ (central routing layer) │
└─────────────────────────┬───────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ OpenAPIAdapter │ │ MCPAdapter │ │ (your adapter) │
│ (FastAPI) │ │ stdio/sse/http │ │ Adapter ABC │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ HTTP Clients │ │ MCP Clients │
└─────────────────┘ └─────────────────┘
Adding a New Adapter
- Subclass
Adapterfromtoolregistry_server.adapters - Implement
run(**kwargs)andcreate_and_run(cls, route_table, **kwargs) - Optionally implement
add_cli_arguments(parser)for CLI integration - Call
App().serve(MyAdapter, ...)— no changes toAppneeded
Deployment Profiles
--profile applies tag-based tool filtering at startup:
| Profile | Disables |
|---|---|
remote |
FILE_SYSTEM, DESTRUCTIVE, PRIVILEGED tagged tools |
local |
NETWORK tagged tools |
Documentation
- Full Documentation
- Configuration Guide
- Authentication & OAuth
- Deploying with an External Authorization Server
- Connecting OAuth Clients
- OAuth Reference
- API Reference
Contributing
Contributions are welcome! Please see our Contributing Guide for details.
License
MIT — see LICENSE.
Related Projects
- ToolRegistry — Core library
- toolregistry-hub — Built-in tool collection
- Model Context Protocol — MCP specification
toolregistry MCP questions
What types of tool sources can I register?
You can register Python modules, Python classes, existing MCP servers, and OpenAPI endpoints.