Skip to content

feat(tools): add codebase_search and github_codebase_search tools#2474

Open
DhruvBhatia0 wants to merge 3 commits intoOpenHands:mainfrom
DhruvBhatia0:feat/codebase-search-tool
Open

feat(tools): add codebase_search and github_codebase_search tools#2474
DhruvBhatia0 wants to merge 3 commits intoOpenHands:mainfrom
DhruvBhatia0:feat/codebase-search-tool

Conversation

@DhruvBhatia0
Copy link

Summary

  • Register Morph's WarpGrep as native OpenHands tools via the @morphllm/morphmcp MCP server
  • Users add Tool(name="codebase_search") to their agent like any other tool — MCP plumbing is internal
  • Two separate tool registrations (codebase_search + github_codebase_search) sharing one MCP server process
  • edit_file from the MCP server is filtered out to avoid conflict with FileEditorTool
  • Clear ValueError with dashboard link when MORPH_API_KEY is missing
  • Pre-installs @morphllm/morphmcp in Docker image for fast cold starts

Usage

from openhands.tools.codebase_search import register_codebase_search_tools

register_codebase_search_tools()

agent = Agent(
    llm=llm,
    tools=[
        Tool(name="codebase_search"),           # search local repos
        Tool(name="github_codebase_search"),    # search public GitHub repos
    ],
)

Requires MORPH_API_KEY env var (or passed via Tool(name="codebase_search", params={"api_key": "sk-..."})) and Node.js 18+.

Test plan

  • Import and registration verified locally
  • Both tools appear in list_registered_tools()
  • Missing MORPH_API_KEY raises ValueError with instructions + dashboard link
  • Top-level from openhands.tools import register_codebase_search_tools works
  • End-to-end test with MORPH_API_KEY set against a real repo
  • Docker image build with @morphllm/morphmcp pre-installed

🤖 Generated with Claude Code

Register Morph's WarpGrep as native OpenHands tools backed by the
@morphllm/morphmcp MCP server. Users add Tool(name="codebase_search")
to their agent like any other tool — the MCP plumbing is internal.

- Two separate tool registrations sharing one MCP server process
- edit_file from the MCP server is filtered out (FileEditorTool exists)
- Clear ValueError with dashboard link when MORPH_API_KEY is missing
- Pre-install @morphllm/morphmcp in Docker image for fast cold starts
- README section + example at examples/01_standalone_sdk/45_codebase_search.py

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@VascoSch92
Copy link
Contributor

Thanks for the PR.

Why a tool wrapping an mcp? Can we not just use the mcp directly?

- Fix resolver signatures to match registry calling convention
  (conv_state=, **params) instead of (params: dict, conv_state: object)
- Fix race condition: hold lock for entire MCP server start in
  _get_morph_search_tools
- Add atexit handler to close cached MCP clients on process exit
- Use (api_key, api_url, timeout_ms) tuple as cache key instead of
  just api_key
- Add TYPE_CHECKING import for ConversationState
- Use lazy %s logger formatting instead of f-string
- Add docstring note explaining callable resolver pattern
- Exclude 45_codebase_search.py from CI example tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@DhruvBhatia0
Copy link
Author

Thanks for the PR.

Why a tool wrapping an mcp? Can we not just use the mcp directly?

ah good point, i can make this change,

Replace the MCP-based approach (which wrapped @morphllm/morphmcp) with
direct calls to @morphllm/morphsdk via a Node.js bridge script.

- Native ToolDefinition subclasses with proper Action/Observation schemas
- bridge.js calls WarpGrepClient.execute() and searchGitHub() directly
- No more MCP server process, shared client cache, or atexit cleanup
- Clear error messages for missing Node.js, missing SDK, missing API key
- Dockerfile installs @morphllm/morphsdk instead of @morphllm/morphmcp

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@DhruvBhatia0 DhruvBhatia0 marked this pull request as ready for review March 17, 2026 04:24
@VascoSch92
Copy link
Contributor

If this is just an MCP server, which we already support, why do we need a new tool instead of using the MCP directly (i.e., passing it to the agent)?

Moreover, we already have tools that allow the agent to explore the codebase. Why would this tool be better? Is there a related issue for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants