Skip to main content
Glama
str-replace.ts2.45 kB
import type {McpServer} from '@modelcontextprotocol/sdk/server/mcp.js'; import {z} from 'zod'; import * as fs from 'node:fs/promises'; import {jsonResult} from '../utils/response.js'; import {expandPath} from '../utils/paths.js'; const description = `Replace an exact string in a file. - old_str must match exactly and be unique in the file - If old_str appears 0 times or more than once, the operation fails - If new_str is omitted, old_str is deleted - Use absolute paths`; export function registerStrReplace(server: McpServer): void { server.registerTool( 'str_replace', { title: 'String Replace', description, inputSchema: { path: z.string().describe('Absolute path to file'), old_str: z.string().describe('Exact string to find (must be unique)'), new_str: z.string().optional().describe('Replacement string (omit to delete)'), }, annotations: { readOnlyHint: false, destructiveHint: true, }, }, async (args) => { const targetPath = expandPath(args.path); const oldStr = args.old_str; const newStr = args.new_str ?? ''; const content = await fs.readFile(targetPath, 'utf-8'); // Check for empty file if (content.length === 0) { throw new Error('Cannot use str_replace on an empty file'); } // Count occurrences const occurrences = countOccurrences(content, oldStr); if (occurrences === 0) { const preview = oldStr.length > 100 ? `${oldStr.slice(0, 100)}...` : oldStr; throw new Error(`old_str not found in file: "${preview}"`); } if (occurrences > 1) { // Find line numbers of all occurrences const lines = content.split('\n'); const matchingLines: number[] = []; for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (line?.includes(oldStr)) { matchingLines.push(i + 1); } } throw new Error(`old_str appears ${occurrences} times (must be unique). Found on lines: ${matchingLines.join(', ')}`); } // Replace const newContent = content.replace(oldStr, newStr); await fs.writeFile(targetPath, newContent, 'utf-8'); return jsonResult({ success: true, path: targetPath, replacements: 1, }); }, ); } function countOccurrences(str: string, substr: string): number { if (substr.length === 0) { return 0; } let count = 0; let pos = 0; while ((pos = str.indexOf(substr, pos)) !== -1) { count += 1; pos += substr.length; } return count; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/domdomegg/filesystem-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server