Skip to content

fix(mcp-gate): handle JSON-RPC notifications correctly#379

Open
namesreallyblank wants to merge 2066 commits intoruvnet:mainfrom
namesreallyblank:fix/mcp-gate-notification-handling
Open

fix(mcp-gate): handle JSON-RPC notifications correctly#379
namesreallyblank wants to merge 2066 commits intoruvnet:mainfrom
namesreallyblank:fix/mcp-gate-notification-handling

Conversation

@namesreallyblank
Copy link
Copy Markdown

Problem

mcp-gate rejects MCP notifications (e.g. notifications/initialized) with a parse error because the JsonRpcRequest struct treats id as required. Per JSON-RPC 2.0 spec, notifications carry no id. The current behavior also violates the spec by sending an error response to a notification (notifications must not receive responses).

This causes Claude Code's CLI to drop the connection during the MCP handshake — Claude Code treats the unexpected error response as a protocol failure.

Fix

  1. types.rs: change id: serde_json::Value -> id: Option<serde_json::Value> with #[serde(default)]
  2. server.rs: in handle_message, check if id.is_none() and return None for notifications instead of always returning a response
  3. Updated 8 call sites that used request.id.clone() to handle the Option

Testing

  • 16 unit tests passing (added 2 new ones for notification handling)
  • Verified manual handshake: initialize -> notifications/initialized -> tools/list returns 2 responses, no response for notification
  • Verified Claude Code CLI now connects successfully where it timed out before

Reference

ruvnet and others added 30 commits February 20, 2026 21:00
Merges PR ruvnet#181 fixes:
- SIGSEGV on repeated queries (xs_orderbyvals allocation)
- Bidirectional HNSW connections with pruning
- Correct distance metric from operator class
- Sorted result ordering (into_sorted_vec)
- xs_recheckorderby=false for PG17
- Null-safe endscan (use-after-free fix)
- Bounds checks for page boundary reads
- Non-kNN scan fallback (COUNT/WHERE IS NOT NULL)
- Dimension extraction from atttypmod

Co-Authored-By: claude-flow <ruv@ruv.net>
  Built from commit 72c2a8e

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
  Built from commit 881ba31

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
rvlite's writer_lease.rs used __errno_location (Linux libc) under a
generic #[cfg(unix)] guard, causing link failures on macOS where the
equivalent is __error. Split the extern and wrapper into separate
#[cfg(target_os)] blocks matching the pattern already used in
rvf-runtime/src/locking.rs.

Closes ruvnet#174

Co-Authored-By: claude-flow <ruv@ruv.net>
fix(rvlite): macOS linking bug — platform-specific errno
  Built from commit ba66880

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
The chat() method signature is (sessionId, content, options?) but the API
handler was passing (sessionId, agentId, message), causing TS2559. Fix by
creating a session from agentId first, then calling chat(sessionId, message).

Co-Authored-By: claude-flow <ruv@ruv.net>
- Build real Linux 6.6.80 bzImage with tinyconfig+virtio+net (1.5 MB)
- Create build-rvf.js that assembles self-contained RVF binary:
  KERNEL_SEG: gzip-compressed Linux 6.6.80 bzImage (MicroLinux, x86_64)
  WASM_SEG: Full RuvBot Node.js runtime bundle (2.2 MB)
  META_SEG: Package metadata with capabilities
  PROFILE_SEG: AI assistant domain profile
  WITNESS_SEG: Build provenance chain
  MANIFEST_SEG: Segment directory
- Include kernel/bzImage and ruvbot.rvf in npm distribution
- Add build:rvf script to package.json
- Total RVF: 3.67 MB, bootable with Firecracker/QEMU/Cloud Hypervisor

Co-Authored-By: claude-flow <ruv@ruv.net>
…a-binaries

feat(ruvbot): self-contained RVF with real Linux 6.6 kernel + API server fix
Co-Authored-By: claude-flow <ruv@ruv.net>
  Built from commit e34a47c

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
  Built from commit 5e776f3

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
Adds run-rvf.js that extracts the kernel from KERNEL_SEG, builds a
minimal initramfs with a static init binary, and boots via QEMU.
Rebuilds kernel with CONFIG_BLK_DEV_INITRD for initramfs support.

Modes: --boot (QEMU), --runtime (Node.js), --inspect (manifest)

Co-Authored-By: claude-flow <ruv@ruv.net>
Add comprehensive RVF section to README covering segment layout,
build/run commands, boot output, supported hypervisors, and kernel
config. Add run:rvf and inspect:rvf npm scripts.

Co-Authored-By: claude-flow <ruv@ruv.net>
  Built from commit 293b31a

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
…iner

