Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances IronClaw's integration with NEAR AI by introducing a companion Multi-Channel Protocol (MCP) server. This allows for seamless discovery and connection to NEAR AI's MCP endpoints, leveraging existing authentication for efficiency and security. Additionally, it refines the handling of web_search arguments to improve reliability and ensures the new MCP server is robustly integrated across all application lifecycle stages, from startup to extension management and CLI testing. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a new feature for NEAR AI companion MCP integration, allowing IronClaw to automatically derive and connect to ${nearai.base_url}/mcp and reuse existing NEAR AI authentication. The changes involve updating McpClient, McpServerConfig, and ExtensionManager to handle the NEAR AI session manager and API key for authentication. A new module nearai_auth.rs centralizes the bearer token resolution logic, which is a good refactoring for maintainability. Additionally, web_search MCP arguments are now normalized to prevent invalid inputs from breaking upstream calls, enhancing robustness. The implementation appears solid, with appropriate updates to constructors, method signatures, and test cases across the affected modules.
# Conflicts: # src/app.rs
|
@claude review |
zmanian
left a comment
There was a problem hiding this comment.
Review: NEAR AI companion MCP integration
Good feature -- auto-deriving MCP config from the existing NEAR AI LLM backend eliminates manual setup. No new dependencies, secrets handled with SecretString, no .unwrap() in production paths. CI green.
Concerning: Web search argument normalization too permissive
The final commit narrows normalization to only strip empty strings via map.retain(). This means invalid enum values for freshness (only "pd", "pw", "pm", "py" are valid) pass through unchecked. An LLM hallucinating "freshness": "invalid" would hit the upstream API raw.
Suggestion: keep the current retain-empty approach but add explicit validation for freshness values since it's a closed enum.
Concerning: Incomplete reserved server protection
CLI prevents removing and toggling the companion server, and auth_server() returns early for runtime-auth servers. But there's no protection against manual JSON config edits that could override the derived server config. Consider validating at load time that _nearai_companion_mcp entries match the derived config.
Minor: Test feature gate
test_derive_nearai_companion_mcp_server_strips_trailing_v1 is gated with #[cfg(feature = "libsql")] but the function under test has no DB dependencies. Should compile unconditionally or use #[cfg(any(feature = "libsql", feature = "postgres"))].
Minor: NEARAI_API_KEY env var not wrapped in SecretString
In nearai_auth.rs, the NEARAI_API_KEY env fallback returns a raw String rather than being wrapped in SecretString like the keychain-sourced credential. Low risk since it's only passed to the LLM provider, but inconsistent with the rest of the secret handling.
What's good
- Clean auto-derivation:
derive_nearai_companion_mcp_server()constructs MCP config from LLM config without duplicating secrets - Underscore-prefixed
_nearai_companion_mcpname signals "system-managed" is_derivedflag prevents persistence of ephemeral config- Factory error handling properly uses
McpFactoryError::MissingRuntimeAuthContext - Good test coverage for derivation, CLI protection, and header injection
There was a problem hiding this comment.
Pull request overview
Adds a derived “NEAR AI companion” MCP server integration so IronClaw can auto-discover a NearAI-backed MCP endpoint and reuse NearAI auth for MCP requests, wiring it through startup, extensions, and CLI flows.
Changes:
- Introduces
McpAuthSource::NearAi+ derived companion server config (_nearai_companion_mcp) and plumbs runtime NearAI auth context into MCP client creation. - Centralizes NearAI bearer-token resolution into
resolve_nearai_bearer_tokenand reuses it for both chat and MCP. - Updates extension/web types to surface “derived” extensions and adjusts CLI MCP commands to include derived servers while preventing user management of the reserved companion.
Reviewed changes
Copilot reviewed 15 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/module_init_integration.rs | Updates ExtensionManager::new call site for new constructor args. |
| src/tools/mcp/factory.rs | Adds runtime-auth context parameters and creates MCP clients with NearAI auth reuse. |
| src/tools/mcp/config.rs | Adds auth_source, reserved companion name, derivation helper, and insert-if-absent behavior. |
| src/tools/mcp/client.rs | Adds NearAI runtime auth header injection and web_search argument normalization. |
| src/tools/builtin/extension_tools.rs | Updates ExtensionManager::new test stub for new args. |
| src/llm/nearai_chat.rs | Switches bearer-token resolution to shared helper. |
| src/llm/nearai_auth.rs | New module factoring NearAI bearer-token resolution logic. |
| src/llm/mod.rs | Exposes nearai_auth module and re-exports resolver. |
| src/extensions/mod.rs | Adds derived flag to installed extension representation. |
| src/extensions/manager.rs | Loads derived companion MCP server, adds runtime-auth checks, and tags derived extensions. |
| src/cli/mcp.rs | Includes derived servers in list/auth/test, prevents reserved-name management, filters derived servers from persistence. |
| src/channels/web/types.rs | Adds derived to web API extension payload type. |
| src/channels/web/server.rs | Wires derived through extensions list handler/tests and updates constructor args. |
| src/channels/web/handlers/extensions.rs | Wires derived through extensions list handler. |
| src/app.rs | Derives companion MCP server at startup and passes NearAI auth context into MCP activation flows. |
| channels-src/whatsapp/Cargo.lock | Bumps whatsapp-channel lockfile version entry. |
| .gitignore | Adds Python artifact patterns and JetBrains .idea ignore. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| fn resolve_llm_from_env() -> Result<LlmConfig, crate::error::ConfigError> { | ||
| LlmConfig::resolve(&Settings::default()) |
| /// | ||
| /// This is used for companion MCP servers that should reuse an existing | ||
| /// provider identity instead of running their own MCP OAuth flow. | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] |
| // model frequently emits as empty strings. Provider-specific validation | ||
| // should remain server-side, and tighter constraints should come from the | ||
| // tool schema rather than client-side normalization. | ||
| map.retain(|_, value| !value.as_str().is_some_and(|s| s.trim().is_empty())); |
| if let Ok(key) = std::env::var("NEARAI_API_KEY") | ||
| && !key.is_empty() | ||
| { | ||
| return Ok(key); |
Summary
${nearai.base_url}/mcpwhen the active backend isnearai.web_searchMCP arguments before sending them upstream so invalid empty-string and malformed locale/freshness values do not break provider-backed search calls.expect(...)panic in MCP client creation, preserving API-key-based auth reuse in the extension manager path, and preventing reserved companion-name collisions.Change Type
Linked Issue
Closes #548
Validation
cargo fmtcargo clippy --all --benches --tests --examples --all-featurescargo check -qpassed; no dedicated automated test subset was run separatelycloud-apiandchat-apiMCP endpoints; confirmed IronClaw auto-derived_nearai_companion_mcp,ironclaw mcp test _nearai_companion_mcpsucceeded without DB-backed config for the runtime-auth path, and the agent successfully executed provider-backed web search end-to-endSecurity Impact
This change affects MCP auth and network calls. IronClaw now reuses the active NEAR AI provider auth for a derived companion MCP endpoint under the same base URL. The runtime auth bridge is scoped to the built-in
NearAiauth source rather than arbitrary MCP servers, and the reserved companion server name cannot be user-defined or persisted accidentally.Database Impact
None.
Blast Radius
Touches LLM auth resolution, MCP client creation, MCP config derivation, extension manager MCP loading, MCP CLI testing and persistence behavior, and provider-backed tool execution. Regressions could affect NearAI-backed MCP discovery, MCP auth header injection, extension reload/activation flows, CLI MCP management behavior, or provider-backed web search execution.
Rollback Plan
Revert the companion MCP integration commits to restore the previous behavior:
web_searchMCP argument normalizationReview track: C