Conversation
WalkthroughThe changes introduce a new composable for programmatically managing custom MCP servers, integrate it into the TinyRobotChat component with a new public API, add a toolChoice configuration option, bump package versions, and temporarily disable a UI action. These modifications enable users to add MCP servers dynamically in two modes: code-based batch import and form-based single server creation. Changes
Sequence Diagram(s)sequenceDiagram
participant Component as TinyRobotChat Component
participant Composable as useCustomMcpServer
participant Agent as AgentModelProvider
participant PluginStore as installedPlugins (Ref)
participant UI as UI Feedback
Component->>Composable: handleCustomAdd(type, data)
alt type === 'code'
Composable->>Composable: Parse JSON string
Composable->>Composable: Extract MCP servers
loop Each MCP Server
Composable->>Agent: Add MCP server
Composable->>PluginStore: Create & push PluginInfo
Composable->>UI: Update success/failure count
end
else type === 'form'
Composable->>Composable: Validate form data
Composable->>Agent: Create & insert MCP server
Composable->>Composable: Generate pluginId + tools
Composable->>PluginStore: Push PluginInfo
Composable->>UI: Show success toast
end
Composable->>Agent: Close all connections
Composable->>Component: Return (Promise resolves)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
Fix all issues with AI Agents 🤖
In @packages/next-remoter/src/composable/useCustomMcpServer.ts:
- Around line 203-217: The destructured variable _headers from data is unused;
either remove it from the destructuring or wire it into the MCP server form
handling (e.g., propagate to the form state or include in the payload sent when
saving the server). Update the destructuring in useCustomMcpServer (remove
"headers: _headers") if you don't intend to support headers, or if you do,
ensure the headers value from data is validated and assigned to the form/model
fields and included in save/update logic where name, url, description,
thumbnail, and type (mcpType) are handled.
- Around line 229-233: The code unsafely casts mcpType into
'streamableHttp'|'sse' when building the mcpServer, which can let invalid values
(e.g. 'extension') slip through and miss required fields like sessionId; replace
the cast with explicit runtime validation of mcpType before constructing
mcpServer: check if mcpType === 'streamableHttp' || mcpType === 'sse' and build
McpServerConfig with those fields, otherwise handle other known kinds (e.g.
'extension') by including the required sessionId field or reject/throw/log an
error for unsupported values; reference mcpType, mcpServer and McpServerConfig
and ensure any branch produces a fully populated config.
🧹 Nitpick comments (2)
packages/next-remoter/src/composable/useCustomMcpServer.ts (2)
37-72: Consider adding URL validation for robustness.The
normalizeMcpConfigfunction handles type normalization well, but invalid URLs could pass through unchecked. Consider adding basic URL format validation to fail fast on misconfigured servers.🔎 Suggested validation
const normalizeMcpConfig = (config: any): McpServerConfig | null => { if (!config || typeof config !== 'object' || !config.url) { return null } + + // Basic URL validation + try { + new URL(config.url) + } catch { + return null + } const { type, url, sessionId } = config
122-123: Consider defining proper type extension instead of@ts-ignore.Using
@ts-ignoreto addoriginMcpConfigtoPluginInfosuggests a type definition gap. If this is a common pattern, consider extending thePluginInfotype or creating a local interface.🔎 Type extension example
// At the top of the file or in a shared types file interface ExtendedPluginInfo extends PluginInfo { originMcpConfig?: McpServerConfig }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/next-remoter/package.jsonpackages/next-remoter/src/components/tiny-robot-chat.vuepackages/next-remoter/src/composable/CustomAgentModelProvider.tspackages/next-remoter/src/composable/useCustomMcpServer.tspackages/next-sdk/package.jsonpackages/next-wxt/entrypoints/sidepanel/App.vue
🧰 Additional context used
🧬 Code graph analysis (1)
packages/next-remoter/src/composable/useCustomMcpServer.ts (3)
packages/next-sdk/agent/type.ts (1)
McpServerConfig(37-41)packages/next-wxt/public/vendor/mcp-server.js (1)
sessionId(34-34)packages/next-remoter/src/components/default-plugin-svg.ts (1)
defaultPluginSrc(19-19)
🔇 Additional comments (10)
packages/next-remoter/package.json (1)
3-3: LGTM!Version bump to
0.0.10-beta.5is appropriate for the newuseCustomMcpServercomposable feature.packages/next-sdk/package.json (1)
3-3: LGTM!Version bump aligns with the coordinated release of new features in the
next-remoterpackage.packages/next-wxt/entrypoints/sidepanel/App.vue (1)
224-230: Temporary UI disabling acknowledged.The header-actions slot containing the custom add button is commented out pending screen recording feature completion. The custom add functionality is still available through
TrMcpServerPickerwith:show-custom-add-button="true"intiny-robot-chat.vue.packages/next-remoter/src/composable/CustomAgentModelProvider.ts (1)
488-491: LGTM!Explicitly setting
toolChoice: 'auto'with clear documentation of available options ('none','required') improves code clarity and makes the tool invocation behavior configurable and predictable.packages/next-remoter/src/composable/useCustomMcpServer.ts (2)
9-31: LGTM!The
parseMcpConfigFromJsonfunction has good error handling, validates the expected JSON structure, and provides clear error messages.
145-250: Functions are globally available—no imports needed.
showToastandshowLoadingToastare auto-imported globally fromvant/esvia the unplugin-auto-import configuration (seepackages/next-remoter/auto-imports.d.ts). These can be used without explicit imports in this file.Likely an incorrect or invalid review comment.
packages/next-remoter/src/components/tiny-robot-chat.vue (4)
120-133: LGTM!The
TrMcpServerPickeris correctly configured with:show-custom-add-button="true"and the@plugin-createevent is properly wired tohandleCustomAddfrom the new composable.
169-169: LGTM!Import statement correctly added for the new
useCustomMcpServercomposable.
738-739: LGTM!The composable is correctly initialized with all required dependencies:
agent,installedPlugins, anddefaultPluginSrc.
772-774: Good addition to the public API surface.Exposing
addMessageviadefineExposeenables external consumers to programmatically add messages, which is useful for integration scenarios. The existinghandleClientDisconnectedexposure is maintained.
| const { | ||
| description, | ||
| headers: _headers, | ||
| name, | ||
| thumbnail, | ||
| type: mcpType, | ||
| url | ||
| } = data as { | ||
| description?: string | ||
| headers?: string | Record<string, string> | ||
| name?: string | ||
| thumbnail?: string | null | ||
| type?: string | ||
| url?: string | ||
| } |
There was a problem hiding this comment.
Unused variable _headers extracted but never used.
The headers field is destructured from data but is not utilized in the form processing logic. Either remove it or implement header support for MCP server configuration.
🔎 Proposed fix
// 解构数据对象,headers 可能是字符串或对象
const {
description,
- headers: _headers,
name,
thumbnail,
type: mcpType,
url
} = data as {
description?: string
- headers?: string | Record<string, string>
name?: string
thumbnail?: string | null
type?: string
url?: string
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const { | |
| description, | |
| headers: _headers, | |
| name, | |
| thumbnail, | |
| type: mcpType, | |
| url | |
| } = data as { | |
| description?: string | |
| headers?: string | Record<string, string> | |
| name?: string | |
| thumbnail?: string | null | |
| type?: string | |
| url?: string | |
| } | |
| const { | |
| description, | |
| name, | |
| thumbnail, | |
| type: mcpType, | |
| url | |
| } = data as { | |
| description?: string | |
| name?: string | |
| thumbnail?: string | null | |
| type?: string | |
| url?: string | |
| } |
🤖 Prompt for AI Agents
In @packages/next-remoter/src/composable/useCustomMcpServer.ts around lines
203-217, The destructured variable _headers from data is unused; either remove
it from the destructuring or wire it into the MCP server form handling (e.g.,
propagate to the form state or include in the payload sent when saving the
server). Update the destructuring in useCustomMcpServer (remove "headers:
_headers") if you don't intend to support headers, or if you do, ensure the
headers value from data is validated and assigned to the form/model fields and
included in save/update logic where name, url, description, thumbnail, and type
(mcpType) are handled.
| const mcpServer: McpServerConfig = { | ||
| type: mcpType as 'streamableHttp' | 'sse', | ||
| url, | ||
| useAISdkClient: true | ||
| } as McpServerConfig |
There was a problem hiding this comment.
Type assertion could allow invalid mcpType values.
The cast mcpType as 'streamableHttp' | 'sse' doesn't validate the input. If mcpType is an unexpected value (e.g., 'extension'), it will be assigned to the config object without the required sessionId field.
🔎 Proposed validation
+ // Validate mcpType for form mode (only streamableHttp and sse are supported)
+ if (mcpType !== 'streamableHttp' && mcpType !== 'sse') {
+ showToast('添加工具失败:不支持的连接类型,仅支持 streamableHttp 或 sse')
+ return
+ }
+
const mcpServer: McpServerConfig = {
- type: mcpType as 'streamableHttp' | 'sse',
+ type: mcpType,
url,
useAISdkClient: true
- } as McpServerConfig
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const mcpServer: McpServerConfig = { | |
| type: mcpType as 'streamableHttp' | 'sse', | |
| url, | |
| useAISdkClient: true | |
| } as McpServerConfig | |
| // Validate mcpType for form mode (only streamableHttp and sse are supported) | |
| if (mcpType !== 'streamableHttp' && mcpType !== 'sse') { | |
| showToast('添加工具失败:不支持的连接类型,仅支持 streamableHttp 或 sse') | |
| return | |
| } | |
| const mcpServer: McpServerConfig = { | |
| type: mcpType, | |
| url, | |
| useAISdkClient: true | |
| } |
🤖 Prompt for AI Agents
In @packages/next-remoter/src/composable/useCustomMcpServer.ts around lines
229-233, The code unsafely casts mcpType into 'streamableHttp'|'sse' when
building the mcpServer, which can let invalid values (e.g. 'extension') slip
through and miss required fields like sessionId; replace the cast with explicit
runtime validation of mcpType before constructing mcpServer: check if mcpType
=== 'streamableHttp' || mcpType === 'sse' and build McpServerConfig with those
fields, otherwise handle other known kinds (e.g. 'extension') by including the
required sessionId field or reject/throw/log an error for unsupported values;
reference mcpType, mcpServer and McpServerConfig and ensure any branch produces
a fully populated config.
feat: 添加自定义插件工具的能力同时支持表单和json数据格式
Summary by CodeRabbit
New Features
addMessagemethod for external message management.Chores
Changes
✏️ Tip: You can customize this high-level summary in your review settings.