6-layer defense-in-depth in a single sealed RVF file:
  1. TEE attestation (SGX, SEV-SNP, TDX, ARM CCA) with bound keys
  2. Hardened Linux microkernel (16 security configs, REQUIRES_TEE)
  3. eBPF packet filter (XDP) + syscall enforcer (Seccomp)
  4. AIDefence WASM engine (injection, jailbreak, PII, behavioral)
  5. Ed25519 signing + SHAKE-256 content hashes + Paranoid policy
  6. 6-role RBAC + Coherence Gate authorization

20 capabilities verified, 10/10 AIDefence tests, 3/3 tamper rejections,
30-entry witness chain, 1000 threat signatures (512-dim), 3 tenant stores.

Co-Authored-By: claude-flow <ruv@ruv.net>
Include the generated 2.1 MB .rvf binary artifact in repo alongside
the v2.0 optimized example (22 capabilities, zero warnings, Paranoid
policy, audited queries, COW branching, SSN/encoding detection).

Co-Authored-By: claude-flow <ruv@ruv.net>
Copy the 2.1 MB sealed RVF artifact to examples/ for easier discovery.

Co-Authored-By: claude-flow <ruv@ruv.net>
- Add security_hardened.rvf entry to RVF Cognitive Containers section
- Add to examples table as top entry
- Link ADR-042 alongside ADR-030 and ADR-031
- Update capabilities table from 20 to 22 (COW branching, audited queries, exfil detection)

Co-Authored-By: claude-flow <ruv@ruv.net>
Upgrade from 22 to 30 capabilities exercising every major RVF API:
- KernelBinding anti-tamper (manifest_root + policy_hash binding)
- Dual WASM modules (Interpreter + Microkernel, self-bootstrapping)
- DASHBOARD_SEG embedded security monitoring UI
- Scalar quantization (int8, 4x compression) via rvf-quant
- Binary quantization (1-bit, 32x compression) + Hamming distance
- Filter deletion + compaction lifecycle
- QEMU requirements check via rvf-launch
- Freeze/seal permanent immutability
- Additional kernel flags: VIRTIO_NET, VSOCK, INGEST_API
- RvfOptions: signing=true, profile=3, m=32, ef_construction=400

Co-Authored-By: claude-flow <ruv@ruv.net>
feat(security): ADR-042 Security RVF — AIDefence + TEE hardened container
  Built from commit 6b20327

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
…Learning

Implement trait-based IntelligenceProvider extension point for external
quality signals. Addresses PR ruvnet#190 proposal (renumbered from ADR-029 to
avoid collision with existing ADR-029-rvf-canonical-format).

- IntelligenceProvider trait with load_signals() and quality_weights()
- FileSignalProvider built-in for JSON file-based signal exchange
- IntelligenceLoader for multi-provider registration and aggregation
- QualitySignal, QualityFactors, ProviderQualityWeights types
- calibration_bias() on TaskComplexityAnalyzer for router feedback
- 12 unit tests (all passing)

Co-Authored-By: claude-flow <ruv@ruv.net>
…roviders

feat(intelligence): ADR-043 External Intelligence Providers
  Built from commit db8f83a

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
TypeScript IntelligenceProvider, FileSignalProvider, and
IntelligenceLoader matching the Rust ADR-043 implementation.
Also fixes invalid category slug for ruvllm crate publish.

Co-Authored-By: claude-flow <ruv@ruv.net>
  Built from commit 4e37468

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
… validation, file size limits

Security hardening for ADR-043 intelligence module:
- Replace String outcome/verdict with Outcome and HumanVerdict enums (type safety)
- Add MAX_SIGNAL_FILE_SIZE (10 MiB) and MAX_SIGNALS_PER_FILE (10,000) limits
- BufReader streaming parse instead of read_to_string (prevent double allocation)
- Validate quality_score range (finite, 0.0-1.0) on load
- NaN protection in calibration_bias()
- TypeScript: top-level imports, runtime validation, file size checks, score clamping
- Bump workspace to 2.0.4, @ruvector/ruvllm to 2.5.1
- Published ruvllm@2.0.4 to crates.io, @ruvector/ruvllm@2.5.1 to npm

