@indiccoder/mentis-cli 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/.mentis/session.json +15 -0
  3. package/.mentis/sessions/1769189035730.json +23 -0
  4. package/.mentis/sessions/1769189569160.json +23 -0
  5. package/.mentis/sessions/1769767538672.json +23 -0
  6. package/.mentis/sessions/1769767785155.json +23 -0
  7. package/.mentis/sessions/1769768745802.json +23 -0
  8. package/.mentis/sessions/1769769600884.json +31 -0
  9. package/.mentis/sessions/1769770030160.json +31 -0
  10. package/.mentis/sessions/1769770606004.json +78 -0
  11. package/.mentis/sessions/1769771084515.json +141 -0
  12. package/.mentis/sessions/1769881926630.json +57 -0
  13. package/ARCHITECTURE.md +267 -0
  14. package/CONTRIBUTING.md +209 -0
  15. package/README.md +17 -0
  16. package/dist/checkpoint/CheckpointManager.js +92 -0
  17. package/dist/commands/Command.js +15 -1
  18. package/dist/commands/CommandManager.js +30 -5
  19. package/dist/commands/__tests__/CommandManager.test.js +70 -0
  20. package/dist/debug_google.js +61 -0
  21. package/dist/debug_lite.js +49 -0
  22. package/dist/debug_lite_headers.js +57 -0
  23. package/dist/debug_search.js +16 -0
  24. package/dist/index.js +33 -0
  25. package/dist/mcp/JsonRpcClient.js +16 -0
  26. package/dist/mcp/McpConfig.js +132 -0
  27. package/dist/mcp/McpManager.js +189 -0
  28. package/dist/repl/PersistentShell.js +20 -1
  29. package/dist/repl/ReplManager.js +410 -138
  30. package/dist/skills/Skill.js +17 -2
  31. package/dist/skills/SkillsManager.js +28 -3
  32. package/dist/skills/__tests__/SkillsManager.test.js +62 -0
  33. package/dist/tools/AskQuestionTool.js +172 -0
  34. package/dist/tools/EditFileTool.js +141 -0
  35. package/dist/tools/FileTools.js +7 -1
  36. package/dist/tools/PlanModeTool.js +53 -0
  37. package/dist/tools/WebSearchTool.js +190 -27
  38. package/dist/ui/DiffViewer.js +110 -0
  39. package/dist/ui/InputBox.js +16 -2
  40. package/dist/ui/MultiFileSelector.js +123 -0
  41. package/dist/ui/PlanModeUI.js +105 -0
  42. package/dist/ui/ToolExecutor.js +154 -0
  43. package/dist/ui/UIManager.js +12 -2
  44. package/dist/utils/__mocks__/chalk.js +20 -0
  45. package/dist/utils/__tests__/ContextVisualizer.test.js +95 -0
  46. package/docs/MCP_INTEGRATION.md +290 -0
  47. package/google_dump.html +18 -0
  48. package/lite_dump.html +176 -0
  49. package/lite_headers_dump.html +176 -0
  50. package/package.json +34 -2
  51. package/scripts/test_exa_mcp.ts +90 -0
  52. package/src/checkpoint/CheckpointManager.ts +102 -0
  53. package/src/commands/Command.ts +64 -13
  54. package/src/commands/CommandManager.ts +26 -5
  55. package/src/commands/__tests__/CommandManager.test.ts +83 -0
  56. package/src/debug_google.ts +30 -0
  57. package/src/debug_lite.ts +18 -0
  58. package/src/debug_lite_headers.ts +25 -0
  59. package/src/debug_search.ts +18 -0
  60. package/src/index.ts +45 -1
  61. package/src/mcp/JsonRpcClient.ts +19 -0
  62. package/src/mcp/McpConfig.ts +153 -0
  63. package/src/mcp/McpManager.ts +224 -0
  64. package/src/repl/PersistentShell.ts +24 -1
  65. package/src/repl/ReplManager.ts +1521 -1204
  66. package/src/skills/Skill.ts +91 -11
  67. package/src/skills/SkillsManager.ts +25 -3
  68. package/src/skills/__tests__/SkillsManager.test.ts +73 -0
  69. package/src/tools/AskQuestionTool.ts +197 -0
  70. package/src/tools/EditFileTool.ts +172 -0
  71. package/src/tools/FileTools.ts +3 -0
  72. package/src/tools/PlanModeTool.ts +50 -0
  73. package/src/tools/WebSearchTool.ts +235 -63
  74. package/src/ui/DiffViewer.ts +117 -0
  75. package/src/ui/InputBox.ts +17 -2
  76. package/src/ui/MultiFileSelector.ts +135 -0
  77. package/src/ui/PlanModeUI.ts +121 -0
  78. package/src/ui/ToolExecutor.ts +182 -0
  79. package/src/ui/UIManager.ts +15 -2
  80. package/src/utils/__mocks__/chalk.ts +19 -0
  81. package/src/utils/__tests__/ContextVisualizer.test.ts +118 -0
  82. package/console.log(tick) +0 -0
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ToolExecutor = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ /**
10
+ * Visual feedback for tool execution
11
+ * Shows colored icons, spinners, and grouped display
12
+ */
13
+ class ToolExecutor {
14
+ /**
15
+ * Get colored text for a tool name
16
+ */
17
+ static colorToolName(toolName, color) {
18
+ switch (color) {
19
+ case 'blue': return chalk_1.default.blue(toolName);
20
+ case 'yellow': return chalk_1.default.yellow(toolName);
21
+ case 'cyan': return chalk_1.default.cyan(toolName);
22
+ case 'magenta': return chalk_1.default.magenta(toolName);
23
+ case 'green': return chalk_1.default.green(toolName);
24
+ case 'red': return chalk_1.default.red(toolName);
25
+ case 'gray': return chalk_1.default.gray(toolName);
26
+ default: return toolName;
27
+ }
28
+ }
29
+ /**
30
+ * Start a tool execution with visual feedback
31
+ */
32
+ static startExecution(toolName, args) {
33
+ const execution = {
34
+ toolName,
35
+ args,
36
+ status: 'running'
37
+ };
38
+ this.executions.push(execution);
39
+ // Get icon and color for tool type
40
+ const { icon, color } = this.getToolStyle(toolName);
41
+ // Format args for display (truncate long values)
42
+ const argsDisplay = this.formatArgs(args);
43
+ // Start spinner
44
+ const spinner = (0, ora_1.default)({
45
+ text: `${icon} ${this.colorToolName(toolName, color)} ${argsDisplay}`,
46
+ color: color
47
+ });
48
+ spinner.start();
49
+ this.spinners.set(toolName, spinner);
50
+ }
51
+ /**
52
+ * Complete a tool execution successfully
53
+ */
54
+ static completeExecution(toolName, result) {
55
+ const execution = this.executions.find(e => e.toolName === toolName);
56
+ if (execution) {
57
+ execution.status = 'completed';
58
+ execution.result = result;
59
+ }
60
+ const spinner = this.spinners.get(toolName);
61
+ if (spinner) {
62
+ const { icon } = this.getToolStyle(toolName);
63
+ spinner.succeed(`${icon} ${chalk_1.default.green(toolName)} completed`);
64
+ this.spinners.delete(toolName);
65
+ }
66
+ }
67
+ /**
68
+ * Mark a tool execution as failed
69
+ */
70
+ static failExecution(toolName, error) {
71
+ const execution = this.executions.find(e => e.toolName === toolName);
72
+ if (execution) {
73
+ execution.status = 'failed';
74
+ execution.error = error;
75
+ }
76
+ const spinner = this.spinners.get(toolName);
77
+ if (spinner) {
78
+ const { icon } = this.getToolStyle(toolName);
79
+ spinner.fail(`${icon} ${chalk_1.default.red(toolName)} failed: ${error}`);
80
+ this.spinners.delete(toolName);
81
+ }
82
+ }
83
+ /**
84
+ * Show grouped summary of all tool executions
85
+ */
86
+ static showSummary() {
87
+ if (this.executions.length === 0) {
88
+ return;
89
+ }
90
+ console.log('');
91
+ console.log(chalk_1.default.gray('─'.repeat(60)));
92
+ console.log(chalk_1.default.cyan('🔧 Tool Executions'));
93
+ console.log(chalk_1.default.gray('─'.repeat(60)));
94
+ for (const execution of this.executions) {
95
+ const { icon, color } = this.getToolStyle(execution.toolName);
96
+ const statusIcon = execution.status === 'completed' ? '✓' : execution.status === 'failed' ? '✗' : '…';
97
+ console.log(`${icon} ${this.colorToolName(execution.toolName, color)} ${chalk_1.default.dim(statusIcon)}`);
98
+ }
99
+ console.log(chalk_1.default.gray('─'.repeat(60)));
100
+ console.log('');
101
+ // Reset for next batch
102
+ this.executions = [];
103
+ }
104
+ /**
105
+ * Get visual style for a tool type
106
+ */
107
+ static getToolStyle(toolName) {
108
+ const styles = {
109
+ 'read_file': { icon: '📖', color: 'blue' },
110
+ 'write_file': { icon: '📄', color: 'yellow' },
111
+ 'edit_file': { icon: '✏️', color: 'yellow' },
112
+ 'list_dir': { icon: '📁', color: 'cyan' },
113
+ 'search_files': { icon: '🔍', color: 'magenta' },
114
+ 'search_web': { icon: '🌐', color: 'blue' },
115
+ 'run_command': { icon: '💻', color: 'green' },
116
+ 'git_commit': { icon: '📝', color: 'green' }
117
+ };
118
+ return styles[toolName] || { icon: '🔧', color: 'gray' };
119
+ }
120
+ /**
121
+ * Format arguments for display
122
+ */
123
+ static formatArgs(args) {
124
+ const parts = [];
125
+ for (const [key, value] of Object.entries(args)) {
126
+ const strValue = String(value);
127
+ // Truncate long values
128
+ const display = strValue.length > 30 ? strValue.slice(0, 30) + '...' : strValue;
129
+ parts.push(`${key}=${chalk_1.default.dim(display)}`);
130
+ }
131
+ return parts.length > 0 ? chalk_1.default.dim(`(${parts.join(', ')})`) : '';
132
+ }
133
+ /**
134
+ * Show a simple inline tool usage message
135
+ */
136
+ static showInline(toolName, args) {
137
+ const { icon, color } = this.getToolStyle(toolName);
138
+ const argsDisplay = this.formatArgs(args);
139
+ console.log(chalk_1.default.dim(` ${icon} ${this.colorToolName(toolName, color)} ${argsDisplay}`));
140
+ }
141
+ /**
142
+ * Clear all pending executions
143
+ */
144
+ static clear() {
145
+ for (const spinner of this.spinners.values()) {
146
+ spinner.stop();
147
+ }
148
+ this.spinners.clear();
149
+ this.executions = [];
150
+ }
151
+ }
152
+ exports.ToolExecutor = ToolExecutor;
153
+ ToolExecutor.executions = [];
154
+ ToolExecutor.spinners = new Map();
@@ -19,12 +19,12 @@ class UIManager {
19
19
  whitespaceBreak: true,
20
20
  });
