Skip to content

feat(core): add global tool registry#2003

Merged
senamakel merged 3 commits into
tinyhumansai:mainfrom
Zavianx:codex/OH-1848-tool-registry
May 18, 2026
Merged

feat(core): add global tool registry#2003
senamakel merged 3 commits into
tinyhumansai:mainfrom
Zavianx:codex/OH-1848-tool-registry

Conversation

@Zavianx
Copy link
Copy Markdown
Contributor

@Zavianx Zavianx commented May 17, 2026

Summary

  • Add a new tool_registry core domain with openhuman.tool_registry_list and openhuman.tool_registry_get JSON-RPC controllers.
  • Aggregate current MCP stdio tools and tools namespace controller-backed tools into one read-only discovery registry.
  • Include stable tool_id, transport, route, version, input/output schemas, allowed agents, tags, enabled state, and health metadata for each entry.
  • Document the registry in the MCP server guide and add it to the runtime capability catalog and coverage matrix.
  • Add focused Rust unit coverage and an HTTP JSON-RPC E2E test for list/get plus missing-tool failure behavior.

Problem

Solution

  • Introduce src/openhuman/tool_registry/ as a small read-only domain.
  • Reuse existing sources of truth instead of adding a parallel registry: mcp_server::tool_specs() for MCP tools and tools::all_tools_controller_schemas() for controller-backed tools.
  • Keep dispatch unchanged: MCP tools still call tools/call, and controller-backed tools still call their existing JSON-RPC methods.
  • Expose the new domain through the shared controller registry and capability catalog.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — focused changed-line tests were added and passed; local merged coverage was not run because the full Rust suite has unrelated existing failures listed below. CI coverage gate remains authoritative.
  • Coverage matrix updated — added 11.1.5 Global tool registry to docs/TEST-COVERAGE-MATRIX.md and scripts/feature-ids.json.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • N/A: Manual smoke checklist updated if this touches release-cut surfaces — this adds read-only core discovery, not a release manual smoke surface.
  • N/A: Linked issue closed via Closes #NNN — this PR is the core discovery MVP for Feature Request : Global MCP tool registry - centralised discovery, versioning, and routing for all MCP tools across the swarm #1848 and should not close the broader dashboard/routing/policy issue.

Impact

  • Runtime/platform impact: core JSON-RPC and CLI schema discovery only; no frontend route or Tauri shell behavior change.
  • Security/permissions: discovery-only metadata; no tool dispatch or permission checks are bypassed or changed.
  • Compatibility: existing MCP and tools.* controller methods keep their current routes.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Keep this section for AI-authored PRs. For human-only PRs, mark each field N/A.

Linear Issue

Commit & Branch

  • Branch: codex/OH-1848-tool-registry
  • Commit SHA: a4de942ffc708eec7ba169e8fdac845a8fe0884c

Validation Run

  • pnpm --filter openhuman-app format:check
  • pnpm typecheck
  • Focused tests: pnpm debug rust -- --lib tool_registry -- --nocapture (13 passed after CodeRabbit fix); pnpm debug rust -- --test json_rpc_e2e json_rpc_tool_registry_lists_and_gets_entries -- --nocapture; pnpm debug rust -- --lib namespace_description_known_namespaces; pnpm debug rust -- --lib catalog; node scripts/check-coverage-matrix.mjs
  • Rust fmt/check (if changed): cargo fmt --manifest-path Cargo.toml --all --check; cargo check --manifest-path Cargo.toml; git diff --check; git diff --cached --check
  • Tauri fmt/check (if changed): N/A: no Tauri source changed; pnpm --filter openhuman-app format:check and the pre-push hook also ran cargo fmt --manifest-path app/src-tauri/Cargo.toml --all --check and cargo check --manifest-path app/src-tauri/Cargo.toml.

