Skip to content

[codex] Add Bocha Search MCP example - #697

Open
NiTingKY wants to merge 2 commits into
lastmile-ai:mainfrom
NiTingKY:codex/bocha-search-mcp-example
Open

[codex] Add Bocha Search MCP example#697
NiTingKY wants to merge 2 commits into
lastmile-ai:mainfrom
NiTingKY:codex/bocha-search-mcp-example

Conversation

@NiTingKY

@NiTingKY NiTingKY commented May 28, 2026

Copy link
Copy Markdown

Summary

  • add a Bocha Search MCP use case example that connects to BochaAI/bocha-search-mcp over stdio
  • read BOCHA_API_KEY and BOCHA_SEARCH_MCP_DIR from the runtime environment so secrets and local paths are not stored in config
  • add focused tests for secret-free config, runtime env mapping, and Bocha API error surfacing

Validation

  • uv run pytest tests/examples/test_bocha_search_mcp_agent_example.py -q -> 3 passed
  • local smoke test with BOCHA_API_KEY and BOCHA_SEARCH_MCP_DIR set -> discovered bocha_bocha_web_search / bocha_bocha_ai_search and completed bocha_web_search with HTTP 200
  • scanned the new example/test files for the real Bocha key before commit

Notes

  • The example expects the Bocha MCP server repo to be cloned separately and referenced via BOCHA_SEARCH_MCP_DIR.
  • The PR is opened as draft for maintainer review of example placement and naming.

Summary by CodeRabbit

  • Documentation

    • Added a README with setup and usage steps for the Bocha Search MCP agent example.
  • New Features

    • Added a runnable Bocha Search MCP agent example and a sample MCP agent configuration to demonstrate connecting and performing a web search.
  • Tests

    • Added smoke tests to verify example configuration, environment handling, and error reporting.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a9a81238-3b4f-4467-b347-b9bfcd64b56e

📥 Commits

Reviewing files that changed from the base of the PR and between 4d0abe0 and fe4fb64.

📒 Files selected for processing (3)
  • examples/usecases/bocha_search_mcp_agent/README.md
  • examples/usecases/bocha_search_mcp_agent/main.py
  • tests/examples/test_bocha_search_mcp_agent_example.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • examples/usecases/bocha_search_mcp_agent/README.md
  • examples/usecases/bocha_search_mcp_agent/main.py

📝 Walkthrough

Walkthrough

Adds a complete Bocha Search MCP agent example: YAML config, a runnable async Python example that reads BOCHA env vars, discovers and invokes the bocha_web_search tool via MCP with error detection and cleanup, tests covering config and error cases, and a README with setup and run instructions.

Changes

Bocha Search MCP Agent Example

Layer / File(s) Summary
Configuration and environment setup
examples/usecases/bocha_search_mcp_agent/mcp_agent.config.yaml, examples/usecases/bocha_search_mcp_agent/main.py
MCP YAML config (asyncio engine, debug console) and module-level MCPApp; bocha_server_config_from_process() reads and validates BOCHA_SEARCH_MCP_DIR and BOCHA_API_KEY, returning CLI args and env mapping.
Search implementation and error handling
examples/usecases/bocha_search_mcp_agent/main.py
raise_for_bocha_error() inspects tool response content for HTTP/API-key error substrings; find_bocha_search_tool() selects a tool whose name ends with bocha_web_search; search_bocha() patches server config, creates MCPAggregator, invokes the tool with fixed {query, freshness="noLimit", count=3}, validates results, closes aggregator in finally, and __main__ runs the async entrypoint.
Tests for configuration, error handling, and environment reading
tests/examples/test_bocha_search_mcp_agent_example.py
Tests verify the YAML config uses runtime env without embedded secrets, that API-like tool errors raise RuntimeError, that bocha_server_config_from_process() maps env to expected CLI args/env, and negative tests for missing/invalid env and missing tool.
Documentation and usage guide
examples/usecases/bocha_search_mcp_agent/README.md
README documents cloning the Bocha server, setting BOCHA_API_KEY and BOCHA_SEARCH_MCP_DIR (with Windows CMD equivalents), and running the example via uv run.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • saqadri
  • petersonbill64

Poem

A rabbit hops to start the run, 🐇
Reads env and finds the Bocha sun,
Calls the web search, checks each line,
Cleans the sockets, prints the sign,
Tests passed — the agent's work is done.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding a Bocha Search MCP example. It is concise, directly related to the primary changeset, and provides meaningful information about what was added.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@NiTingKY
NiTingKY marked this pull request as ready for review May 28, 2026 02:24

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/examples/test_bocha_search_mcp_agent_example.py (1)

38-55: ⚡ Quick win

Add negative-path env tests for required variables.

This test only covers the happy path. Add cases where BOCHA_API_KEY or BOCHA_SEARCH_MCP_DIR is missing to lock the RuntimeError contract.

