@morphllm/morphmcp 0.8.13 → 0.8.14
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.
- package/README.md +100 -13
- package/dist/index.js +86 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@ Unified Model Context Protocol (MCP) server providing AI-powered file editing an
|
|
|
6
6
|
|
|
7
7
|
### AI-Powered Tools
|
|
8
8
|
- **Fast Apply (edit_file)** - Morph's lightning-fast code editing at 10,500+ tokens/sec with 98% accuracy
|
|
9
|
-
- **
|
|
9
|
+
- **Semantic Search (codebase_search)** - Natural language code search using embeddings and GPU reranking for finding relevant code across your codebase
|
|
10
|
+
- **Fast Context Search (fast_context_search)** - AI-powered grep agent using WarpGrep that intelligently explores repositories to find relevant code
|
|
10
11
|
|
|
11
12
|
### Filesystem Operations
|
|
12
13
|
- Read/write files with memory-efficient head/tail operations
|
|
@@ -29,33 +30,36 @@ Unified Model Context Protocol (MCP) server providing AI-powered file editing an
|
|
|
29
30
|
| Variable | Description | Default |
|
|
30
31
|
|----------|-------------|---------|
|
|
31
32
|
| `MORPH_API_KEY` | Your Morph API key (required for AI tools) | - |
|
|
32
|
-
| `ENABLED_TOOLS` | Comma-separated list of enabled tools, or `all` | `edit_file,
|
|
33
|
+
| `ENABLED_TOOLS` | Comma-separated list of enabled tools, or `all` | `edit_file,codebase_search` |
|
|
33
34
|
| `MORPH_DEBUG` | Enable debug logging for grep agent (`true`/`false`) | `false` |
|
|
34
35
|
| `ENABLE_WORKSPACE_MODE` | Auto-detect workspace root (`true`/`false`) | `true` |
|
|
35
36
|
| `WORKSPACE_ROOT` | Override workspace root directory | `$PWD` |
|
|
36
37
|
|
|
37
38
|
### Tool Configuration
|
|
38
39
|
|
|
39
|
-
Control which tools are available using `ENABLED_TOOLS`. **By default, only AI-powered tools (`edit_file` and `
|
|
40
|
+
Control which tools are available using `ENABLED_TOOLS`. **By default, only AI-powered tools (`edit_file` and `codebase_search`) are enabled** to keep the interface clean. Enable additional filesystem tools as needed:
|
|
40
41
|
|
|
41
42
|
```bash
|
|
42
43
|
# Default: Only AI-powered tools
|
|
43
|
-
# (No ENABLED_TOOLS needed - edit_file and
|
|
44
|
+
# (No ENABLED_TOOLS needed - edit_file and codebase_search are enabled by default)
|
|
44
45
|
|
|
45
46
|
# Enable all tools including filesystem operations
|
|
46
47
|
ENABLED_TOOLS=all
|
|
47
48
|
|
|
48
49
|
# Only AI-powered tools (explicit, same as default)
|
|
49
|
-
ENABLED_TOOLS=edit_file,
|
|
50
|
+
ENABLED_TOOLS=edit_file,codebase_search
|
|
50
51
|
|
|
51
52
|
# Only fast apply
|
|
52
53
|
ENABLED_TOOLS=edit_file
|
|
53
54
|
|
|
54
|
-
# Only
|
|
55
|
-
ENABLED_TOOLS=
|
|
55
|
+
# Only semantic search
|
|
56
|
+
ENABLED_TOOLS=codebase_search
|
|
57
|
+
|
|
58
|
+
# Include fast_context_search (grep agent)
|
|
59
|
+
ENABLED_TOOLS=edit_file,codebase_search,fast_context_search
|
|
56
60
|
|
|
57
61
|
# Custom selection
|
|
58
|
-
ENABLED_TOOLS=read_file,write_file,edit_file,
|
|
62
|
+
ENABLED_TOOLS=read_file,write_file,edit_file,codebase_search
|
|
59
63
|
```
|
|
60
64
|
|
|
61
65
|
## Available Tools
|
|
@@ -77,6 +81,62 @@ ENABLED_TOOLS=read_file,write_file,edit_file,fast_context_search
|
|
|
77
81
|
|
|
78
82
|
**Note for Cursor users:** If you're using this tool within Cursor, you may need to first use another tool (like `search_replace`) to add exactly one empty newline somewhere in the file before using `edit_file`. This ensures the file is in an editable state.
|
|
79
83
|
|
|
84
|
+
#### `codebase_search`
|
|
85
|
+
**SEMANTIC CODE SEARCH** - Find code using natural language queries. Uses two-stage retrieval (vector search + GPU reranking) to find the most relevant code across your entire codebase.
|
|
86
|
+
|
|
87
|
+
**Key features:**
|
|
88
|
+
- Natural language queries: "Where is JWT validation?" or "How does auth work?"
|
|
89
|
+
- Two-stage retrieval: Vector search (~240ms) + GPU reranking (~630ms)
|
|
90
|
+
- Returns precise code chunks with relevance scores
|
|
91
|
+
- Searches by semantic meaning, not just keywords
|
|
92
|
+
- Works across all files and languages
|
|
93
|
+
|
|
94
|
+
**Requires:** `MORPH_API_KEY` and code pushed to Morph git
|
|
95
|
+
|
|
96
|
+
**How it works:**
|
|
97
|
+
```
|
|
98
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
99
|
+
│ SEMANTIC SEARCH LIFECYCLE │
|
|
100
|
+
└─────────────────────────────────────────────────────────────┘
|
|
101
|
+
|
|
102
|
+
1. CODE CHANGES 2. AUTO-SYNC (Plugin)
|
|
103
|
+
┌─────────────┐ ┌─────────────┐
|
|
104
|
+
│ Agent edits │ ──────────────────> │ git commit │
|
|
105
|
+
│ files │ │ + push │
|
|
106
|
+
└─────────────┘ └──────┬──────┘
|
|
107
|
+
│
|
|
108
|
+
▼
|
|
109
|
+
3. EMBEDDING (3-8s) 4. INDEXED & SEARCHABLE
|
|
110
|
+
┌─────────────────┐ ┌──────────────────┐
|
|
111
|
+
│ Code chunking │ │ PostgreSQL │
|
|
112
|
+
│ morph-v4-embed │ ────────────> │ pgvector (HNSW) │
|
|
113
|
+
│ Vector storage │ │ Ready for search │
|
|
114
|
+
└─────────────────┘ └────────┬─────────┘
|
|
115
|
+
│
|
|
116
|
+
▼
|
|
117
|
+
5. SEARCH QUERY 6. TWO-STAGE RETRIEVAL
|
|
118
|
+
┌─────────────────┐ ┌──────────────────┐
|
|
119
|
+
│ "Find auth │ │ Vector: top 50 │
|
|
120
|
+
│ logic" │ ────────────> │ Rerank: top 10 │
|
|
121
|
+
└─────────────────┘ │ ~1000ms total │
|
|
122
|
+
└────────┬─────────┘
|
|
123
|
+
│
|
|
124
|
+
▼
|
|
125
|
+
7. RESULTS 8. AGENT USES CONTEXT
|
|
126
|
+
┌─────────────────┐ ┌──────────────────┐
|
|
127
|
+
│ Ranked code │ │ Makes informed │
|
|
128
|
+
│ with scores │ ────────────> │ edits with │
|
|
129
|
+
│ + line numbers │ │ relevant context │
|
|
130
|
+
└─────────────────┘ └──────────────────┘
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Setup:** Install the `morph-sync` plugin to automatically sync code after every agent response. See [Enable Semantic Search](#enable-semantic-search-with-morph-sync-plugin) below.
|
|
134
|
+
|
|
135
|
+
**Example queries:**
|
|
136
|
+
- "Where is JWT validation implemented?"
|
|
137
|
+
- "How does the authentication middleware work?"
|
|
138
|
+
- "Find database connection setup"
|
|
139
|
+
|
|
80
140
|
#### `fast_context_search`
|
|
81
141
|
Intelligently search and gather relevant code context from a repository using Morph's WarpGrep AI-powered search agent. Automatically explores the codebase with grep, file reading, and directory analysis to find exactly what you need.
|
|
82
142
|
|
|
@@ -228,12 +288,12 @@ Or manually add to `.vscode/mcp.json`:
|
|
|
228
288
|
}
|
|
229
289
|
```
|
|
230
290
|
|
|
231
|
-
**For code search only:**
|
|
291
|
+
**For semantic code search only:**
|
|
232
292
|
```json
|
|
233
293
|
{
|
|
234
294
|
"env": {
|
|
235
295
|
"MORPH_API_KEY": "sk-...",
|
|
236
|
-
"ENABLED_TOOLS": "
|
|
296
|
+
"ENABLED_TOOLS": "codebase_search"
|
|
237
297
|
}
|
|
238
298
|
}
|
|
239
299
|
```
|
|
@@ -253,16 +313,27 @@ Or manually add to `.vscode/mcp.json`:
|
|
|
253
313
|
{
|
|
254
314
|
"env": {
|
|
255
315
|
"MORPH_API_KEY": "sk-..."
|
|
256
|
-
// ENABLED_TOOLS defaults to edit_file,
|
|
316
|
+
// ENABLED_TOOLS defaults to edit_file,codebase_search
|
|
257
317
|
}
|
|
258
318
|
}
|
|
259
319
|
```
|
|
260
320
|
|
|
261
|
-
### 3.
|
|
321
|
+
### 3. Enable Semantic Search (Optional but Recommended)
|
|
322
|
+
|
|
323
|
+
For the `codebase_search` tool to work, code must be synced to Morph git. Install the `morph-sync` plugin:
|
|
324
|
+
|
|
325
|
+
**In Claude Code:**
|
|
326
|
+
```bash
|
|
327
|
+
/plugin install morph-sync
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
The plugin automatically commits and pushes code after every agent response, triggering embedding in the background (3-8 seconds).
|
|
331
|
+
|
|
332
|
+
### 4. Test Your Setup
|
|
262
333
|
|
|
263
334
|
In your AI assistant, try:
|
|
264
335
|
- **Edit test:** "Use the edit_file tool to add a comment to the main function"
|
|
265
|
-
- **Search test:** "
|
|
336
|
+
- **Search test:** "Find the authentication logic in this codebase" (uses codebase_search)
|
|
266
337
|
|
|
267
338
|
## Usage Examples
|
|
268
339
|
|
|
@@ -279,6 +350,22 @@ The AI will:
|
|
|
279
350
|
5. Report errors (if any) to Morph for continuous improvement
|
|
280
351
|
```
|
|
281
352
|
|
|
353
|
+
### Semantic Code Search
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
Ask AI: "Find the authentication logic in this codebase"
|
|
357
|
+
|
|
358
|
+
The codebase_search tool will:
|
|
359
|
+
1. Query the embedded codebase using natural language
|
|
360
|
+
2. Vector search retrieves top 50 candidates (~240ms)
|
|
361
|
+
3. GPU reranking scores for precision (~630ms)
|
|
362
|
+
4. Return top 10 most relevant code chunks with scores
|
|
363
|
+
5. Include file paths, line numbers, and relevance percentages
|
|
364
|
+
6. Agent uses this context to make informed edits
|
|
365
|
+
|
|
366
|
+
Note: Requires code to be synced via morph-sync plugin
|
|
367
|
+
```
|
|
368
|
+
|
|
282
369
|
### Fast Context Search
|
|
283
370
|
|
|
284
371
|
```
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { isPathWithinAllowedDirectories } from './path-validation.js';
|
|
|
14
14
|
import { getValidRootDirectories } from './roots-utils.js';
|
|
15
15
|
import { executeEditFile } from '@morphllm/morphsdk/tools/fastapply';
|
|
16
16
|
import { runWarpGrep, LocalRipgrepProvider } from '@morphllm/morphsdk/tools/warp-grep';
|
|
17
|
+
import { CodebaseSearchClient } from '@morphllm/morphsdk/tools/codebase-search';
|
|
17
18
|
import axios from "axios";
|
|
18
19
|
// Command line argument parsing
|
|
19
20
|
const args = process.argv.slice(2);
|
|
@@ -33,13 +34,14 @@ const ALL_TOOLS = [
|
|
|
33
34
|
'get_file_info',
|
|
34
35
|
'list_allowed_directories',
|
|
35
36
|
'edit_file',
|
|
36
|
-
'fast_context_search'
|
|
37
|
+
'fast_context_search',
|
|
38
|
+
'codebase_search'
|
|
37
39
|
];
|
|
38
40
|
// Only expose Morph-specific tools by default
|
|
39
41
|
// Other filesystem tools remain available for internal use and via ENABLED_TOOLS env var
|
|
40
42
|
const DEFAULT_TOOLS = [
|
|
41
43
|
'edit_file',
|
|
42
|
-
'
|
|
44
|
+
'codebase_search'
|
|
43
45
|
];
|
|
44
46
|
// Parse ENABLED_TOOLS env var: comma-separated list or 'all'
|
|
45
47
|
const ENABLED_TOOLS = process.env.ENABLED_TOOLS
|
|
@@ -268,6 +270,14 @@ const FastContextSearchArgsSchema = z.object({
|
|
|
268
270
|
repoPath: z.string().describe("Path to the repository root"),
|
|
269
271
|
query: z.string().describe("Natural language query describing the code context needed"),
|
|
270
272
|
});
|
|
273
|
+
const CodebaseSearchArgsSchema = z.object({
|
|
274
|
+
query: z.string().describe('Natural language query to search for code'),
|
|
275
|
+
repoId: z.string().describe('Repository identifier'),
|
|
276
|
+
branch: z.string().optional().describe('Branch to search (uses latest commit)'),
|
|
277
|
+
commitHash: z.string().optional().describe('Specific commit hash to search'),
|
|
278
|
+
target_directories: z.array(z.string()).default([]).describe('Filter to specific directories, empty for all'),
|
|
279
|
+
limit: z.number().optional().default(10).describe('Max results to return')
|
|
280
|
+
});
|
|
271
281
|
const ToolInputSchema = ToolSchema.shape.inputSchema;
|
|
272
282
|
// Server setup
|
|
273
283
|
const server = new Server({
|
|
@@ -650,6 +660,22 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
650
660
|
inputSchema: zodToJsonSchema(FastContextSearchArgsSchema),
|
|
651
661
|
requiresApiKey: true,
|
|
652
662
|
},
|
|
663
|
+
{
|
|
664
|
+
name: "codebase_search",
|
|
665
|
+
description: "**SEMANTIC CODE SEARCH - USE FOR FINDING CODE**\n\n" +
|
|
666
|
+
"⚡ INTELLIGENT: Natural language search across your entire codebase using AI embeddings.\n" +
|
|
667
|
+
"🎯 USE THIS TOOL to find code when you need to understand existing implementations.\n\n" +
|
|
668
|
+
"Benefits:\n" +
|
|
669
|
+
"- Two-stage retrieval: vector search (~240ms) + GPU reranking (~630ms)\n" +
|
|
670
|
+
"- Returns precise code chunks with relevance scores\n" +
|
|
671
|
+
"- Searches by semantic meaning, not just keywords\n" +
|
|
672
|
+
"- Works across all files and languages\n\n" +
|
|
673
|
+
"Search your codebase using natural language queries. Code must be pushed to Morph git first (see Repo Storage docs). " +
|
|
674
|
+
"Returns ranked code chunks with relevance scores, file paths, and line numbers. " +
|
|
675
|
+
"Example queries: 'Where is JWT validation?', 'How does auth work?', 'Find database connection logic'.",
|
|
676
|
+
inputSchema: zodToJsonSchema(CodebaseSearchArgsSchema),
|
|
677
|
+
requiresApiKey: true,
|
|
678
|
+
},
|
|
653
679
|
];
|
|
654
680
|
// Filter tools based on ENABLED_TOOLS and API key availability
|
|
655
681
|
const availableTools = allTools.filter(tool => {
|
|
@@ -1152,6 +1178,64 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1152
1178
|
};
|
|
1153
1179
|
}
|
|
1154
1180
|
}
|
|
1181
|
+
case "codebase_search": {
|
|
1182
|
+
const parsed = CodebaseSearchArgsSchema.safeParse(args);
|
|
1183
|
+
if (!parsed.success) {
|
|
1184
|
+
return {
|
|
1185
|
+
content: [{ type: "text", text: `Invalid arguments: ${parsed.error}` }],
|
|
1186
|
+
isError: true,
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
try {
|
|
1190
|
+
const apiKey = MORPH_API_KEY;
|
|
1191
|
+
if (!apiKey) {
|
|
1192
|
+
throw new Error('MORPH_API_KEY environment variable must be set in MCP config.');
|
|
1193
|
+
}
|
|
1194
|
+
const client = new CodebaseSearchClient({ apiKey, debug: false });
|
|
1195
|
+
const result = await client.search({
|
|
1196
|
+
query: parsed.data.query,
|
|
1197
|
+
repoId: parsed.data.repoId,
|
|
1198
|
+
branch: parsed.data.branch,
|
|
1199
|
+
commitHash: parsed.data.commitHash,
|
|
1200
|
+
target_directories: parsed.data.target_directories,
|
|
1201
|
+
limit: parsed.data.limit
|
|
1202
|
+
});
|
|
1203
|
+
if (!result.success) {
|
|
1204
|
+
return {
|
|
1205
|
+
content: [{ type: "text", text: `Search failed: ${result.error}` }],
|
|
1206
|
+
isError: true,
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
// Format results
|
|
1210
|
+
const resultText = result.results.length === 0
|
|
1211
|
+
? `No results found for query: "${parsed.data.query}"`
|
|
1212
|
+
: `Found ${result.results.length} results in ${result.stats.searchTimeMs}ms:\n\n` +
|
|
1213
|
+
result.results.map((r, i) => `${i + 1}. ${r.filepath} (${(r.rerankScore * 100).toFixed(1)}% match)\n` +
|
|
1214
|
+
` Lines ${r.startLine}-${r.endLine}\n` +
|
|
1215
|
+
` ${r.content.substring(0, 200)}${r.content.length > 200 ? '...' : ''}\n`).join('\n');
|
|
1216
|
+
return {
|
|
1217
|
+
content: [{ type: "text", text: resultText }],
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
catch (error) {
|
|
1221
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1222
|
+
reportMorphError({
|
|
1223
|
+
error_message: errorMessage,
|
|
1224
|
+
error_type: error instanceof Error ? error.constructor.name : 'UnknownError',
|
|
1225
|
+
context: {
|
|
1226
|
+
tool: 'codebase_search',
|
|
1227
|
+
query: parsed.data.query,
|
|
1228
|
+
repo_id: parsed.data.repoId
|
|
1229
|
+
},
|
|
1230
|
+
stack_trace: error instanceof Error ? error.stack : undefined,
|
|
1231
|
+
source: 'mcp-filesystem'
|
|
1232
|
+
}).catch(() => { });
|
|
1233
|
+
return {
|
|
1234
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
1235
|
+
isError: true,
|
|
1236
|
+
};
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1155
1239
|
default:
|
|
1156
1240
|
throw new Error(`Unknown tool: ${name}`);
|
|
1157
1241
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morphllm/morphmcp",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.14",
|
|
4
4
|
"description": "Fast & accurate MCP server with AI-powered file editing and intelligent code search. Prevents context pollution and saves time for a better user experience.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Morph (https://morphllm.com)",
|