Morph Grep Agent MCP Server
TypeScript implementation of the Morph code-search subagent packaged as a Model Context Protocol (MCP) server. The server runs the three-round grep/search workflow defined in common/system_prompt.py, using fast local tools (analyse, read, grep, finish) to collect context for a natural-language query against a repository.
Features
- Exact prompt parity – ships the same system prompt and tool semantics as the Python agent (
common/).
- High-performance tools – wraps
@vscode/ripgrep for fast repo-wide regex search, plus cached analyse and read utilities.
- Hybrid file suggestions – ports the Python hybrid path/content ranking used to seed initial results.
- Configurable LLM backend – targets any OpenAI-compatible
/v1/chat/completions endpoint (local vLLM, OpenRouter, etc.).
- Secure repo access – restrict repositories to an allowlist (defaults to the current working directory).
Quick Start
For End Users (via NPM)
-
Get your Morph API key from https://morphllm.com/dashboard/api-keys
-
Add to .cursor/mcp.json (or ~/.cursor/mcp.json for global):
{
"mcpServers": {
"morph-fast-context": {
"command": "npx",
"args": ["-y", "morph-codeseek"],
"env": {
"GREP_AGENT_API_KEY": "sk-your-morph-api-key-here"
}
}
}
}
-
Reload Cursor (Cmd+Shift+P → "Developer: Reload Window")
That's it! The server is pre-configured with Morph's production infrastructure.
For Developers
cd morph-mcp/grep-agent
npm install
npm test
npm start
Environment Variables (Optional)
GREP_AGENT_API_KEY | Your Morph API key | (required) |
GREP_AGENT_HOST_URL | Override inference server URL | http://192.222.50.122:8080 |
GREP_AGENT_MODEL | Override model name | fast-grep-303 |
MORPH_DEBUG | Enable debug logging (true/1) | disabled |
GREP_AGENT_DEBUG_DIR | Custom debug log directory | {tmpdir}/morph-codeseek-debug |
MCP Tool
run_grep_agent({
repoPath: "/absolute/path/to/repo",
query: "Where do we validate JWT refresh tokens?"
})
The tool returns the relevant code snippets found, formatted as XML blocks with line numbers.
Response Format
The MCP server returns a structured response showing:
- Search actions - What the agent did during exploration
- File list - All relevant files and line ranges found
- File contents - The actual code wrapped in XML blocks with line numbers
Example successful response:
Morph Fast Context subagent performed search on repository:
- Grepped 'validate.*token' in `src`
- Grepped 'jwt' in `.`
- Read file `src/auth/jwt.ts:1-50`
- Analysed directory `src/auth`
- Grepped 'authMiddleware' in `src`
- Read file `src/middleware/auth.ts:10-30`
- Read file `src/auth/jwt.ts:75-90`
Relevant context found:
- src/auth/jwt.ts:25-31,75-78
- src/middleware/auth.ts:10-22
Here is the content of files:
<file path="src/auth/jwt.ts">
25| export function validateToken(token: string) {
26| const decoded = jwt.verify(token, SECRET_KEY);
27| if (!decoded || !decoded.exp) {
28| throw new Error('Invalid token');
29| }
30| return decoded;
31| }
75| export function refreshToken(oldToken: string) {
76| const payload = validateToken(oldToken);
77| return generateToken(payload.userId);
78| }
</file>
<file path="src/middleware/auth.ts">
10| export const authMiddleware = (req, res, next) => {
11| const token = req.headers.authorization?.split(' ')[1];
12| if (!token) {
13| return res.status(401).json({ error: 'No token provided' });
14| }
15| try {
16| const user = validateToken(token);
17| req.user = user;
18| next();
19| } catch (err) {
20| return res.status(401).json({ error: 'Invalid token' });
21| }
22| };
</file>
Response Scenarios
Successful completion
When the agent finds relevant code, the response contains three sections:
-
Search Actions: Shows what the Morph Fast Context subagent did during exploration
Grepped '...' in '...' - Searched for a regex pattern in a directory or file
Read file '...' - Read specific file or line ranges
Analysed directory '...' - Explored directory structure
-
File List: Compact summary of all files found with their line ranges in format path:start-end,start-end
-
File Contents: Full XML blocks with actual code content and line numbers from the identified locations
No results
If the agent completes all rounds without calling the finish tool:
Agent completed 4 rounds but did not call finish tool.
Error during execution
If an error occurs during the agent's execution:
Error: LLM request failed with status 500
Agent Execution Flow
The agent follows a 4-round workflow:
-
Rounds 1-3: Exploration using grep, read, and analyse tools
- Each round can execute up to 8 tool calls in parallel
- Results guide subsequent exploration
-
Finish Reminder: After round 3, the agent is prompted to call finish
-
Round 4: Final round where the agent calls finish with identified file locations
The XML response automatically includes the actual code content from the line ranges the agent identified.
Debug Logging
Debug logging is disabled by default for optimal performance. To enable detailed logging, set MORPH_DEBUG=true (or MORPH_DEBUG=1) in your environment:
{
"mcpServers": {
"morph-fast-context": {
"command": "npx",
"args": ["-y", "morph-codeseek"],
"env": {
"GREP_AGENT_API_KEY": "sk-your-morph-api-key-here",
"MORPH_DEBUG": "true"
}
}
}
}
When enabled, detailed logs are saved to {tmpdir}/morph-codeseek-debug/ (customizable via GREP_AGENT_DEBUG_DIR):
session-{timestamp}-{id}.log: Human-readable logs with timestamps and context
session-{timestamp}-{id}.jsonl: Structured JSONL logs for programmatic analysis
session-{timestamp}-{id}-messages.json: Complete conversation history including all messages exchanged between system, user, and assistant
These logs are useful for debugging, performance analysis, and understanding the agent's decision-making process.
Testing
npm test
npm run build
Development Notes
- Source lives in
src/ (ESM, Node >=18).
- Tests reside in
src/__tests__/ and run under ts-jest.
- Ripgrep is bundled via
@vscode/ripgrep; no system dependency is required.
- The agent uses the hybrid file finder and repo overview ports from
common/utils.
Installing in Windsurf Cascade
Follow these steps to wire the server into Windsurf’s Cascade MCP host:
-
Check prerequisites
- Node.js 18+ (ESM +
fetch)
- npm (bundled with Node)
- This repo (or the
morph-mcp submodule) cloned locally
- Verify with
node --version and npm --version
-
Install dependencies & build
cd morph-mcp/grep-agent
npm install
Re-run npm run build after any source changes.
-
Register the server in Windsurf Cascade
- Open Settings → Cascade.
- Add a Custom MCP Server with Command
node, Args ["/lambda/nfs/embeddings/dat/workspace/swe-grep/dat_sft/morph-mcp/grep-agent/dist/server.js"], and no working directory needed.
Editing the Cascade JSON directly:
{
"mcpServers": {
"morph-fast-context": {
"command": "node",
"args": [
"/lambda/nfs/embeddings/dat/workspace/swe-grep/dat_sft/morph-mcp/grep-agent/dist/server.js"
],
"env": {
"GREP_AGENT_HOST_URL": "http://localhost:8000",
"GREP_AGENT_MODEL": "/model"
}
}
}
}
Adjust the environment variables to match your setup. Cascade applies the configuration after you press Refresh.
-
Set optional environment overrides (in Cascade’s env section, for STDIO launches)
GREP_AGENT_HOST_URL | Base URL for your OpenAI-compatible endpoint | http://localhost:8000 |
GREP_AGENT_MODEL | Model identifier | /model |
(You can supply apiKey directly in the tool call if authentication is required.)
-
Validate the setup
- Connect to the server from the Cascade panel in Windsurf.
- Run a sample prompt (e.g., “Find where JWT tokens are validated.”).
- The agent should send
analyse/grep/read calls, then finish with a summary.
If the STDIO server exits early, run it manually to inspect logs:
node /lambda/nfs/embeddings/dat/workspace/swe-grep/dat_sft/morph-mcp/grep-agent/dist/server.js
-
Stay current
- Pull updates →
npm install to pick up new deps.
npm test to run the Jest suite (includes an integration test for runAgent).
Installing in Cursor
Follow these steps to wire the server into Cursor’s MCP host:
-
Check prerequisites
- Node.js 18+ (needed for native ESM and
fetch)
- npm (bundled with Node)
- This repo (or the
morph-mcp submodule) cloned locally
- Verify with
node --version and npm --version
-
Install dependencies & build
cd morph-mcp/grep-agent
npm install
Re-run npm run build after you change TypeScript sources so dist/server.js stays current.
-
Pick a configuration scope
- Global: create
~/.cursor/mcp.json to expose the server in every project.
- Workspace: create
.cursor/mcp.json in the project root (the folder Cursor opens).
- Cursor supports placeholders such as
${workspaceFolder} / ${workspaceFolderBasename} and ${env:VAR_NAME} inside the JSON.
-
Add the server definition
{
"mcpServers": {
"morph-fast-context": {
"command": "node",
"args": [
"/lambda/nfs/embeddings/dat/workspace/swe-grep/dat_sft/morph-mcp/grep-agent/dist/server.js"
],
"transport": "stdio",
"env": {
"GREP_AGENT_HOST_URL": "http://localhost:8000",
"GREP_AGENT_MODEL": "/model"
}
}
}
}
Adjust the environment variables to match your setup.
-
Reload Cursor and validate
-
Stay current
- Pull updates →
npm install to sync dependencies.
npm test to execute the Jest suite (unit + integration coverage).
npm run build before reconnecting the MCP server to regenerate dist/.