Feat/node butterbase#1069
Conversation
Clone of tool_mcp_client hardcoded to Butterbase's Streamable HTTP MCP server (https://api.butterbase.ai/mcp, Bearer auth). Discovers and exposes Butterbase's backend tools (init_app, schema, auth, storage, functions, RAG) to agents as butterbase.<tool>. Includes example pipe and unit tests (namespacing, tool cache, dispatch).
RocketRide Wave agent wired to tool_butterbase (and the required memory_internal), using Claude (claude-sonnet-4-6). Both keys use ROCKETRIDE_-prefixed env vars so pipeline substitution resolves them: ROCKETRIDE_ANTHROPIC_KEY and ROCKETRIDE_BUTTERBASE_API_KEY.
Butterbase publishes no vector logo, so point the icon field at the official Smithery server icon URL. Icon.tsx renders http(s) icon values via <img>, so a remote PNG works without bundling a local SVG.
…rimental flag Display title (node + default profile + shape) is now 'Butterbase MCP Client'; removed the 'experimental' capability so the card shows no EXPERIMENTAL badge. Internal ids (tool_butterbase, prefix, protocol) unchanged.
…atch llm_anthropic style)
The Butterbase app must have Developer Mode enabled for the agent to create/modify resources (writes are rejected otherwise). Added to the README (Prerequisite section) and the node description shown in the builder.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR adds a Butterbase MCP client service preset configuration and an example agent pipeline demonstrating integration. The service preset defines the tool_butterbase node transport, endpoint, and API credential fields. The example pipe wires a chat input through an agent that uses the Butterbase tool alongside internal memory and OpenAI LLM nodes. ChangesButterbase Tool Configuration and Usage
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related issues
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
No description provided. |
…onstants - API Key field help now links to the Butterbase dashboard (dashboard.butterbase.ai → API Keys), matching the xTrace pattern. - Extract transport defaults to named constants (_MCP_PROTOCOL_VERSION, _CLIENT_NAME, _CLIENT_VERSION, _DEFAULT_TIMEOUT_S) to avoid magic values in the client signature.
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 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 `@nodes/src/nodes/tool_butterbase/IGlobal.py`:
- Around line 108-124: The tool-cache attributes _tools_by_original and
_tools_by_namespaced (and optionally _client) must be initialized to safe
defaults in the startup path that can early-return (beginGlobal) so methods like
list_namespaced_tools, get_tool and _tool_query_dynamic do not raise
AttributeError; update beginGlobal (and/or class initializer) to set
self._tools_by_original = {} and self._tools_by_namespaced = {} (and
self._client = None if referenced) before any early return, leaving
_cache_tools, list_namespaced_tools and get_tool logic unchanged.
In `@nodes/src/nodes/tool_butterbase/mcp_streamable_http_client.py`:
- Around line 233-258: Persist the selected MCP protocol version in
McpStreamableHttpClient (e.g., set self._protocol_version from initialize()
return or from the initialize response's protocolVersion) and ensure
_build_headers() includes 'MCP-Protocol-Version' when self._protocol_version is
set; update _post_request_and_wait(), _post_notification(), and stop() (DELETE)
to rely on the updated _build_headers() so the header is sent on tools/list,
tools/call, notifications/initialized and stop() requests. Ensure the header
value is used for all subsequent requests after initialize and not only inside
the JSON-RPC body.
In `@nodes/src/nodes/tool_butterbase/README.md`:
- Around line 36-37: The README's `api_key`/env var entries reference
`BUTTERBASE_API_KEY` but the example pipe uses `ROCKETRIDE_BUTTERBASE_API_KEY`,
causing mismatch; either standardize both the README and the example pipe
(`butterbase-agent.pipe`) to the same env var name or explicitly document both
`BUTTERBASE_API_KEY` and `ROCKETRIDE_BUTTERBASE_API_KEY` and their precedence,
and update all occurrences of the env var in the README table (the `api_key`
rows and the other referenced rows) to match that single chosen convention so
users won't misconfigure authentication.
In `@nodes/src/nodes/tool_butterbase/services.json`:
- Around line 69-107: The runtime env-var name is inconsistent:
services.json/examples use ROCKETRIDE_BUTTERBASE_API_KEY but IGlobal.py
currently falls back to BUTTERBASE_API_KEY; fix by standardizing them. Either
(A) update IGlobal.py (the env lookup at the current fallback around the code
referencing BUTTERBASE_API_KEY) to read ROCKETRIDE_BUTTERBASE_API_KEY (or accept
both names for backward compatibility), and ensure services.json
"butterbase.api_key" preconfig/default and any example wiring use the same
ROCKETRIDE_BUTTERBASE_API_KEY name; or (B) change services.json/examples to
BUTTERBASE_API_KEY to match IGlobal.py—apply the chosen name consistently across
the runtime lookup in IGlobal.py, the "butterbase.api_key" preconfig in
services.json, and all example wiring. Ensure the env-var string literal
referenced is identical in all three places.
In `@nodes/test/tool_butterbase/test_tools.py`:
- Around line 86-96: Add assertions in the test to exercise IGlobal.endGlobal():
after invoking endGlobal() on the global instance used in the test, assert that
the fake client's stop() was called (e.g., _FakeClient.stopped is True) and that
any cached tool maps in the global implementation have been cleared (verify that
cached structures used by the code under test are empty or reset). Locate the
tests that create the _FakeClient and call into the global lifecycle (the setup
that calls into IGlobal and dispatches tools) and extend them to call
IGlobal.endGlobal(), then assert _FakeClient.stopped and inspect/clear the
cached tool registry/state to ensure no stale tool names remain.
- Around line 72-78: The test currently installs import stubs at collection time
via _ensure_rocketlib, _ensure_ai_common, and _ensure_pkg which mutates
sys.modules and leaks across the pytest session; change this by creating a
pytest fixture (e.g., stub_modules or isolated_modules) that runs these helpers
inside the fixture body and uses monkeypatch or pytest's monkeypatch fixture to
set/restore sys.modules entries so the stubs are only present during a test;
update tests to depend on that fixture and remove the top-level calls to
_ensure_rocketlib, _ensure_ai_common, and _ensure_pkg so module mutation is
isolated per-test.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: dbdebda2-e8f4-4a0a-a9ea-b831787c7b95
📒 Files selected for processing (10)
examples/butterbase-agent.pipenodes/src/nodes/tool_butterbase/IGlobal.pynodes/src/nodes/tool_butterbase/IInstance.pynodes/src/nodes/tool_butterbase/README.mdnodes/src/nodes/tool_butterbase/__init__.pynodes/src/nodes/tool_butterbase/mcp_streamable_http_client.pynodes/src/nodes/tool_butterbase/requirements.txtnodes/src/nodes/tool_butterbase/services.jsonnodes/test/tool_butterbase/__init__.pynodes/test/tool_butterbase/test_tools.py
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
nodes/src/nodes/tool_butterbase/mcp_streamable_http_client.py (2)
33-34:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDocstring references outdated spec version.
The docstring references "MCP spec 2025-03-26" but the code negotiates
_MCP_PROTOCOL_VERSION = '2025-11-25'. Update the docstring to match the actual protocol version.📝 Proposed fix
Spec reference: - MCP spec 2025-03-26: Streamable HTTP transport + MCP spec 2025-11-25: Streamable HTTP transport🤖 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 `@nodes/src/nodes/tool_butterbase/mcp_streamable_http_client.py` around lines 33 - 34, Update the module docstring to reference the correct MCP spec date that matches the negotiated protocol constant: change the docstring mention "MCP spec 2025-03-26" to "MCP spec 2025-11-25" so it aligns with _MCP_PROTOCOL_VERSION = '2025-11-25'; ensure any other human-readable spec references in the same file (e.g., top-level module docstring or comments) are updated consistently to avoid mismatch with the _MCP_PROTOCOL_VERSION symbol.
232-236: 🧹 Nitpick | 🔵 Trivial | 💤 Low valueRedundant condition - dead code.
Line 232's
not bodyalready handles empty bytes (b''is falsy), making lines 235-236 unreachable.♻️ Proposed fix
if 200 <= status < 300 and not body: return - # Some servers may return 200 with empty body; accept it. - if 200 <= status < 300 and body == b'': - return🤖 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 `@nodes/src/nodes/tool_butterbase/mcp_streamable_http_client.py` around lines 232 - 236, The second conditional checking "if 200 <= status < 300 and body == b''" is redundant because the earlier "if 200 <= status < 300 and not body" already covers empty bytes; remove the redundant block (the second if and its comment) in mcp_streamable_http_client.py where status and body are evaluated so only the first check remains and any explanatory comment reflects that empty bodies are accepted.nodes/src/nodes/tool_butterbase/services.json (1)
57-57:⚠️ Potential issue | 🟠 Major | ⚡ Quick winFix the tile template parameter namespace to use the protocol prefix.
The tile template references
${parameters.butterbase.serverName}, but according to this repo's convention, tile template parameters must use the node protocol prefix (tool_butterbase), not the field key prefix (butterbase). This mismatch will likely prevent the tile from rendering the server name correctly in the pipeline builder.🎨 Proposed fix
- "tile": ["Server: ${parameters.butterbase.serverName}"], + "tile": ["Server: ${parameters.tool_butterbase.serverName}"],Based on learnings: In tile template strings inside
services.json, the template parameter namespace should use the node protocol prefix (e.g.,${parameters.llm_minimax.profile}), not the declared field key prefix.🤖 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 `@nodes/src/nodes/tool_butterbase/services.json` at line 57, The tile template uses the wrong parameter namespace: change the template string in the "tile" field from "${parameters.butterbase.serverName}" to use the node protocol prefix, i.e. "${parameters.tool_butterbase.serverName}", so the tile will read the serverName from the tool_butterbase parameter namespace; update the "tile" entry accordingly.
🤖 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.
Outside diff comments:
In `@nodes/src/nodes/tool_butterbase/mcp_streamable_http_client.py`:
- Around line 33-34: Update the module docstring to reference the correct MCP
spec date that matches the negotiated protocol constant: change the docstring
mention "MCP spec 2025-03-26" to "MCP spec 2025-11-25" so it aligns with
_MCP_PROTOCOL_VERSION = '2025-11-25'; ensure any other human-readable spec
references in the same file (e.g., top-level module docstring or comments) are
updated consistently to avoid mismatch with the _MCP_PROTOCOL_VERSION symbol.
- Around line 232-236: The second conditional checking "if 200 <= status < 300
and body == b''" is redundant because the earlier "if 200 <= status < 300 and
not body" already covers empty bytes; remove the redundant block (the second if
and its comment) in mcp_streamable_http_client.py where status and body are
evaluated so only the first check remains and any explanatory comment reflects
that empty bodies are accepted.
In `@nodes/src/nodes/tool_butterbase/services.json`:
- Line 57: The tile template uses the wrong parameter namespace: change the
template string in the "tile" field from "${parameters.butterbase.serverName}"
to use the node protocol prefix, i.e.
"${parameters.tool_butterbase.serverName}", so the tile will read the serverName
from the tool_butterbase parameter namespace; update the "tile" entry
accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: d8ed2fdf-9472-4f53-a07e-d11a0a8d06b7
📒 Files selected for processing (2)
nodes/src/nodes/tool_butterbase/mcp_streamable_http_client.pynodes/src/nodes/tool_butterbase/services.json
…e API key) Its dynamic test would connect to the Butterbase MCP server and requires a live bb_sk_ key, so exclude it from the default CI run (opt-in via ROCKETRIDE_INCLUDE_SKIP). Mocked unit tests still cover the logic.
…) first to verify connectivity
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/butterbase-agent.pipe`:
- Around line 27-30: Update the agent prompt to use the runtime tool naming
convention with the butterbase namespace (butterbase.<tool>) instead of the
incorrect flat name butterbase_docs; specifically replace the call instruction
referencing butterbase_docs with butterbase.docs (or the correct
butterbase.<tool> name used by the runtime) and scan the "instructions" array in
the same file to update any other occurrences so the initial "call the docs"
step is reachable at runtime.
- Around line 120-126: The example pipe currently wires an OpenAI LLM (id
"llm_openai_1", "provider": "llm_openai", config key "openai-5-2" and env var
${ROCKETRIDE_OPENAI_KEY}) but the PR/docs expect a Wave+Anthropic setup; update
the pipe to either (A) replace the OpenAI block by an Anthropic block (change
"provider" to "llm_anthropic", set an Anthropic model key name instead of
"openai-5-2" and replace ${ROCKETRIDE_OPENAI_KEY} with
${ROCKETRIDE_ANTHROPIC_KEY}) or (B) keep the OpenAI block and add a new
"llm_anthropic" entry with its own id and config using
${ROCKETRIDE_ANTHROPIC_KEY}; ensure the chosen model key and provider string
match the rest of the PR/docs so the example reflects a
Wave+Anthropic+Butterbase setup.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 162219a5-e900-4879-bec8-c11ecf0db9b2
📒 Files selected for processing (1)
examples/butterbase-agent.pipe
…_mcp_client Per review: the cloned tool_butterbase node was byte-identical to tool_mcp_client (transport + IInstance), so drop it and add a branded manifest (tool_mcp_client/services.butterbase.json) that reuses the same implementation via path=nodes.tool_mcp_client — same pattern as response/*. Keeps the 'Butterbase MCP Client' title + logo + Butterbase Streamable-HTTP preset, with zero duplicated code. Removes the standalone node, its test, and the conftest skip entry; example pipe updated to the mcp_client config shape (transport+bearer).
… the forum Enrich the agent instructions with the practical lessons from repairing a real Butterbase app: enable Developer Mode for writes; keep schema/frontend field names consistent (body vs content); use the absolute data API base and the separate /auth/<app_id> base; set is_published for anon reads; auto-login after signup (no email verification needed); ensure the frontend deployment reaches READY.
…d docs tool, commented manifest - Example pipe: switch LLM to llm_anthropic (claude-sonnet-4-6, ROCKETRIDE_ANTHROPIC_KEY) to match the Wave+Anthropic+Butterbase intent. - Example pipe: the agent calls the runtime-namespaced tool 'butterbase.butterbase_docs' (serverName.tool), not the flat name. - services.butterbase.json: add the // Required/Optional comment blocks (matching llm_anthropic style) and ensure a trailing newline.
…ery URL Download the Butterbase mark, downscale to 96px, embed as a data-URI in a local butterbase.svg (next to mcp.svg) and point the manifest icon at it. Removes the runtime dependency on the external Smithery URL (which could disappear).
Summary
Type
feat
Testing
./builder testpassesChecklist
Linked Issue
Fixes #
Summary by CodeRabbit