feat(mcp): 增强新增服务参数填写提示

This commit is contained in:
Syngnat
2026-06-11 12:37:02 +08:00
parent 4265d7cfa9
commit 19989e4c26
5 changed files with 294 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
import React from 'react';
import type { OverlayWorkbenchTheme } from '../../utils/overlayWorkbenchTheme';
import { buildMCPArgumentHintProfile } from '../../utils/mcpArgumentHints';
import { buildMCPHintStyle, mcpLabelStyle } from './AIMCPHelpBlock';
interface AIMCPArgumentHintsProps {
command: string;
args?: string[];
cardBorder: string;
darkMode: boolean;
overlayTheme: OverlayWorkbenchTheme;
}
const AIMCPArgumentHints: React.FC<AIMCPArgumentHintsProps> = ({
command,
args,
cardBorder,
darkMode,
overlayTheme,
}) => {
const profile = buildMCPArgumentHintProfile(command, args);
if (!profile) {
return null;
}
return (
<div
style={{
padding: '10px 12px',
borderRadius: 10,
border: `1px dashed ${cardBorder}`,
background: darkMode ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.7)',
display: 'flex',
flexDirection: 'column',
gap: 8,
}}
>
<div style={{ ...mcpLabelStyle, color: overlayTheme.titleText }}>
{profile.commandName}
</div>
<div style={{ fontSize: 12, fontWeight: 700, color: overlayTheme.titleText }}>
{profile.title}
</div>
<div style={buildMCPHintStyle(overlayTheme.mutedText)}>{profile.summary}</div>
<div style={buildMCPHintStyle(overlayTheme.mutedText)}>{profile.orderHint}</div>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
{profile.steps.map((step) => (
<span
key={step.key}
style={{
padding: '4px 9px',
borderRadius: 999,
fontSize: 12,
border: `1px solid ${cardBorder}`,
color: step.satisfied ? '#16a34a' : (step.required ? '#b45309' : overlayTheme.mutedText),
background: step.satisfied
? (darkMode ? 'rgba(34,197,94,0.14)' : 'rgba(34,197,94,0.10)')
: (darkMode ? 'rgba(255,255,255,0.04)' : 'rgba(255,255,255,0.82)'),
}}
title={step.detail}
>
{step.label}: <code style={{ fontFamily: 'var(--gn-font-mono)' }}>{step.example}</code>
{step.required ? ' *' : ''}
</span>
))}
</div>
{profile.nextActions.length > 0 ? (
<div style={buildMCPHintStyle('#b45309')}>
{profile.nextActions.join('')}
</div>
) : (
<div style={buildMCPHintStyle(overlayTheme.mutedText)}>
README
</div>
)}
</div>
);
};
export default AIMCPArgumentHints;

View File

@@ -53,6 +53,10 @@ describe('AIMCPServerCard', () => {
expect(markup).toContain('npx -y package --stdio');
expect(markup).toContain('-y、@modelcontextprotocol/server-filesystem、--stdio、server.js');
expect(markup).toContain('每个参数单独录入一个标签');
expect(markup).toContain('当前命令 node 的参数提示');
expect(markup).toContain('Node 脚本参数顺序建议');
expect(markup).toContain('推荐顺序:脚本路径 -&gt; --stdio -&gt; 服务自己的业务参数');
expect(markup).toContain('必填参数看起来已经齐了');
expect(markup).toContain('每行一个 KEY=VALUE');
expect(markup).toContain('没有等号或 key 含空格的行不会保存');
expect(markup).toContain('不要把 npx -y package --stdio 或 node server.js --stdio 整串都塞进这里');

View File

@@ -7,6 +7,7 @@ import type { AIMCPServerConfig, AIMCPToolDescriptor } from '../../types';
import type { ParsedMCPEnvDraft } from '../../utils/mcpEnvDraft';
import type { MCPServerDraftValidation } from '../../utils/mcpServerValidation';
import AIMCPHelpBlock, { buildMCPHintStyle, mcpLabelStyle } from './AIMCPHelpBlock';
import AIMCPArgumentHints from './AIMCPArgumentHints';
import AIMCPServerValidationPanel from './AIMCPServerValidationPanel';
import AIMCPToolSchemaSummary from './AIMCPToolSchemaSummary';
@@ -129,6 +130,13 @@ const AIMCPServerFormPanel: React.FC<AIMCPServerFormPanelProps> = ({
placeholder="命令参数,回车录入,例如:-y、包名、--stdio"
style={{ width: '100%' }}
/>
<AIMCPArgumentHints
command={server.command}
args={server.args}
cardBorder={cardBorder}
darkMode={darkMode}
overlayTheme={overlayTheme}
/>
</AIMCPHelpBlock>
{launchPreview && (