Skip to content

feat: mcp - #74

Merged
sergiofilhowz merged 3 commits into
mainfrom
feat/mcp
May 4, 2026
Merged

sergiofilhowz merged 3 commits into
mainfrom
feat/mcp

Conversation

@sergiofilhowz

@sergiofilhowz sergiofilhowz commented May 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • HTTP-only MCP bridge configurable via YAML (POST /mcp) with api_path, timeouts, hidden-prefix rules, and require_expose flag
    • --manifest output and simplified CLI: --config, --url, --manifest
  • Refactor

    • Package/binary renamed to mcp and module surface streamlined; protocol reduced to core MCP v0.1 methods
    • Stdio transport removed in favor of HTTP bridge
  • Documentation

    • README updated with quickstart, tool-name mangling, and reduced surface/behavior list
  • Tests

    • Added comprehensive BDD suite and test helpers for core MCP behaviors

@coderabbitai

coderabbitai Bot commented May 4, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@sergiofilhowz has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 53 minutes and 52 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a1781f99-9ef2-4ad6-b90f-e4c100877747

📥 Commits

Reviewing files that changed from the base of the PR and between 30067a5 and 0655895.

⛔ Files ignored due to path filters (1)
  • mcp/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • mcp/Cargo.toml
  • mcp/src/functions/handler.rs
  • mcp/src/functions/mod.rs
  • mcp/src/manifest.rs
  • mcp/src/protocol.rs
  • mcp/tests/features/tools.feature
  • mcp/tests/steps/tools.rs
📝 Walkthrough

Walkthrough

Replaces the old multi-transport MCP worker with a simplified HTTP-only MCP bridge: new config, protocol helpers, and a compact JSON-RPC dispatcher; removes legacy stdio/transport, session state, prompts, spec helpers, and worker-manager code; adds manifest support and a Cucumber BDD test harness with feature files and step defs.

Changes

MCP Worker Restructure (core feature DAG)