21
21
  console.log(gradient_string_1.default.pastel.multiline(logoText));
22
- console.log(chalk_1.default.gray(' v1.1.3 - AI Coding Agent'));
22
+ console.log(chalk_1.default.gray(' v1.1.6 - AI Coding Agent'));
23
23
  console.log('');
24
24
  }
25
25
  static renderDashboard(config) {
26
26
  const { model, cwd } = config;
27
- const version = 'v1.1.3';
27
+ const version = 'v1.1.6';
28
28
  // Layout: Left (Status/Welcome) | Right (Tips/Activity)
29
29
  // Total width ~80 chars.
30
30
  // Left ~45, Right ~30.
@@ -74,5 +74,15 @@ class UIManager {
74
74
  static printSeparator() {
75
75
  console.log(chalk_1.default.gray('──────────────────────────────────────────────────'));
76
76
  }
77
+ static logBullet(text, color = 'white') {
78
+ const bullet = color === 'white' ? '●' : chalk_1.default[color]('●');
79
+ console.log(` ${bullet} ${text}`);
80
+ }
81
+ static logSystem(text) {
82
+ console.log(chalk_1.default.dim(` ${text}`));
83
+ }
84
+ static logTransition(text) {
85
+ console.log(` ${chalk_1.default.red('+')} ${chalk_1.default.red(text)}`);
86
+ }
77
87
  }
78
88
  exports.UIManager = UIManager;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ // Manual mock for chalk to avoid ESM issues in Jest
3
+ module.exports = {
4
+ dim: (str) => str,
5
+ green: (str) => str,
6
+ yellow: (str) => str,
7
+ red: (str) => str,
8
+ gray: (str) => str,
9
+ bold: (str) => str,
10
+ cyan: (str) => str,
11
+ default: {
12
+ dim: (str) => str,
13
+ green: (str) => str,
14
+ yellow: (str) => str,
15
+ red: (str) => str,
16
+ gray: (str) => str,
17
+ bold: (str) => str,
18
+ cyan: (str) => str
19
+ }
20
+ };
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ /**
3
+ * Tests for ContextVisualizer
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ContextVisualizer_1 = require("../ContextVisualizer");
7
+ describe('ContextVisualizer', () => {
8
+ let visualizer;
9
+ beforeEach(() => {
10
+ visualizer = new ContextVisualizer_1.ContextVisualizer();
11
+ });
12
+ describe('calculateUsage', () => {
13
+ it('should handle empty history', () => {
14
+ const history = [];
15
+ const usage = visualizer.calculateUsage(history);
16
+ // Includes 2000 char overhead = 500 tokens
17
+ expect(usage.tokens).toBe(500);
18
+ expect(usage.maxTokens).toBe(128000);
19
+ expect(usage).toHaveProperty('percentage');
20
+ expect(usage).toHaveProperty('tokens');
21
+ expect(usage).toHaveProperty('maxTokens');
22
+ });
23
+ it('should calculate tokens for messages', () => {
24
+ const history = [
25
+ { role: 'system', content: 'You are a helpful assistant.' },
26
+ { role: 'user', content: 'Hello' },
27
+ { role: 'assistant', content: 'Hi there!' }
28
+ ];
29
+ const usage = visualizer.calculateUsage(history);
30
+ expect(usage.tokens).toBeGreaterThan(500);
31
+ expect(usage.tokens).toBeLessThan(1000);
32
+ expect(usage.maxTokens).toBe(128000);
33
+ });
34
+ it('should handle large messages', () => {
35
+ const largeContent = 'x'.repeat(10000);
36
+ const history = [
37
+ { role: 'user', content: largeContent }
38
+ ];
39
+ const usage = visualizer.calculateUsage(history);
40
+ expect(usage.tokens).toBeGreaterThan(1500);
41
+ });
42
+ });
43
+ describe('formatBar', () => {
44
+ it('should format bar at low usage', () => {
45
+ const usage = { tokens: 1000, percentage: 5, maxTokens: 128000 };
46
+ const bar = visualizer.formatBar(usage);
47
+ // Check that bar contains expected data (without chalk dependency)
48
+ expect(bar).toContain('5');
49
+ expect(bar).toContain('1k');
50
+ expect(bar).toContain('128');
51
+ });
52
+ it('should format bar at medium usage', () => {
53
+ const usage = { tokens: 50000, percentage: 40, maxTokens: 128000 };
54
+ const bar = visualizer.formatBar(usage);
55
+ expect(bar).toContain('40');
56
+ expect(bar).toContain('50k');
57
+ });
58
+ it('should format bar at high usage', () => {
59
+ const usage = { tokens: 100000, percentage: 80, maxTokens: 128000 };
60
+ const bar = visualizer.formatBar(usage);
61
+ expect(bar).toContain('80');
62
+ expect(bar).toContain('100k');
63
+ });
64
+ });
65
+ describe('shouldCompact', () => {
66
+ it('should return false for low percentage', () => {
67
+ const history = [
68
+ { role: 'user', content: 'small message' }
69
+ ];
70
+ const shouldCompact = visualizer.shouldCompact(history);
71
+ expect(shouldCompact).toBe(false);
72
+ });
73
+ it('should return true at 80% threshold', () => {
74
+ // Create enough content to exceed 80%
75
+ // 80% of 128000 tokens = 102400 tokens = ~409600 chars
76
+ // Subtract 2000 overhead = ~407400 chars needed
77
+ const largeContent = 'x'.repeat(410000);
78
+ const history = [
79
+ { role: 'system', content: largeContent },
80
+ { role: 'user', content: largeContent }
81
+ ];
82
+ const shouldCompact = visualizer.shouldCompact(history);
83
+ expect(shouldCompact).toBe(true);
84
+ });
85
+ });
86
+ describe('setMaxTokens', () => {
87
+ it('should update max tokens', () => {
88
+ visualizer.setMaxTokens(32000);
89
+ const history = [];
90
+ const usage = visualizer.calculateUsage(history);
91
+ expect(usage.maxTokens).toBe(32000);
92
+ expect(usage.percentage).toBeGreaterThan(1); // Should be higher percentage with smaller max
93
+ });
94
+ });
95
+ });
@@ -0,0 +1,290 @@
1
+ # MCP (Model Context Protocol) Integration
2
+
3
+ Mentis CLI now supports MCP (Model Context Protocol) servers, allowing you to extend functionality with external tools and services.
4
+
5
+ ## Overview
6
+
7
+ MCP allows you to:
8
+ - Connect to external services (search, databases, APIs, etc.)
9
+ - Use additional tools beyond the built-in ones
10
+ - Create a customizable toolkit for your AI assistant
11
+
12
+ ## Preconfigured MCP Servers
13
+
14
+ The following MCP servers are pre-configured:
15
+
16
+ ### 1. Exa Search
17
+ - **Purpose**: Web search via Exa API
18
+ - **Setup**: Requires `EXA_API_KEY` environment variable
19
+ - **Command**: `npx -y @exa-labs/mcp-server-exa`
20
+
21
+ ### 2. Memory Server
22
+ - **Purpose**: Persistent memory storage for conversations
23
+ - **Setup**: No additional configuration required
24
+ - **Command**: `npx -y @modelcontextprotocol/server-memory`
25
+
26
+ ### 3. Filesystem Server
27
+ - **Purpose**: Enhanced filesystem operations
28
+ - **Setup**: No additional configuration required
29
+ - **Command**: `npx -y @modelcontextprotocol/server-filesystem <directory>`
30
+
31
+ ### 4. GitHub Server
32
+ - **Purpose**: GitHub repository management and operations
33
+ - **Setup**: Requires `GITHUB_PERSONAL_ACCESS_TOKEN` environment variable
34
+ - **Command**: `npx -y @modelcontextprotocol/server-github`
35
+
36
+ ### 5. Puppeteer Server
37
+ - **Purpose**: Web browser automation and scraping
38
+ - **Setup**: No additional configuration required
39
+ - **Command**: `npx -y @modelcontextprotocol/server-puppeteer`
40
+
41
+ ### 6. Brave Search Server
42
+ - **Purpose**: Web search via Brave Search API
43
+ - **Setup**: Requires `BRAVE_API_KEY` environment variable
44
+ - **Command**: `npx -y @modelcontextprotocol/server-brave-search`
45
+
46
+ ### 7. Slack Server
47
+ - **Purpose**: Slack workspace integration
48
+ - **Setup**: Requires `SLACK_BOT_TOKEN` environment variable
49
+ - **Command**: `npx -y @modelcontextprotocol/server-slack`
50
+
51
+ ## MCP Commands
52
+
53
+ ### List Servers
54
+ ```bash
55
+ /mcp list
56
+ ```
57
+ Shows all configured MCP servers and their connection status.
58
+
59
+ ### Connect to Server
60
+ ```bash
61
+ # Interactive selection
62
+ /mcp connect
63
+
64
+ # Direct connection
65
+ /mcp connect "Exa Search"
66
+ ```
67
+
68
+ ### Disconnect from Server
69
+ ```bash
70
+ # Interactive selection
71
+ /mcp disconnect
72
+
73
+ # Disconnect specific server
74
+ /mcp disconnect "Exa Search"
75
+
76
+ # Disconnect all
77
+ /mcp disconnect all
78
+ ```
79
+
80
+ ### Add Custom Server
81
+ ```bash
82
+ /mcp add "My Server" npx -y @my/mcp-server
83
+ ```
84
+
85
+ ### Remove Server
86
+ ```bash
87
+ # Interactive selection
88
+ /mcp remove
89
+
90
+ # Remove specific server
91
+ /mcp remove "My Server"
92
+ ```
93
+
94
+ ### Test Connection
95
+ ```bash
96
+ # Interactive selection
97
+ /mcp test
98
+
99
+ # Test specific server
100
+ /mcp test "Exa Search"
101
+ ```
102
+
103
+ ### View Configuration
104
+ ```bash
105
+ /mcp config
106
+ ```
107
+ Shows the full MCP configuration file location and contents.
108
+
109
+ ## Configuration
110
+
111
+ MCP servers are configured in `~/.mentis/mcp.json`. The configuration includes:
112
+
113
+ ```json
114
+ {
115
+ "servers": [
116
+ {
117
+ "name": "Exa Search",
118
+ "command": "npx",
119
+ "args": ["-y", "@exa-labs/mcp-server-exa"],
120
+ "description": "Web search and information retrieval via Exa API",
121
+ "autoConnect": false,
122
+ "env": {
123
+ "EXA_API_KEY": ""
124
+ }
125
+ }
126
+ ]
127
+ }
128
+ ```
129
+
130
+ ### Server Configuration Fields
131
+
132
+ - `name`: Display name for the server
133
+ - `command`: Command to run (e.g., `npx`, `node`)
134
+ - `args`: Array of arguments for the command
135
+ - `description`: Optional description of what the server does
136
+ - `autoConnect`: If `true`, automatically connects on startup
137
+ - `env`: Optional environment variables required by the server
138
+
139
+ ## Environment Variables
140
+
141
+ Some MCP servers require API keys or other configuration:
142
+
143
+ ### Exa Search
144
+ ```bash
145
+ export EXA_API_KEY=your_exa_api_key
146
+ ```
147
+
148
+ ### GitHub Server
149
+ ```bash
150
+ export GITHUB_PERSONAL_ACCESS_TOKEN=your_github_token
151
+ ```
152
+
153
+ ### Brave Search
154
+ ```bash
155
+ export BRAVE_API_KEY=your_brave_api_key
156
+ ```
157
+
158
+ ### Slack Server
159
+ ```bash
160
+ export SLACK_BOT_TOKEN=your_slack_bot_token
161
+ ```
162
+
163
+ ## Usage Examples
164
+
165
+ ### Exa Search Integration
166
+
167
+ 1. Set up your Exa API key:
168
+ ```bash
169
+ export EXA_API_KEY=your_api_key_here
170
+ ```
171
+
172
+ 2. Connect to the Exa Search server:
173
+ ```bash
174
+ /mcp connect "Exa Search"
175
+ ```
176
+
177
+ 3. Use the search functionality:
178
+ ```
179
+ Search for recent developments in TypeScript
180
+ ```
181
+
182
+ The AI will now have access to the Exa search tools and can perform web searches.
183
+
184
+ ### Memory Server
185
+
186
+ 1. Connect to the memory server:
187
+ ```bash
188
+ /mcp connect Memory
189
+ ```
190
+
191
+ 2. The AI can now store and retrieve information across sessions.
192
+
193
+ ### GitHub Integration
194
+
195
+ 1. Set up your GitHub token:
196
+ ```bash
197
+ export GITHUB_PERSONAL_ACCESS_TOKEN=your_token_here
198
+ ```
199
+
200
+ 2. Connect to the GitHub server:
201
+ ```bash
202
+ /mcp connect GitHub
203
+ ```
204
+
205
+ 3. Use GitHub functionality:
206
+ ```
207
+ List the recent issues in the mentis-cli repository
208
+ Create a pull request for my changes
209
+ ```
210
+
211
+ ## Auto-Connect
212
+
213
+ To automatically connect to specific servers on startup, set `autoConnect: true` in the server configuration:
214
+
215
+ ```json
216
+ {
217
+ "servers": [
218
+ {
219
+ "name": "Memory",
220
+ "command": "npx",
221
+ "args": ["-y", "@modelcontextprotocol/server-memory"],
222
+ "autoConnect": true
223
+ }
224
+ ]
225
+ }
226
+ ```
227
+
228
+ ## Troubleshooting
229
+
230
+ ### Connection Issues
231
+
232
+ 1. **Missing API Keys**: Ensure all required environment variables are set
233
+ 2. **Network Issues**: Check your internet connection
234
+ 3. **Server Not Found**: Verify the MCP server package is correct
235
+
236
+ ### Test Connection
237
+
238
+ Use the test command to verify connectivity:
239
+ ```bash
240
+ /mcp test <server_name>
241
+ ```
242
+
243
+ ### View Logs
244
+
245
+ MCP connection errors are logged with detailed information. Check the console output for specific error messages.
246
+
247
+ ## Creating Custom MCP Servers
248
+
249
+ You can add any MCP server to your configuration:
250
+
251
+ ```bash
252
+ /mcp add "My Custom Server" node /path/to/my-server.js
253
+ ```
254
+
255
+ Or manually edit `~/.mentis/mcp.json`:
256
+
257
+ ```json
258
+ {
259
+ "servers": [
260
+ {
261
+ "name": "My Custom Server",
262
+ "command": "node",
263
+ "args": ["/path/to/my-server.js"],
264
+ "description": "My custom MCP server",
265
+ "autoConnect": false
266
+ }
267
+ ]
268
+ }
269
+ ```
270
+
271
+ ## Security Considerations
272
+
273
+ - **API Keys**: Store API keys securely using environment variables
274
+ - **Server Trust**: Only connect to MCP servers from trusted sources
275
+ - **File Access**: Be cautious with filesystem servers that have broad access
276
+ - **Network**: MCP servers may make network requests on your behalf
277
+
278
+ ## Best Practices
279
+
280
+ 1. **Environment Variables**: Always use environment variables for sensitive data
281
+ 2. **Minimal Scope**: Configure servers with minimal required permissions
282
+ 3. **Regular Updates**: Keep MCP server packages updated
283
+ 4. **Monitor Usage**: Check which tools are being used and how frequently
284
+
285
+ ## Resources
286
+
287
+ - [MCP Specification](https://modelcontextprotocol.io/)
288
+ - [Exa API Documentation](https://docs.exa.ai/)
289
+ - [Model Context Protocol GitHub](https://github.com/modelcontextprotocol)
290
+ - [Available MCP Servers](https://mcp-examples.now.sh/)