Proposed test additions
+import pytest
@@
 def test_bocha_example_reads_server_config_from_process_env(monkeypatch):
@@
     assert env == {"BOCHA_API_KEY": "test-key"}
+
+
+def test_bocha_example_server_config_requires_api_key(monkeypatch):
+    from examples.usecases.bocha_search_mcp_agent.main import bocha_server_config_from_process
+
+    monkeypatch.delenv("BOCHA_API_KEY", raising=False)
+    monkeypatch.setenv("BOCHA_SEARCH_MCP_DIR", "D:/bocha-search-mcp")
+
+    with pytest.raises(RuntimeError, match="BOCHA_API_KEY is required"):
+        bocha_server_config_from_process()
+
+
+def test_bocha_example_server_config_requires_search_dir(monkeypatch):
+    from examples.usecases.bocha_search_mcp_agent.main import bocha_server_config_from_process
+
+    monkeypatch.setenv("BOCHA_API_KEY", "test-key")
+    monkeypatch.delenv("BOCHA_SEARCH_MCP_DIR", raising=False)
+
+    with pytest.raises(RuntimeError, match="BOCHA_SEARCH_MCP_DIR is required"):
+        bocha_server_config_from_process()
🤖 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 `@tests/examples/test_bocha_search_mcp_agent_example.py` around lines 38 - 55,
The test only covers the happy path for bocha_server_config_from_process; add
negative-path tests that unset BOCHA_API_KEY and BOCHA_SEARCH_MCP_DIR (use
monkeypatch.delenv or monkeypatch.setenv with None) and assert
bocha_server_config_from_process raises a RuntimeError when either required env
var is missing, referencing the function name bocha_server_config_from_process
and the environment variable names BOCHA_API_KEY and BOCHA_SEARCH_MCP_DIR in the
assertions to ensure the RuntimeError contract is enforced.
🤖 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 `@examples/usecases/bocha_search_mcp_agent/main.py`:
- Around line 14-24: The code checks BOCHA_SEARCH_MCP_DIR exists as an env var
but does not verify the path points to an actual directory before returning
server args; update the logic around server_dir (the value from
os.environ.get("BOCHA_SEARCH_MCP_DIR")) to construct a Path(server_dir) and
verify path.exists() and path.is_dir(), and if not raise a RuntimeError with a
clear message including the invalid path value so the function that returns
(["--directory", str(Path(server_dir)), "run", "bocha-search-mcp"],
{"BOCHA_API_KEY": api_key}) fails fast with useful context.
- Around line 52-54: The current expression that finds the search tool using
next(name for name in tool_names if name.endswith("bocha_web_search")) can raise
a raw StopIteration; modify the lookup to handle missing tools and raise a clear
RuntimeError including tool_names instead. Replace that next(...) call (where
search_tool and tool_names are used) with a safe lookup (e.g., next(..., None)
or a try/except around next) and if no match is found raise RuntimeError(f"No
'bocha_web_search' tool found; available tools: {tool_names}") so the async
function surfaces a clear, targeted error.

In `@examples/usecases/bocha_search_mcp_agent/README.md`:
- Around line 28-32: Update the README.md example command to avoid a “file not
found” error by explicitly specifying the examples directory or adding a cd step
before running main.py; mention the examples/usecases/bocha_search_mcp_agent
path and either prepend cd examples/usecases/bocha_search_mcp_agent then run uv
run --project ... python main.py, or run uv run --project ... python
examples/usecases/bocha_search_mcp_agent/main.py so that the reference to
main.py is repo-root-safe and unambiguous.

---

Nitpick comments:
In `@tests/examples/test_bocha_search_mcp_agent_example.py`:
- Around line 38-55: The test only covers the happy path for
bocha_server_config_from_process; add negative-path tests that unset
BOCHA_API_KEY and BOCHA_SEARCH_MCP_DIR (use monkeypatch.delenv or
monkeypatch.setenv with None) and assert bocha_server_config_from_process raises
a RuntimeError when either required env var is missing, referencing the function
name bocha_server_config_from_process and the environment variable names
BOCHA_API_KEY and BOCHA_SEARCH_MCP_DIR in the assertions to ensure the
RuntimeError contract is enforced.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: cdd9c151-7fdc-42ff-a168-42b122e209b6

📥 Commits

Reviewing files that changed from the base of the PR and between f62d849 and 4d0abe0.

📒 Files selected for processing (4)
  • examples/usecases/bocha_search_mcp_agent/README.md
  • examples/usecases/bocha_search_mcp_agent/main.py
  • examples/usecases/bocha_search_mcp_agent/mcp_agent.config.yaml
  • tests/examples/test_bocha_search_mcp_agent_example.py

Comment thread examples/usecases/bocha_search_mcp_agent/main.py
Comment thread examples/usecases/bocha_search_mcp_agent/main.py Outdated
Comment thread examples/usecases/bocha_search_mcp_agent/README.md
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.

1 participant