Layer / File(s) Summary
Data Shape & Protocol
mcp/src/protocol.rs, mcp/src/config.rs, mcp/config.yaml
Adds MCP_PROTOCOL_VERSION, JSON-RPC error constants, JsonRpcResponse/JsonRpcError, tool ↔ function id mapping, schema sanitization, hidden-prefix / expose checks; introduces McpConfig with serde defaults and YAML schema (api_path, state_timeout_ms, hidden_prefixes, require_expose).
Core Implementation
mcp/src/functions/handler.rs
New JSON-RPC dispatcher (handle + dispatch) that accepts engine HTTP trigger envelopes or raw payloads; parses/validates frames; implements initialize, ping, tools/list, tools/call, resources/*, prompts/*; enforces hidden-prefixes and optional require_expose; delegates to engine/skills/prompts via triggers.
Wiring / Integration
mcp/src/functions/mod.rs, mcp/src/lib.rs, mcp/src/main.rs
register_all(iii,cfg) registers mcp::handler and an HTTP POST trigger at cfg.api_path; library exports updated (config, functions, manifest, protocol); CLI simplified and manifest mode added; main loads YAML config and registers handlers.
Build & Manifest
mcp/Cargo.toml, mcp/build.rs, mcp/src/manifest.rs
Cargo manifest rewritten (crate mcp, lib name iii_mcp, bin mcp, dependency updates, dev deps and bdd test target); build.rs emits TARGET into env; ModuleManifest and --manifest output implemented.
Removals / Cleanup
mcp/src/handler.rs, mcp/src/transport.rs, mcp/src/spec.rs, mcp/src/prompts.rs, mcp/src/worker_manager.rs, mcp/examples/*
Removes legacy stdio transport, session-scoped handler/state, spec helpers, prompt generator module, worker-manager logic, and an example auth file—consolidating behavior into protocol/functions modules.
Documentation & Metadata
mcp/README.md, mcp/iii.worker.yaml
README rewritten for HTTP POST /mcp bridge, method coverage, name-mangling and hiding rules, and config; worker YAML updated to use bin: mcp.

BDD Test Harness & Fixtures (independent DAG focused on tests)

Layer / File(s) Summary
Test Harness Core
mcp/Cargo.toml (dev-deps), mcp/tests/bdd.rs, mcp/tests/common/engine.rs
Adds cucumber-based BDD target (bdd), async Cucumber entry that connects-or-skips engine, .before hooks, and env-driven required-engine gating; common::engine connects to engine with retries and caches III handle.
Test Fixtures & Registration
mcp/tests/common/workers.rs, mcp/tests/common/mod.rs
Idempotent register_all that stubs/registrars skills/prompts fixtures and two tool fixtures (bdd::echo, bdd::boom); global shared McpConfig state for tests.
World Model
mcp/tests/common/world.rs
Adds IiiMcpWorld with optional engine handle, shared config, scenario-unique id, and stash for step communication.
Feature Specs
mcp/tests/features/*.feature
Adds Gherkin features: core, tools, resources, prompts with scenarios covering initialize/ping, tools list/call, resources read/list/templates, prompts list/get and error cases.
Step Definitions
mcp/tests/steps/*, mcp/tests/steps/mod.rs
Implements Rust step defs for features; helpers to trigger mcp::handler, stash/unpack envelopes, and assertions for protocol fields, tool content, resource/prompt delegation, and error codes.
Smoke / Manifest Test
mcp/tests/manifest.rs
Adds manifest subcommand test asserting manifest JSON fields and default config values; removes old CLI/unit tests that relied on previous binary flags.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Engine as iii Engine<br>(HTTP)
    participant Handler as mcp::handler
    participant Protocol as protocol helpers
    participant Skills as skills Worker
    participant Tool as Tool Function

    Client->>Engine: POST /mcp {"jsonrpc":"2.0","id":1,"method":"tools/list"}
    Engine->>Handler: TriggerRequest(payload)
    Handler->>Handler: parse_body() / validate_frame()
    Handler->>Engine: trigger("engine::functions::list")
    Engine->>Handler: FunctionInfo[]
    Handler->>Protocol: filter hidden/exposed & function_to_tool()
    Handler->>Engine: return HTTP envelope (200) with JSON-RPC result
    Engine->>Client: 200 + body with tools list

    Client->>Engine: POST /mcp {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{...}}
    Engine->>Handler: TriggerRequest(payload)
    Handler->>Protocol: tool_name_to_function_id(), is_hidden()
    Handler->>Engine: trigger("bdd::echo", params)
    Engine->>Tool: execute
    Tool->>Engine: result
    Handler->>Protocol: tool_text()/tool_error()
    Handler->>Engine: return HTTP envelope (200) with tool result

    Client->>Engine: POST /mcp {"jsonrpc":"2.0","id":3,"method":"resources/read","params":{"uri":"iii://demo"}}
    Engine->>Handler: TriggerRequest(payload)
    Handler->>Handler: delegate to skills::resources-read
    Handler->>Engine: trigger("skills::resources-read", params)
    Engine->>Skills: execute
    Skills->>Engine: resource payload
    Handler->>Engine: return HTTP envelope (200) with resource result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

  • iii-hq/workers#13: overlapping changes around manifest, build, and tool-name sanitization.
  • iii-hq/workers#70: implements the skills worker endpoints that this bridge delegates to.
  • iii-hq/workers#4: prior MCP implementation refactored/replaced by this PR.

Suggested reviewers

  • ytallo

Poem

🐰 I hopped through code at break of day,
Old transports tucked politely away,
YAML maps the path so neat,
Handler hums — responses sweet,
BDD hops, features all in view—
A tidy bridge, fresh and new! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The PR title 'feat: mcp' is generic and vague, using a non-descriptive term that does not convey meaningful information about the substantial changes made. Consider a more descriptive title such as 'feat: implement MCP JSON-RPC bridge handler and worker registration' to better reflect the scope of architectural changes and new functionality.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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
  • Commit unit tests in branch feat/mcp

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 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: 10

🧹 Nitpick comments (1)
mcp/src/manifest.rs (1)

14-38: ⚡ Quick win

Derive default_config from McpConfig::default() rather than hardcoding it.

The inline serde_json::json!({...}) block on lines 21–35 duplicates the defaults already authoritative in config.rs. When a field is added to or changed in McpConfig, this block silently drifts — and the duplication already shows: require_expose (present in McpConfig) is absent here. Serializing McpConfig::default() directly keeps the two in sync without a second list to maintain.

♻️ Proposed refactor
+use crate::config::McpConfig;
 use serde::Serialize;

 pub fn build_manifest() -> ModuleManifest {
+    let default_cfg = McpConfig::default();
     ModuleManifest {
         name: env!("CARGO_PKG_NAME").to_string(),
         version: env!("CARGO_PKG_VERSION").to_string(),
         description:
             "Model Context Protocol bridge. Exposes iii functions as MCP tools and the skills worker as MCP resources/prompts over POST /mcp."
                 .to_string(),
-        default_config: serde_json::json!({
-            "api_path": "mcp",
-            "state_timeout_ms": 30_000,
-            "hidden_prefixes": [
-                "engine::",
-                "state::",
-                "stream::",
-                "iii.",
-                "iii::",
-                "mcp::",
-                "a2a::",
-                "skills::",
-                "prompts::"
-            ]
-        }),
+        default_config: serde_json::to_value(&default_cfg)
+            .expect("McpConfig is always serializable"),
         supported_targets: vec![env!("TARGET").to_string()],
     }
 }
🤖 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 `@mcp/src/manifest.rs` around lines 14 - 38, The manifest's default_config is
hardcoded via serde_json::json! causing duplication with McpConfig defaults;
change build_manifest to set ModuleManifest.default_config by serializing
McpConfig::default() instead (e.g., use
serde_json::to_value(McpConfig::default()) or equivalent) so that the
default_config derives from McpConfig::default() and includes fields like
require_expose automatically; update the build_manifest function (reference:
build_manifest, ModuleManifest, default_config, McpConfig::default) to perform
that serialization and handle any Result/error as needed.
🤖 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 `@mcp/README.md`:
- Around line 7-14: The README lists `prompts/list` and `prompts/get` as backed
by the `skills` worker but the runtime actually wires them to the prompts worker
under `prompts::mcp-list` and `prompts::mcp-get`; update the table rows and any
install guidance so that `prompts/list` and `prompts/get` reference the prompts
worker (e.g., `prompts::mcp-list`, `prompts::mcp-get`) instead of `skills`, and
ensure the later method coverage table matches this same change so users are
pointed to the correct backing worker.

In `@mcp/src/config.rs`:
- Around line 60-64: The load_config function should validate or normalize the
api_path field on McpConfig to reject or strip a leading '/' so downstream code
(e.g., register_http_trigger which does format!("/{}", api_path) in
functions::mod.rs) does not produce double slashes; update load_config to parse
the YAML into McpConfig then either trim a leading '/' from cfg.api_path or
return an Err if api_path starts_with('/') and include a clear error message,
referencing the McpConfig type and the load_config function for location.

In `@mcp/src/functions/handler.rs`:
- Around line 193-229: In tools_call, enforce the same "require_expose"
execution guard used by tools/list: after computing function_id with
protocol::tool_name_to_function_id and before triggering ctx.iii.trigger, check
the require_expose flag on ctx.cfg and verify the function is explicitly exposed
(use the same predicate used by tools/list — e.g. a protocol::is_exposed or
equivalent check against ctx.cfg.exposed list); if require_expose is true and
the function is not exposed, return protocol::tool_error denying execution
instead of proceeding to ctx.iii.trigger. Ensure you reference tools_call,
protocol::tool_name_to_function_id, ctx.cfg.require_expose (or equivalent), and
the exposure-check helper used by tools/list.
- Around line 111-146: The dispatch function currently treats any message
lacking an id as a notification before verifying the shape of the JSON-RPC
frame, allowing malformed payloads (e.g. {}, [], scalars) to be swallowed;
change dispatch to first validate that the incoming body is a JSON object and
that "method" exists and is a string (use the same extraction logic around
method = body.get("method").and_then(|v| v.as_str()) but check for None/invalid
types), and if validation fails return a JSON-RPC Invalid Request error (use
JsonRpcResponse::error with the INVALID_REQUEST constant) rather than returning
None; only after confirming a valid string method should you apply the
notification fast-path (method.starts_with("notifications/") || id.is_none())
and proceed to the existing match (e.g., tools_list, tools_call, resources_read,
prompts_get, etc.).

In `@mcp/src/functions/mod.rs`:
- Around line 20-23: Change register_all to return a Result or status rather
than unit so HTTP trigger registration failures bubble to the caller: update the
signature of register_all(iii: &Arc<III>, cfg: &Arc<McpConfig>) -> Result<(),
SomeError> (or -> bool) and have it call register_handler and then call
register_http_trigger propagating any error from register_http_trigger (do not
swallow errors). Update register_handler and/or register_http_trigger return
types as needed so register_all can propagate failures, and update the calling
site in main to check the returned Result/status and abort or avoid advertising
readiness on error; the same change should be applied to the other registration
block referenced (the code around register calls at 62-79). Ensure error types
are mapped or converted consistently so main can inspect and log the failure.
- Around line 62-70: Normalize or reject leading slashes on api_path in
register_http_trigger: inside the register_http_trigger function, inspect
cfg.api_path before building RegisterTriggerInput and either strip a leading '/'
(e.g., api_path = api_path.trim_start_matches('/')) or return/raise an error
when api_path.starts_with('/'); then pass the normalized string into the JSON
config for RegisterTriggerInput (config.api_path) so the engine never receives a
value beginning with '/'.

In `@mcp/src/protocol.rs`:
- Around line 106-112: The current bidirectional mapping in
function_id_to_tool_name and tool_name_to_function_id is ambiguous when function
IDs contain "__"; fix by making the encoding collision-free or by rejecting
ambiguous IDs: either (A) change the converters to encode "::" with a safe
scheme (e.g., percent-encode "::" or use an escape sequence that cannot occur in
function IDs) so round-trips are lossless, or (B) add explicit validation that
function IDs do not contain "__" (validate in function_id_to_tool_name and at
the tools/call dispatch entry) and return a clear error when violated; update
the dispatch handling that looks up tools/call to check for this guard and
expand the round-trip tests to include the previously ambiguous case
("worker_v2__util::action") to ensure correct behavior.

In `@mcp/tests/common/engine.rs`:
- Around line 57-60: The closure passed to get_or_init is swallowing
registration errors by calling register_all(&iii).await.ok()? which converts
failures into None (treated as "skip"); change this to propagate failures
instead so test setup fails on registration errors—replace the .ok()? pattern
with a fallible await (e.g., use register_all(&iii).await? or explicitly map the
Result to an error) so that register_all errors cause the get_or_init future to
return an Err and not set world.iii to None; update the closure around
try_connect_raw(), register_all, and the Some(iii) return to propagate
registration errors rather than downgrading them to skips.

In `@mcp/tests/steps/core.rs`:
- Around line 17-20: The step functions (e.g., call_handler) currently use
guarded early returns when world.iii is None, which skips tests; instead require
the engine be present so the scenario fails: replace the pattern `let Some(iii)
= world.iii.clone() else { return; }` with a hard requirement (e.g.,
assert/expect that world.iii is Some or call unwrap/expect) so the test fails if
the engine is missing; apply the same change to the other step functions
referenced (the guards at the other listed locations) so all steps depend on
world.iii being present rather than silently returning.

In `@mcp/tests/steps/tools.rs`:
- Around line 47-59: In includes_echo, the test currently asserts msg is the
first entry by checking echo["inputSchema"]["required"][0]; change this to
assert that the "required" array contains "msg" regardless of order: locate the
echo object found via tools.iter().find(...) (function includes_echo and
variables v, tools, echo) and replace the index-based assertion with a
membership check over echo["inputSchema"]["required"] (e.g., iterate or use
any/contains logic) so the test passes even if field order changes.

---

Nitpick comments:
In `@mcp/src/manifest.rs`:
- Around line 14-38: The manifest's default_config is hardcoded via
serde_json::json! causing duplication with McpConfig defaults; change
build_manifest to set ModuleManifest.default_config by serializing
McpConfig::default() instead (e.g., use
serde_json::to_value(McpConfig::default()) or equivalent) so that the
default_config derives from McpConfig::default() and includes fields like
require_expose automatically; update the build_manifest function (reference:
build_manifest, ModuleManifest, default_config, McpConfig::default) to perform
that serialization and handle any Result/error as needed.
🪄 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: 37cd4da0-e860-49c4-ab0c-e7043a50ac12

📥 Commits

Reviewing files that changed from the base of the PR and between 93a3f96 and 39837ef.

⛔ Files ignored due to path filters (1)
  • mcp/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (36)
  • mcp/Cargo.toml
  • mcp/README.md
  • mcp/build.rs
  • mcp/config.yaml
  • mcp/examples/default-secure-auth.rs
  • mcp/iii.worker.yaml
  • mcp/src/config.rs
  • mcp/src/functions/handler.rs
  • mcp/src/functions/mod.rs
  • mcp/src/handler.rs
  • mcp/src/lib.rs
  • mcp/src/main.rs
  • mcp/src/manifest.rs
  • mcp/src/prompts.rs
  • mcp/src/protocol.rs
  • mcp/src/spec.rs
  • mcp/src/transport.rs
  • mcp/src/worker_manager.rs
  • mcp/tests/bdd.rs
  • mcp/tests/cli.rs
  • mcp/tests/common/engine.rs
  • mcp/tests/common/mod.rs
  • mcp/tests/common/workers.rs
  • mcp/tests/common/world.rs
  • mcp/tests/features/core.feature
  • mcp/tests/features/prompts.feature
  • mcp/tests/features/resources.feature
  • mcp/tests/features/tools.feature
  • mcp/tests/manifest.rs
  • mcp/tests/protocol_loop_guard.rs
  • mcp/tests/spec_2a.rs
  • mcp/tests/steps/core.rs
  • mcp/tests/steps/mod.rs
  • mcp/tests/steps/prompts.rs
  • mcp/tests/steps/resources.rs
  • mcp/tests/steps/tools.rs
💤 Files with no reviewable changes (9)
  • mcp/tests/cli.rs
  • mcp/examples/default-secure-auth.rs
  • mcp/src/prompts.rs
  • mcp/tests/protocol_loop_guard.rs
  • mcp/src/worker_manager.rs
  • mcp/src/handler.rs
  • mcp/src/transport.rs
  • mcp/tests/spec_2a.rs
  • mcp/src/spec.rs

Comment thread mcp/README.md
Comment thread mcp/src/config.rs
Comment thread mcp/src/functions/handler.rs Outdated
Comment thread mcp/src/functions/handler.rs
Comment thread mcp/src/functions/mod.rs Outdated
Comment thread mcp/src/functions/mod.rs Outdated
Comment thread mcp/src/protocol.rs
Comment thread mcp/tests/common/engine.rs
Comment thread mcp/tests/steps/core.rs
Comment thread mcp/tests/steps/tools.rs
@sergiofilhowz

Copy link
Copy Markdown
Contributor Author

CodeRabbit review pass

Worked through every actionable comment + the nitpick. Summary of what landed and what I'm deferring, with rationale.

Addressed (10 of 11)

# Comment Change
2 + 6 api_path leading-slash Strip in register_http_trigger (defensive at the engine boundary) and in load_config (early-feedback warn at YAML load). New tests cover /mcp and //mcp cases.
3 dispatch swallows malformed frames Extracted validate_frame() as a pure helper. Rejects non-object bodies, missing/non-string method, and {"id":1}-with-no-method as -32600 INVALID_REQUEST instead of falling through to the notification fast-path. 5 new unit tests.
4 tools/call bypassed require_expose Added an execution guard: when cfg.require_expose is on, tools/call resolves the function via engine::functions::list and rejects with tool_error unless metadata.mcp.expose == true. The extra round trip is opt-in.
5 register_all swallowed trigger failures Now returns Result<(), IIIError>. main logs error! (no longer claims mcp ready) on failure; the BDD harness logs a warn and keeps going (HTTP trigger isn't needed for direct mcp::handler invocation).
7 __-encoding is not bijective Three-layer fix: (a) debug_assert! in function_id_to_tool_name, (b) is_tool_name_ambiguous() filters __-bearing IDs from tools/list with a warn log, (c) tools/call re-encodes the resolved function id and rejects with tool_error if the round-trip diverges. 2 new unit tests.
8 engine.rs .ok()? swallowed registration errors as skips Switched to .expect("failed to register MCP test workers"). Connection failures still degrade to None for --tags @pure; registration failures are now loud.
9 Step-level soft-skip pattern Kept the per-step if world.iii.is_none() { return; } (deliberate design for --tags @pure on engine-less dev hosts) but added a harness-level III_ENGINE_REQUIRED=1 env gate in bdd.rs that panics at startup if the engine is unreachable. README documents the new env var for CI use.
10 tools.rs required[0] brittle Changed to membership check over the required array.
11 (nitpick) manifest default_config drift Now derives from serde_json::to_value(McpConfig::default()). Pulls in require_expose automatically and prevents future drift. New test asserts every McpConfig field is present in the manifest output.

Deferred (1 of 11) — comment is based on a wrong premise

# Comment Reason
1 README says prompts/list/prompts/get are backed by the skills worker but the runtime calls prompts::mcp-list / prompts::mcp-get The prompts::mcp-list and prompts::mcp-get functions are registered by the skills worker (see skills/src/functions/prompts.rs:239,254). They use the prompts:: namespace but ship in the skills binary — there is no separate prompts worker in the workspace. The README's "Install skills" guidance is therefore correct, and the lower-table entries pointing to prompts::mcp-* describe the function IDs (also correct). No change needed.

Verification

  • cargo test --lib — 48/48 pass (8 of those are new: 5 for validate_frame, 2 for the __ ambiguity check, 1 for manifest field completeness, 2 for api_path normalization).
  • cargo test --test manifest — passes.
  • cargo clippy --all-targets -- -D warnings — clean.
  • cargo test --test bdd — 15/16 scenarios pass with my changes (same as without). The single failing scenario tools/call without params returns -32602 was failing before my changes too — iii.trigger("mcp::handler", body) returns Err for a body with no params field, so the response never reaches the assertion. Worth a separate look (likely engine-side request-validation), but unrelated to this review pass.

Files touched

mcp/README.md                |   5 +
mcp/src/config.rs            |  37 +-
mcp/src/functions/handler.rs | 258 +-
mcp/src/functions/mod.rs     |  42 +-
mcp/src/main.rs              |  23 +-
mcp/src/manifest.rs          |  37 +-
mcp/src/protocol.rs          |  44 +
mcp/tests/bdd.rs             |  32 +-
mcp/tests/common/engine.rs   |   9 +-
mcp/tests/common/workers.rs  |  12 +-
mcp/tests/steps/tools.rs     |   8 +-

@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: 1

🤖 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 `@mcp/src/protocol.rs`:
- Around line 185-187: In sanitize_schema, the current branch that replaces any
boolean schema (matches!(prop, Value::Bool(_))) with json!({}) incorrectly turns
false (never-valid) into {} (always-valid); change it to inspect the boolean
value and: if true, set *prop = json!({}) (always-valid), if false, set *prop =
json!({"not": {}}) (never-valid) so JSON Schema semantics are preserved. Target
the sanitize_schema function and the variable prop in that match arm to
implement this conditional replacement.
🪄 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: cb6ea97a-a310-4d2e-8eba-66b8b39256aa

📥 Commits

Reviewing files that changed from the base of the PR and between 39837ef and 30067a5.

📒 Files selected for processing (11)
  • mcp/README.md
  • mcp/src/config.rs
  • mcp/src/functions/handler.rs
  • mcp/src/functions/mod.rs
  • mcp/src/main.rs
  • mcp/src/manifest.rs
  • mcp/src/protocol.rs
  • mcp/tests/bdd.rs
  • mcp/tests/common/engine.rs
  • mcp/tests/common/workers.rs
  • mcp/tests/steps/tools.rs
✅ Files skipped from review due to trivial changes (2)
  • mcp/tests/common/workers.rs
  • mcp/README.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • mcp/src/manifest.rs
  • mcp/tests/bdd.rs
  • mcp/src/config.rs
  • mcp/src/main.rs
  • mcp/src/functions/handler.rs

Comment thread mcp/src/protocol.rs
@sergiofilhowz
sergiofilhowz merged commit 81af399 into main May 4, 2026
7 checks passed
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