Install
$ agentstack add mcp-oaklight-toolregistry-server ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
toolregistry-server
[](https://pypi.org/project/toolregistry-server/) [](https://github.com/Oaklight/toolregistry-server/actions/workflows/ci.yml) [](https://opensource.org/licenses/MIT)
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 | [](https://pypi.org/project/toolregistry/) | Docs | | toolregistry-server | Server adapters — expose tools via OpenAPI & MCP | [](https://pypi.org/project/toolregistry-server/) | Docs | | toolregistry-hub | Ready-to-use tools — calculator, web search, file ops, etc. | [](https://pypi.org/project/toolregistry-hub/) | 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](examples/config.yaml) and [examples/config.jsonc](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](CONTRIBUTING.md) for details.
License
MIT — see [LICENSE](LICENSE).
Related Projects
- ToolRegistry — Core library
- toolregistry-hub — Built-in tool collection
- Model Context Protocol — MCP specification
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Oaklight
- Source: Oaklight/toolregistry-server
- License: MIT
- Homepage: https://toolregistry-server.readthedocs.io
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.