Skip to main content
Glama

RAG Documentation MCP Server

import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'; import { BaseHandler } from './base-handler.js'; import { McpToolResponse, RepositoryConfig } from '../types.js'; import fs from 'fs/promises'; import path from 'path'; import { RepositoryWatcher } from '../utils/repository-watcher.js'; import { UpdateRepositoryHandler } from './update-repository.js'; import { RepositoryConfigLoader } from '../utils/repository-config-loader.js'; const REPO_CONFIG_DIR = path.join(process.cwd(), 'repo-configs'); // Map to store active watchers const activeWatchers = new Map<string, RepositoryWatcher>(); export class WatchRepositoryHandler extends BaseHandler { private updateHandler: UpdateRepositoryHandler; constructor(server: any, apiClient: any) { super(server, apiClient); this.updateHandler = new UpdateRepositoryHandler(server, apiClient); } async handle(args: any, callContext?: { progressToken?: string | number, requestId: string | number }): Promise<McpToolResponse> { if (!args.name || typeof args.name !== 'string') { throw new McpError(ErrorCode.InvalidParams, 'Repository name is required'); } if (args.action !== 'start' && args.action !== 'stop') { throw new McpError(ErrorCode.InvalidParams, 'Action must be either "start" or "stop"'); } const repoName = args.name; const configPath = path.join(REPO_CONFIG_DIR, `${repoName}.json`); try { // Check if the repository config exists try { await fs.access(configPath); } catch { throw new McpError(ErrorCode.InvalidParams, `Repository not found: ${repoName}`); } // Read the config const configContent = await fs.readFile(configPath, 'utf-8'); const config = JSON.parse(configContent) as RepositoryConfig; if (args.action === 'start') { // Check if already watching if (activeWatchers.has(repoName)) { return { content: [ { type: 'text', text: `Repository ${repoName} is already being watched`, }, ], }; } // Create a new watcher const watcher = new RepositoryWatcher( config, async (changedFiles, removedFiles) => { console.log(`Repository ${repoName} changed: ${changedFiles.length} files changed, ${removedFiles.length} files removed`); // Update the repository index if (changedFiles.length > 0 || removedFiles.length > 0) { try { // Pass the callContext along if it exists await this.updateHandler.handle({ name: repoName }, callContext); console.log(`Repository ${repoName} index updated successfully`); } catch (error) { console.error(`Failed to update repository ${repoName} index:`, error); } } } ); // Start watching await watcher.start(); activeWatchers.set(repoName, watcher); // Update the config to reflect watch mode config.watchMode = true; await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8'); // Update the repositories.json configuration file const configLoader = new RepositoryConfigLoader(this.server, this.apiClient); await configLoader.addRepositoryToConfig(config); return { content: [ { type: 'text', text: `Started watching repository: ${repoName} (${config.path})`, }, ], }; } else { // Stop watching const watcher = activeWatchers.get(repoName); if (!watcher) { return { content: [ { type: 'text', text: `Repository ${repoName} is not currently being watched`, }, ], }; } watcher.stop(); activeWatchers.delete(repoName); // Update the config to reflect watch mode config.watchMode = false; await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8'); // Update the repositories.json configuration file const configLoader = new RepositoryConfigLoader(this.server, this.apiClient); await configLoader.addRepositoryToConfig(config); return { content: [ { type: 'text', text: `Stopped watching repository: ${repoName} (${config.path})`, }, ], }; } } catch (error) { if (error instanceof McpError) { throw error; } return { content: [ { type: 'text', text: `Failed to ${args.action} watching repository: ${error}`, }, ], isError: true, }; } } }

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/rahulretnan/mcp-ragdocs'

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