Validation Blocked

  • command: pnpm debug rust
  • error: full Rust suite failed in this environment with three failures outside this PR surface: openhuman::composio::action_tool::tests::factory_routes_through_direct_when_mode_is_direct (composio backend mode unavailable: no backend session token), openhuman::tools::implementations::network::url_guard::tests::dns_check_passes_for_public_domain (google.com resolved to private/local 198.18.0.75), and openhuman::wallet::execution::tests::execute_prepared_broadcasts_erc20_transfer_using_default_token_catalog (quote ... not found). Summary: 7568 passed; 3 failed; 7 ignored.
  • impact: Focused tests for the changed registry surface pass; full-suite failures appear unrelated/environmental and should be checked separately from this PR.

Behavior Changes

  • Intended behavior change: adds read-only tool registry discovery via openhuman.tool_registry_list and openhuman.tool_registry_get.
  • User-visible effect: local clients and future dashboards can discover MCP/controller tool metadata from one RPC surface.

Parity Contract

  • Legacy behavior preserved: existing MCP tools/call routing and tools.* JSON-RPC methods are unchanged.
  • Guard/fallback/dispatch parity checks: JSON-RPC E2E verifies registry route metadata points to existing MCP/controller routes and that unknown tool IDs fail cleanly.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): none found for #1848 / tool registry; only unrelated open MCP PR feat(mcp): add SearXNG search tool #1988 matched a broad keyword search.
  • Canonical PR: this PR.
  • Resolution (closed/superseded/updated): N/A.

Summary by CodeRabbit

  • New Features

    • Added a read-only global Tool Registry for discovery, with RPC methods to list and fetch tools
    • Exposed a new Tool Registry capability in the app catalog
  • Documentation

    • Added Tool Registry section to MCP server docs and updated smoke-test expectations
    • Updated test-coverage matrix and feature ID list
  • Tests

    • Added end-to-end tests validating list/get behavior and error cases

Review Change Stack

@Zavianx Zavianx requested a review from a team May 17, 2026 13:10
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

📝 Walkthrough

Walkthrough

Adds a read-only global tool registry: new module exposing openhuman.tool_registry_list and openhuman.tool_registry_get, aggregating MCP stdio tool specs and controller schemas into deduplicated discovery entries with routing, version, input/output JSON Schemas, tags, and health metadata.

Changes

Tool Registry Implementation

Layer / File(s) Summary
Registry data types and contracts
src/openhuman/tool_registry/types.rs
ToolRegistryEntry, ToolRegistryTransport (JsonRpc/McpStdio), ToolRegistryHealth (Available/Unknown), and ToolRegistryList define the serialized schema for tool metadata and discovery responses.
Registry core operations and schema conversion
src/openhuman/tool_registry/ops.rs
list_tools(), get_tool(tool_id), and registry_entries() aggregate MCP specs and controller schemas into sorted, deduplicated entries; helpers convert internal TypeSchema/FieldSchema into JSON Schema Value with proper handling of primitives, arrays, maps, options, enums, nested objects, $ref defs, and MCP output shape; tag and title generation; unit tests for presence, uniqueness, sorting, schema generation, and ID trimming/validation.
RPC handler wiring and controller schema registration
src/openhuman/tool_registry/schemas.rs
all_controller_schemas() and all_registered_controllers() register tool_registry.list and tool_registry.get; async handle_list() and handle_get() validate inputs (required_tool_id), invoke core ops, and convert RpcOutcome<T> to CLI-compatible JSON; unit and async tests verify handler behavior and schema alignment.
Module public API and MCP re-exports
src/openhuman/tool_registry/mod.rs, src/openhuman/mod.rs, src/openhuman/mcp_server/mod.rs
Declares tool_registry public submodule and re-exports list_tools, get_tool, registry_entries, controller schema collectors, registry types, and re-exports tool_specs / McpToolSpec for registry consumption.
Core controller registry integration
src/core/all.rs, src/core/all_tests.rs
build_registered_controllers() and build_declared_controller_schemas() extended to include tool_registry controllers; namespace_description() returns a description for "tool_registry"; test asserts namespace presence.
Capability catalog and validation tests
src/openhuman/about_app/catalog.rs, src/openhuman/about_app/catalog_tests.rs, tests/json_rpc_e2e.rs
Adds intelligence.tool_registry capability entry with Beta/LOCAL_RAW metadata; updates catalog test; adds an end-to-end JSON-RPC test validating openhuman.tool_registry_list, per-tool openhuman.tool_registry_get, schema fields, transport/route metadata, and error behavior for missing tools.
Documentation and metadata
gitbooks/developing/mcp-server.md, docs/TEST-COVERAGE-MATRIX.md, scripts/feature-ids.json
Docs describe a discovery-only global tool registry and updated smoke-test expectations; TEST-COVERAGE-MATRIX records the new covered feature and summary counts; scripts/feature-ids.json gains "11.1.5".

