Skip to content

Commit 522b047

Browse files
authored
feat(install): add MCP auto-configuration, verification, and E2E testing (#3)
- Add mcp-config.ts module with: - Auto-configure MCP for Augment, Claude, Cursor, Gemini IDEs - MCP setup verification (Qdrant, Ollama, MCP server) - End-to-end memory system testing - Display functions for config status and JSON - Update install command Phase 3: - Automatically write MCP config to IDE settings files - Verify dependencies are running and accessible - Run E2E test to confirm system is ready - Show clear success/failure status with troubleshooting tips - Add new CLI options: - --no-configure-mcp: skip MCP auto-configuration - --skip-verify: skip post-install verification - Add mcp-config.test.ts with 9 test cases Closes the gap for: - MCP 自动配置 (was: manual JSON copy) - MCP 验证 (was: no verification) - 端到端测试 (was: no post-install validation)
1 parent 0aba511 commit 522b047

4 files changed

Lines changed: 740 additions & 58 deletions

File tree

cli/src/commands/install.ts

Lines changed: 103 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ import {
2222
getComposeFilePath,
2323
getComposeDir,
2424
} from './deps.js';
25+
import {
26+
configureMcpForIde,
27+
verifyMcpSetup,
28+
runE2EMemoryTest,
29+
displayVerificationResult,
30+
displayE2ETestResult,
31+
displayMcpConfigJson,
32+
IDE_MCP_CONFIGS,
33+
type McpConfigResult,
34+
} from '../lib/mcp-config.js';
2535

2636
// ============================================================================
2737
// Types
@@ -34,6 +44,9 @@ interface InstallOptions {
3444
showMcp?: boolean;
3545
force?: boolean; // Fix Issue #11: Add force option
3646
compose?: boolean; // Use Docker Compose mode
47+
configureMcp?: boolean; // Auto-configure MCP for IDEs
48+
verify?: boolean; // Verify MCP setup after install
49+
skipVerify?: boolean; // Skip verification
3750
}
3851

3952
interface IdeConfig {
@@ -369,44 +382,6 @@ function processTemplate(content: string, projectName: string): string {
369382
.replace(/\{\{CREATED_AT\}\}/g, now);
370383
}
371384

372-
// Fix Issue #7: Improved MCP configuration guidance
373-
function showMcpConfig(ide: string): void {
374-
console.log(chalk.bold('\n📋 MCP 配置 (复制到 IDE 配置文件):'));
375-
376-
// Fix Issue #7: Clarify that OPENAI_API_KEY is optional when using Ollama
377-
console.log(chalk.gray('\n💡 使用本地 Ollama + BGE-M3,无需 OpenAI API Key\n'));
378-
379-
const mcpConfig = {
380-
openmemory: {
381-
command: 'npx',
382-
args: ['-y', 'openmemory-mcp'],
383-
env: {
384-
// Fix Issue #7: Remove misleading OPENAI_API_KEY
385-
MEM0_EMBEDDING_MODEL: 'bge-m3',
386-
MEM0_EMBEDDING_PROVIDER: 'ollama',
387-
OLLAMA_HOST: 'http://localhost:11434',
388-
QDRANT_HOST: 'localhost',
389-
QDRANT_PORT: '6333',
390-
},
391-
},
392-
};
393-
394-
console.log(chalk.cyan('\n```json'));
395-
console.log(JSON.stringify(mcpConfig, null, 2));
396-
console.log(chalk.cyan('```\n'));
397-
398-
const configPaths: Record<string, string> = {
399-
augment: '~/.augment/settings.json (mcpServers 字段)',
400-
claude: '~/.config/claude/mcp.json',
401-
cursor: '~/.cursor/mcp.json',
402-
gemini: '~/.config/gemini/mcp.json',
403-
common: '参考各 IDE 的 MCP 配置文档',
404-
};
405-
406-
console.log(chalk.gray(`配置文件位置: ${configPaths[ide] || configPaths.common}`));
407-
console.log(chalk.gray('\n📖 详细配置说明: https://github.com/mem0ai/mem0/tree/main/openmemory\n'));
408-
}
409-
410385
// ============================================================================
411386
// Phase 1: System Dependencies (with Docker Compose support)
412387
// ============================================================================
@@ -820,27 +795,96 @@ async function phase2_initProject(options: InstallOptions): Promise<string> {
820795
}
821796

822797
// ============================================================================
823-
// Phase 3: Completion
798+
// Phase 3: MCP Configuration, Verification, and Completion
824799
// ============================================================================
825800

826-
function phase3_showCompletion(ide: string, showMcp: boolean): void {
801+
async function phase3_configureMcp(ide: string, options: InstallOptions): Promise<boolean> {
802+
console.log(chalk.bold.cyan('\n━━━ Phase 3: MCP 配置与验证 ━━━\n'));
803+
804+
// Step 1: Auto-configure MCP for the selected IDE
805+
if (options.configureMcp !== false) {
806+
const spinner = ora(`配置 ${IDE_MCP_CONFIGS[ide]?.name || ide} MCP...`).start();
807+
808+
const result = configureMcpForIde(ide, options.force);
809+
810+
if (result.success) {
811+
if (result.created) {
812+
spinner.succeed(`MCP 配置已创建: ${result.path}`);
813+
} else if (result.updated) {
814+
spinner.succeed(`MCP 配置已更新: ${result.path}`);
815+
} else {
816+
spinner.succeed(`MCP 已配置 (无需更改): ${result.path}`);
817+
}
818+
} else {
819+
spinner.fail(`MCP 配置失败: ${result.error}`);
820+
console.log(chalk.yellow('\n手动配置方法:'));
821+
displayMcpConfigJson();
822+
return false;
823+
}
824+
}
825+
826+
// Step 2: Verify MCP setup (unless skipped)
827+
if (!options.skipVerify) {
828+
const spinner = ora('验证 MCP 设置...').start();
829+
830+
const verifyResult = await verifyMcpSetup();
831+
832+
if (verifyResult.success) {
833+
spinner.succeed('MCP 验证通过');
834+
} else {
835+
spinner.warn('MCP 验证未完全通过');
836+
displayVerificationResult(verifyResult);
837+
838+
// Show troubleshooting tips
839+
if (verifyResult.details) {
840+
const { qdrantConnected, ollamaConnected } = verifyResult.details;
841+
if (!qdrantConnected) {
842+
console.log(chalk.yellow(' 💡 Qdrant 未连接,请确保 Docker 已启动并运行:'));
843+
console.log(chalk.gray(' docker compose up -d'));
844+
}
845+
if (!ollamaConnected) {
846+
console.log(chalk.yellow(' 💡 Ollama 未连接或缺少 embedding 模型:'));
847+
console.log(chalk.gray(' ollama pull bge-m3'));
848+
}
849+
}
850+
return false;
851+
}
852+
853+
// Step 3: Run E2E test
854+
const e2eSpinner = ora('运行端到端测试...').start();
855+
const e2eResult = await runE2EMemoryTest();
856+
857+
if (e2eResult.success) {
858+
e2eSpinner.succeed('端到端测试通过');
859+
} else {
860+
e2eSpinner.warn('端到端测试未通过');
861+
displayE2ETestResult(e2eResult);
862+
}
863+
}
864+
865+
return true;
866+
}
867+
868+
function phase3_showCompletion(ide: string, mcpConfigured: boolean): void {
827869
console.log(chalk.bold.cyan('\n━━━ 安装完成 ━━━\n'));
828-
870+
829871
console.log(chalk.green.bold('🎉 OpenMemory Plus 已成功安装!\n'));
830-
872+
873+
if (mcpConfigured) {
874+
console.log(chalk.green('✓ MCP 已自动配置到 ' + (IDE_MCP_CONFIGS[ide]?.name || ide)));
875+
console.log('');
876+
}
877+
831878
console.log(chalk.bold('💡 下一步:'));
832-
console.log(chalk.gray(' 1. IDE 中打开项目'));
879+
console.log(chalk.gray(' 1. 重启 IDE 以加载 MCP 配置'));
833880
console.log(chalk.gray(' 2. 使用 ') + chalk.cyan('/memory') + chalk.gray(' 打开记忆管理菜单'));
834881
console.log(chalk.gray(' 3. 选择操作或用自然语言描述需求'));
835882
console.log('');
836-
837-
if (showMcp) {
838-
showMcpConfig(ide);
839-
} else {
883+
884+
if (!mcpConfigured) {
840885
console.log(chalk.gray('📋 查看 MCP 配置: ') + chalk.cyan('npx openmemory-plus install --show-mcp'));
886+
console.log('');
841887
}
842-
843-
console.log('');
844888
}
845889

846890
// ============================================================================
@@ -850,20 +894,22 @@ function phase3_showCompletion(ide: string, showMcp: boolean): void {
850894
export async function installCommand(options: InstallOptions): Promise<void> {
851895
// Show banner
852896
console.log(chalk.cyan(BANNER));
853-
897+
854898
// If only showing MCP config
855899
if (options.showMcp) {
856-
const ide = options.ide || 'augment';
857-
showMcpConfig(ide);
900+
displayMcpConfigJson();
858901
return;
859902
}
860-
903+
861904
// Phase 1: Check and install dependencies
862905
await phase1_checkAndInstallDeps(options);
863-
906+
864907
// Phase 2: Initialize project
865908
const ide = await phase2_initProject(options);
866-
867-
// Phase 3: Show completion
868-
phase3_showCompletion(ide, false);
909+
910+
// Phase 3: Configure MCP, verify, and test
911+
const mcpSuccess = await phase3_configureMcp(ide, options);
912+
913+
// Show completion
914+
phase3_showCompletion(ide, mcpSuccess);
869915
}

cli/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ program
4848
.option('-y, --yes', '跳过确认提示')
4949
.option('-i, --ide <type>', 'IDE 类型: augment, claude, cursor, gemini, common')
5050
.option('--skip-deps', '跳过依赖安装,仅配置项目')
51-
.option('--show-mcp', '显示 MCP 配置')
51+
.option('--show-mcp', '显示 MCP 配置 JSON')
5252
.option('-f, --force', '强制覆盖已存在的配置文件')
5353
.option('--compose', '使用 Docker Compose 一键部署依赖')
54+
.option('--no-configure-mcp', '跳过 MCP 自动配置')
55+
.option('--skip-verify', '跳过安装后验证')
5456
.action(installCommand);
5557

5658
// Secondary commands (for advanced users)

0 commit comments

Comments
 (0)