Co-Authored-By: claude-flow <ruv@ruv.net>
  Built from commit 62436a4

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
…nd (ruvnet#180)

Fix SPARQL parser backtrack, executor memory leak, and add catch_unwind
github-actions Bot and others added 30 commits February 27, 2026 04:54
  Built from commit 960abf9

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
  Built from commit b943018

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
…System

Co-Authored-By: claude-flow <ruv@ruv.net>
Co-Authored-By: claude-flow <ruv@ruv.net>
  Built from commit ca1de23

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
  Built from commit 494ab00

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
Co-Authored-By: claude-flow <ruv@ruv.net>
  Built from commit a4d891a

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
  Built from commit 4f70c24

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
- New README for domain expansion crate (cross-domain transfer learning)
- All 20 AI OS table layer titles now link to their crate READMEs

Co-Authored-By: claude-flow <ruv@ruv.net>
  Built from commit c82f72f

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
  Built from commit 79ea21a

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
  Built from commit 926aa52

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
  Built from commit 89c4f2d

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
…infrastructure map

Add genomics, trading, quantum, neuromorphic, graph intelligence, nervous
systems, scientific OCR, knowledge graphs, GNN, and SONA as specialized
domains with transfer value explanations. Add cross-domain transfer examples
table, domain connectivity diagram, and underlying infrastructure layer map.

Co-Authored-By: claude-flow <ruv@ruv.net>
The DRY refactor that extracted shared clustering code accidentally
removed the HashMap import still needed by merge_scenes.

https://claude.ai/code/session_01H1GkTK5z9ppVVQDQukjBsY
  Built from commit cff4349

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
…ross-domain transfer

Performance optimizations (net -134 lines):
- BinaryHeap kNN: O(n log k) vs O(n log n) full sort in SpatialIndex
- Zero-clone behavior tree tick via pointer-based borrow splitting
- VecDeque percept buffer for O(1) front eviction
- HashSet assigned_robots for O(1) membership checks
- Shared clustering module eliminates 3 duplicate implementations

Correctness fixes:
- UntilFail decorator 10k iteration guard prevents infinite loops
- OccupancyGrid bounds-checked get() returns Option<f32>
- Pipeline position_history capped at 1000 entries
- Skill learning gracefully handles empty demonstrations
- Anomaly type gets Serialize/Deserialize derives

Dead code removal:
- Remove unused TrajectoryPoint struct
- Remove unused tracing and rand dependencies

Domain expansion integration (behind `domain-expansion` feature flag):
- RoboticsDomain implements domain::Domain trait with 5 task categories:
  PointCloudClustering, ObstacleAvoidance, SceneGraphConstruction,
  SkillSequencing, SwarmFormation
- 64-dim embedding space compatible with planning/orchestration/synthesis
- Reference solutions, difficulty scaling, cross-domain transfer tests
- Enables Meta Thompson Sampling transfer between robotics and
  existing domains (Rust synthesis, structured planning, tool orchestration)

All 257 tests pass (231 unit + 25 integration + 1 doc-test).

https://claude.ai/code/session_01H1GkTK5z9ppVVQDQukjBsY
- Remove unsafe pointer aliasing in BehaviorTree::tick(), use safe
  disjoint field borrowing instead (P0)
- Fix usize underflow in score_scene_graph when expected_objects < 2 (P0)
- Fix cluster ID overflow in reference_solution for PointCloudClustering (P0)
- Fix NaN handling in MaxDistEntry::cmp — NaN treated as maximally
  distant so it gets evicted from kNN heap first (P1)
- Clamp cosine_distance output to prevent negative values from
  floating-point rounding (P1)
- Change search_radius to return Ok(Vec::new()) for empty index instead
  of Err(EmptyIndex) for correct semantics (P1)
- Add debug_assert guards for empty slices in bounding_sphere and
  cluster_to_object (P1)
- Remove dead PipelineConfig.spatial_search_k field (P2)
- Use serde_json::from_value instead of to_string+from_str roundtrip
  in domain_expansion for better performance (P2)

All 257 tests pass.

https://claude.ai/code/session_01H1GkTK5z9ppVVQDQukjBsY
…usion, and benchmarks

New modules for ruvector-robotics:
- bridge/gaussian: GaussianSplat types, PointCloud→Gaussian conversion, vwm-viewer JSON export
- planning: A* pathfinding on OccupancyGrid with octile heuristic, potential field velocity commands
- mcp/executor: ToolExecutor dispatching ToolRequests to perception pipeline and spatial index
- perception/sensor_fusion: multi-sensor cloud fusion with timestamp alignment and voxel downsampling

Rewrites integration tests to use actual crate APIs instead of local reimplementations,
eliminating ~280 lines of false-positive test code. Adds 15 benchmark groups covering
all new modules (Gaussian conversion, A* planning, potential fields, sensor fusion, MCP execution).

All 270+ tests pass including domain-expansion feature.

https://claude.ai/code/session_01H1GkTK5z9ppVVQDQukjBsY
New `rvf` feature flag enables the `ruvf::RoboticsRvf` wrapper that
bridges point clouds, scene graphs, trajectories, Gaussian splats, and
obstacles into the RuVector Format (.rvf) for persistence and similarity
search.

RoboticsRvf supports:
- pack_point_cloud (dim 3)
- pack_scene_objects / pack_scene_graph (dim 9)
- pack_trajectory (dim 3)
- pack_gaussians (dim 7) — converts PointCloud→GaussianSplatCloud→RVF
- pack_obstacles (dim 6)
- query_nearest (kNN via HNSW index)
- open/open_readonly/close lifecycle

9 unit tests covering create, ingest, query, reopen, dimension mismatch,
and empty data rejection. Also fixes unused import warnings in integration
tests. All 290 tests pass across default, domain-expansion, and rvf features.

https://claude.ai/code/session_01H1GkTK5z9ppVVQDQukjBsY
…erception

SpatialIndex: replace Vec<Vec<f32>> with flat Vec<f32> buffer for cache
locality and zero per-point heap allocation; use squared Euclidean
distance in kNN/radius search (defer sqrt to final k results); fuse
cosine distance into single loop.

Clustering: add union-by-rank to union-find preventing tree
degeneration (O(α(n)) amortized); add #[inline] on hot helpers.

A* planning: add closed set (HashSet) to avoid re-expanding nodes;
reuse neighbor buffer to eliminate per-expansion Vec allocation;
pre-allocate HashMap capacity; add #[inline] on helpers.

Perception: defer sqrt in bounding_sphere (compare squared distances,
one sqrt at end); defer sqrt in scene graph edge construction (filter
on squared threshold); add #[inline] on dist_3d.

Sensor fusion: pre-allocate merged vectors from total eligible cloud
size. Anomaly detection: fuse distance + statistics into single pass
using Welford's online algorithm (eliminates one full data pass).

All 281 tests pass.

https://claude.ai/code/session_01H1GkTK5z9ppVVQDQukjBsY
Implements ADR-057 with 7 modules (2,940 lines, 54 tests):
- types: 4 new segment types (FederatedManifest 0x33, DiffPrivacyProof 0x34,
  RedactionLog 0x35, AggregateWeights 0x36)
- pii_strip: 3-stage pipeline (detect, redact, attest) with 12 regex rules
- diff_privacy: Gaussian/Laplace noise, RDP accountant, gradient clipping
- federation: ExportBuilder + ImportMerger with version-aware conflict resolution
- aggregate: FedAvg, FedProx, Byzantine-tolerant weighted averaging
- policy: FederationPolicy for selective sharing with allow/deny lists
- error: 15 typed error variants

Also updates rvf-types with 4 new segment discriminants (0x33-0x36),
workspace Cargo.toml, and root README (crate count, segment count,
federated learning code example).

Co-Authored-By: claude-flow <ruv@ruv.net>
feat: rvf-federation crate for federated transfer learning
  Built from commit c550fff

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
Clippy fixes (8 warnings → 0):
- Replace 5 manual Default impls with #[derive(Default)]
- Use .clamp() instead of .min().max() chain
- Use .is_some_and() instead of .map_or(false, ...)
- Add type alias for complex return type in scene_graph_to_adjacency

P0 correctness fixes from code review:
- Fix NaN panic: use unwrap_or(Ordering::Equal) in cognitive_core think()
- Fix integer overflow: use checked_mul in OccupancyGrid::new
- Fix potential unwrap: use map_or in domain_expansion score_avoidance

Co-Authored-By: claude-flow <ruv@ruv.net>
Add repository, homepage, keywords, categories for crates.io listing.
Pin optional dependency versions (ruvector-domain-expansion 2.0.4,
rvf-runtime 0.2, rvf-types 0.2) required for cargo publish.

Co-Authored-By: claude-flow <ruv@ruv.net>
…egration-VOZu2

Add ruvector-robotics: unified cognitive robotics platform
  Built from commit 85df6b9

  Platforms updated:
  - linux-x64-gnu
  - linux-arm64-gnu
  - darwin-x64
  - darwin-arm64
  - win32-x64-msvc

  🤖 Generated by GitHub Actions
JSON-RPC 2.0 notifications have no `id` field. The previous
JsonRpcRequest struct required `id: serde_json::Value`, causing
a parse error when MCP clients send notifications (e.g.
`notifications/initialized`). Additionally, the spec forbids
sending any response to a notification.

Changes:
- types.rs: id is now `Option<serde_json::Value>` with `#[serde(default)]`
- server.rs: handle_message returns None when id is None (notification path)
- server.rs: all call sites updated with `.unwrap_or(Value::Null)`
- tests: updated 4 existing tests, added 2 new notification tests

Fixes Claude Code CLI connection timeout during MCP handshake.
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.

3 participants