Sequence Diagram(s)

sequenceDiagram
  participant Agent as Agent/Client
  participant RPC as JSON-RPC Server
  participant handle_list as handle_list()
  participant list_tools as list_tools()
  participant registry_entries as registry_entries()
  participant MCP as MCP Tool Specs
  participant Controllers as Controller Schemas

  Agent->>RPC: POST openhuman.tool_registry_list
  RPC->>handle_list: invoke handler
  handle_list->>list_tools: request ToolRegistryList
  list_tools->>registry_entries: aggregate sources
  registry_entries->>MCP: collect tool_specs
  registry_entries->>Controllers: collect schemas
  registry_entries-->>list_tools: sorted entries
  list_tools-->>handle_list: RpcOutcome<ToolRegistryList>
  handle_list-->>RPC: ToolRegistryList (tools array)
  RPC-->>Agent: JSON response with tools

  Agent->>RPC: POST openhuman.tool_registry_get {tool_id: "tools.web_search"}
  RPC->>handle_list: invoke handler with tool_id
  handle_list->>handle_list: required_tool_id validation
  handle_list->>list_tools: lookup specific tool
  list_tools-->>handle_list: ToolRegistryEntry
  handle_list-->>RPC: entry with transport/route/schemas
  RPC-->>Agent: ToolRegistryEntry JSON
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • senamakel

Poem

A rabbit found a list of tools so bright,
Collected specs by day and JSON by night,
MCP and controllers in a single view,
Hops of discovery, tags, and version too.
🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive The PR implements core registry infrastructure (registration, discovery, routing, schemas, catalog integration, E2E tests) addressing issue #1848 objectives; however, access control enforcement, health checking, versioning, and dashboard integration are not fully implemented. Verify that access control (allowed_agents enforcement [#1848]), health checking, versioning, and dashboard features are addressed in follow-up PRs or clarify their implementation status.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding a global tool registry feature to the core module.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the global tool registry as specified in issue #1848, with no unrelated or out-of-scope modifications.
Docstring Coverage ✅ Passed Docstring coverage is 95.12% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 17, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/openhuman/tool_registry/schemas.rs (1)

80-85: ⚡ Quick win

Add debug logging on tool_registry.get error paths.

required_tool_id(&params)? and ops::get_tool(tool_id)? can return early without any error log, making RPC failures harder to trace in production.

Proposed fix
 fn handle_get(params: Map<String, Value>) -> ControllerFuture {
     Box::pin(async move {
-        let tool_id = required_tool_id(&params)?;
+        let tool_id = match required_tool_id(&params) {
+            Ok(value) => value,
+            Err(err) => {
+                log::debug!("[tool_registry] rpc get rejected invalid tool_id: {err}");
+                return Err(err);
+            }
+        };
         log::debug!("[tool_registry] rpc get requested tool_id={tool_id}");
-        to_json(crate::openhuman::tool_registry::ops::get_tool(tool_id)?)
+        match crate::openhuman::tool_registry::ops::get_tool(tool_id) {
+            Ok(outcome) => to_json(outcome),
+            Err(err) => {
+                log::debug!("[tool_registry] rpc get failed tool_id={tool_id} error={err}");
+                Err(err)
+            }
+        }
     })
 }

