toolregistry-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 | 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
# With OpenAPI support
pip install toolregistry-server[openapi]
# With MCP support
pip install toolregistry-server[mcp]
# Full
pip install toolregistry-server[all]
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
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
Release files for toolregistry-server 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| toolregistry_server-0.5.0.tar.gz | 80.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| toolregistry_server-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 144.4 kB
Release files / toolregistry_server-0.5.0.tar.gz
| Download URL | toolregistry_server-0.5.0.tar.gz |
|---|---|
| Size | 80.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c534de48dbee6472b42fad9396dfcde0a7a5333b1b77161087ebc5781b000ffb
|
|
BLAKE2b-256 checksum How to use checksums |
6939837d2186c580f28b4b57ee89edd38dfe771ac8fb932b9c04eb4199f67805
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.
Transparency logRelease files / toolregistry_server-0.5.0-py3-none-any.whl
| Download URL | toolregistry_server-0.5.0-py3-none-any.whl |
|---|---|
| Size | 64.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
59c1ba1fdd543f79be827cf7c04c3238dd22c4889445a5ba7c76cb2c14878018
|
|
BLAKE2b-256 checksum How to use checksums |
6be691de86891a07d85a61388625f660e40da5c1ad3a0dd2e3ba337597106d3c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.
Transparency log