Tools Registry¶
The Tools Registry is a small Flask + MongoDB service that stores tool definitions (ToolEntry records) and the download link for each tool's code. Agents read from it through the Tools SDK; developers publish to it by uploading a bundle (see Creating a Tool).

What it does
- Accepts a tool bundle, uploads the code to the assets server, and stores the entry in MongoDB
- Gets, updates, and deletes tools by
tool_id - Filters tools by type, tag, keyword, execution mode, or policy URI, or with a raw MongoDB query
All tools live in a single MongoDB collection, tools_registry.tools, keyed by tool_id.
Running the service¶
| Setting | Value |
|---|---|
| Port | 6000 |
MONGO_URL |
MongoDB connection string (required) |
ASSETS_SERVER_URL |
Assets server that stores tool.zip. The registry calls POST {ASSETS_SERVER_URL}/upload and expects {"url": ...} back. |
cd functions-tools/src/tools/registry
docker build -t tools-registry .
docker run -p 6000:6000 \
-e MONGO_URL="mongodb://mongo:27017" \
-e ASSETS_SERVER_URL="http://assets:8080" \
tools-registry
Or run it directly with pip install -r requirements.txt && python main.py.
Schema¶
@dataclass
class ToolEntry:
tool_id: str = ''
tool_metadata: Dict[str, Any] = field(default_factory=dict)
tool_search_description: str = ''
tool_tags: List[str] = field(default_factory=list)
tool_type: str = ''
tool_man_page_doc: str = ''
tool_api_spec: Dict[str, Any] = field(default_factory=dict)
tool_custom_actions_dsl_map: Dict[str, Any] = field(default_factory=dict)
default_tool_usage_credentials: Dict[str, Any] = field(default_factory=dict)
tool_settings: Dict[str, Any] = field(default_factory=dict)
tool_parameters: Dict[str, Any] = field(default_factory=dict)
tool_execution_mode: str = ''
tool_policy_rule_uri: str = ''
tool_source_code_link: str = ''
tool_runtime_type: str = ''
tool_service_url: str = ''
tool_system_function_rpc_id: str = ''
tool_validation_policy_rule_uri: str = ''
tool_validation_mode: str = ''
The second column shows how the current SDK uses each field: Runtime means agents_tools reads it to load or execute the tool, Search means LLM-based search reads it, and Stored means the field is saved and queryable but not used by the SDK.
| Field | Used by | Description |
|---|---|---|
tool_id |
Runtime | Unique ID (primary key). |
tool_runtime_type |
Runtime | "python" or "" → Python executor; anything else → binary executor. |
tool_source_code_link |
Runtime | URL of the code archive. Set by the registry on upload. |
tool_parameters |
Runtime | Default configuration passed to the tool. Merged with overrides from AgentTools.add(). |
tool_api_spec |
Search | Input/output contract. LLM search reads tool_api_spec.entrypoints.execute.input (a JSON Schema). |
tool_search_description |
Search | Short description; also used by the by-keyword query. |
tool_tags |
Search | Tags for filtering and LLM search. |
tool_man_page_doc |
Stored | Markdown docs. Set by the registry from tool.md. |
tool_metadata |
Stored | Free-form metadata (author, version, license, …). |
tool_type |
Stored | Category, e.g. text-processing, utility. |
tool_settings |
Stored | Free-form settings. |
default_tool_usage_credentials |
Stored | Credentials the tool needs. Prefer putting secrets in tool_parameters overrides at add() time rather than in the registry. |
tool_custom_actions_dsl_map |
Stored | Optional DSL map for custom actions. |
tool_execution_mode |
Stored | e.g. sync, async. |
tool_policy_rule_uri |
Stored | Policy governing usage. |
tool_service_url |
Stored | URL of a hosted service, if any. |
tool_system_function_rpc_id |
Stored | ID of a system (gRPC) tool, see RPC System. |
tool_validation_policy_rule_uri |
Stored | Validation policy URI. |
tool_validation_mode |
Stored | e.g. strict, loose. |
API reference¶
Set REG=http://<tools-registry>:6000 in the examples below.
| Method | Path | Purpose |
|---|---|---|
| POST | /tools/upload |
Register a tool from a bundle |
| GET | /tools/<tool_id> |
Get a tool |
| PUT | /tools/<tool_id> |
Update fields |
| DELETE | /tools/<tool_id> |
Delete a tool |
| GET | /tools/query/by-type?type= |
Filter by tool_type |
| GET | /tools/query/by-tag?tag= |
Filter by a tag |
| GET | /tools/query/by-keyword?keyword= |
Case-insensitive regex on tool_search_description |
| GET | /tools/query/by-execution-mode?mode= |
Filter by tool_execution_mode |
| GET | /tools/query/by-policy-uri?uri= |
Filter by tool_policy_rule_uri |
| POST | /tools/query/generic |
Raw MongoDB filter |
POST /tools/upload¶
Upload a zip containing spec.json, tool.zip, and tool.md at its root. The registry:
- Reads
spec.json(it must containtool_id) - Uploads
tool.zipto the assets server and setstool_source_code_link - Sets
tool_man_page_docfromtool.md - Inserts the entry
curl -X POST $REG/tools/upload -F "file=@text-stats-bundle.zip"
| Status | Body |
|---|---|
| 200 | {"message": "Tool uploaded successfully", "tool_id": "text-stats"} |
| 400 | {"error": "Missing file part"} or {"error": "No selected file"} |
| 500 | {"error": "Failed to process tool package"}: a file is missing, tool_id is missing, the asset upload failed, or the tool_id already exists |
GET /tools/<tool_id>¶
curl $REG/tools/text-stats
Returns the full ToolEntry (200) or {"error": "Tool not found"} (404).
PUT /tools/<tool_id>¶
Sets the given top-level fields (MongoDB $set). Use dotted keys to update a nested field.
curl -X PUT $REG/tools/text-stats \
-H "Content-Type: application/json" \
-d '{"tool_tags": ["text", "nlp"], "tool_parameters.top_n": 5}'
Returns {"message": "Tool updated successfully"} (200), {"error": "Missing update payload"} (400), or {"error": "Tool not found"} (404).
DELETE /tools/<tool_id>¶
curl -X DELETE $REG/tools/text-stats
Returns {"message": "Tool deleted successfully"} (200) or {"error": "Tool not found"} (404).
Query endpoints¶
All return a JSON array of ToolEntry objects (an empty array if nothing matches).
curl "$REG/tools/query/by-type?type=text-processing"
curl "$REG/tools/query/by-tag?tag=nlp"
curl "$REG/tools/query/by-keyword?keyword=word"
curl "$REG/tools/query/by-execution-mode?mode=sync"
curl "$REG/tools/query/by-policy-uri?uri=policies://validate/compliance"
POST /tools/query/generic¶
The body is passed directly to MongoDB find().
# all python tools tagged nlp or text
curl -X POST $REG/tools/query/generic \
-H "Content-Type: application/json" \
-d '{"tool_runtime_type": "python", "tool_tags": {"$in": ["nlp", "text"]}}'
# list every tool
curl -X POST $REG/tools/query/generic -H "Content-Type: application/json" -d '{}'
Warning
This endpoint accepts any MongoDB filter. Restrict it to trusted callers.
Notes¶
- GraphQL: a GraphQL schema exists in
core/ql.py, but the/graphqlroute is disabled in the current build. Use/tools/query/genericinstead. - No list endpoint: there is no
GET /tools. UsePOST /tools/query/genericwith{}. - System tools (gRPC tools running on cluster nodes) are tracked by a separate service. See RPC System.