As per coding guidelines: "Use log / tracing at debug or trace level on RPC entry and exit, error paths..."

Also applies to: 88-95

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/tool_registry/schemas.rs` around lines 80 - 85, The RPC handler
handle_get currently uses the `?` operator on `required_tool_id(&params)` and
`crate::openhuman::tool_registry::ops::get_tool(tool_id)` which can return early
without logging; change the implementation to explicitly handle errors (e.g.,
match or .map_err/.and_then) so you log a debug/error message with the error
details before returning the error, keeping the existing successful debug log
and returning the original error after logging; do the same pattern for the
analogous RPC handler in this module that handles the other tool-registry RPC
(the sibling handler implemented just after handle_get) so all entry, success
and error paths emit debug/tracing logs referencing the function names
(`handle_get`, `required_tool_id`, `ops::get_tool`, `to_json`) for easier
tracing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/TEST-COVERAGE-MATRIX.md`:
- Line 397: The new feature row 11.1.5 was added to the matrix but the summary
totals at the bottom were not updated; update the summary counts (the "✅
Covered" count and the "Total leaves" count) in docs/TEST-COVERAGE-MATRIX.md to
reflect inclusion of feature 11.1.5 (increment the covered leaves and total
leaves by one as appropriate) and ensure any percentage or derived totals are
recalculated to remain consistent with the new row.

In `@src/openhuman/tool_registry/ops.rs`:
- Around line 47-55: The registry build currently uses entries.insert(...) for
entries created by mcp_tool_entry(spec) and controller_tool_entry(&schema),
which silently overwrites existing entries on duplicate tool_id; change both
insertion points to detect collisions and fail fast by checking
entries.contains_key(&entry.tool_id) (or using
entries.entry(entry.tool_id.clone()).or_insert_with and matching on Occupied)
and return/panic with a clear error including the duplicate tool_id and the
source (e.g., from mcp_tool_entry(spec) vs controller_tool_entry(&schema)); keep
the same entry creation (mcp_tool_entry and controller_tool_entry) but prevent
silent overwrites by aborting on duplicate tool_id.

---

Nitpick comments:
In `@src/openhuman/tool_registry/schemas.rs`:
- Around line 80-85: The RPC handler handle_get currently uses the `?` operator
on `required_tool_id(&params)` and
`crate::openhuman::tool_registry::ops::get_tool(tool_id)` which can return early
without logging; change the implementation to explicitly handle errors (e.g.,
match or .map_err/.and_then) so you log a debug/error message with the error
details before returning the error, keeping the existing successful debug log
and returning the original error after logging; do the same pattern for the
analogous RPC handler in this module that handles the other tool-registry RPC
(the sibling handler implemented just after handle_get) so all entry, success
and error paths emit debug/tracing logs referencing the function names
(`handle_get`, `required_tool_id`, `ops::get_tool`, `to_json`) for easier
tracing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9963d1dd-979e-4457-b775-8ba372bea530

📥 Commits

Reviewing files that changed from the base of the PR and between f9de38d and d29a83c.

📒 Files selected for processing (14)
  • docs/TEST-COVERAGE-MATRIX.md
  • gitbooks/developing/mcp-server.md
  • scripts/feature-ids.json
  • src/core/all.rs
  • src/core/all_tests.rs
  • src/openhuman/about_app/catalog.rs
  • src/openhuman/about_app/catalog_tests.rs
  • src/openhuman/mcp_server/mod.rs
  • src/openhuman/mod.rs
  • src/openhuman/tool_registry/mod.rs
  • src/openhuman/tool_registry/ops.rs
  • src/openhuman/tool_registry/schemas.rs
  • src/openhuman/tool_registry/types.rs
  • tests/json_rpc_e2e.rs

Comment thread docs/TEST-COVERAGE-MATRIX.md
Comment thread src/openhuman/tool_registry/ops.rs
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 17, 2026
@senamakel senamakel merged commit 8896aa1 into tinyhumansai:main May 18, 2026
31 of 49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants