content_get_raw
Retrieve unprocessed raw Markdown content from files or directories, combining all .md files with separators for direct use in AI models, documentation, or knowledge bases.
Instructions
Get raw markdown content without any processing. If source is a file, returns that file. If source is a directory, combines ALL .md files into one content with separators
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file_path | No | Not used - content source is determined by CONTENT_SOURCE_TYPE and CONTENT_SOURCE_PATH environment variables |
Implementation Reference
- src/tools/contentOperations.ts:6-126 (handler)The core handler function implementing the 'content_get_raw' tool logic: fetches raw content from a single file or concatenates all .md files from a directory using environment variables CONTENT_SOURCE_TYPE and CONTENT_SOURCE_PATH.export const mcp_content_get_raw = async (args: { file_path?: string; }): Promise<ToolResult<{ content: string; source_info: string; total_files: number; size_bytes: number; last_modified: string; }>> => { try { const contentSourceType = process.env.CONTENT_SOURCE_TYPE || 'directory'; const contentSourcePath = process.env.CONTENT_SOURCE_PATH; if (!contentSourcePath) { return { success: false, error: 'CONTENT_SOURCE_PATH not configured' }; } if (contentSourceType === 'file') { // CASO 1: Archivo único - leer el archivo tal como está if (!await fs.pathExists(contentSourcePath)) { return { success: false, error: `File not found: ${contentSourcePath}` }; } const stat = await fs.stat(contentSourcePath); if (!stat.isFile()) { return { success: false, error: `Path is not a file: ${contentSourcePath}` }; } const content = await fs.readFile(contentSourcePath, 'utf-8'); return { success: true, data: { content: content, source_info: `Single file: ${contentSourcePath}`, total_files: 1, size_bytes: stat.size, last_modified: stat.mtime.toISOString() } }; } else { // CASO 2: Directorio - unir TODOS los archivos .md if (!await fs.pathExists(contentSourcePath)) { return { success: false, error: `Directory not found: ${contentSourcePath}` }; } const stat = await fs.stat(contentSourcePath); if (!stat.isDirectory()) { return { success: false, error: `Path is not a directory: ${contentSourcePath}` }; } // Buscar todos los archivos .md recursivamente const { globSync } = await import('glob'); const markdownFiles = globSync('**/*.md', { cwd: contentSourcePath, absolute: true, nodir: true }); if (markdownFiles.length === 0) { return { success: false, error: `No .md files found in directory: ${contentSourcePath}` }; } // Leer y concatenar todos los archivos .md let combinedContent = ''; let totalSize = 0; let latestModified = new Date(0); for (const filePath of markdownFiles) { const fileContent = await fs.readFile(filePath, 'utf-8'); const fileStat = await fs.stat(filePath); // Agregar separador y nombre del archivo const relativePath = path.relative(contentSourcePath, filePath); combinedContent += `\n\n<!-- ========== ARCHIVO: ${relativePath} ========== -->\n\n`; combinedContent += fileContent; totalSize += fileStat.size; if (fileStat.mtime > latestModified) { latestModified = fileStat.mtime; } } return { success: true, data: { content: combinedContent.trim(), source_info: `Combined ${markdownFiles.length} .md files from: ${contentSourcePath}`, total_files: markdownFiles.length, size_bytes: totalSize, last_modified: latestModified.toISOString() } }; } } catch (error: any) { return { success: false, error: `Failed to get raw content: ${error.message}` }; } };
- src/tools.ts:3-18 (schema)Defines the input schema, name, and description for the 'content_get_raw' tool in the MCP_CONTENT_TOOLS export used for tool discovery.export const MCP_CONTENT_TOOLS = [ { name: "content_get_raw", description: "Get raw markdown content without any processing. If source is a file, returns that file. If source is a directory, combines ALL .md files into one content with separators", inputSchema: { type: "object", properties: { file_path: { type: "string", description: "Not used - content source is determined by CONTENT_SOURCE_TYPE and CONTENT_SOURCE_PATH environment variables" } }, additionalProperties: false } } ];
- src/server.ts:62-65 (registration)Registers the ListToolsRequestSchema handler to return MCP_CONTENT_TOOLS, registering 'content_get_raw' for discovery by MCP clients.// @ts-ignore - Bypass TypeScript errors from the SDK's types server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: MCP_CONTENT_TOOLS }));
- src/server.ts:95-98 (registration)In the CallToolRequestSchema handler's switch statement, specifically dispatches to the mcp_content_get_raw handler for execution.case 'content_get_raw': logToFile(`[DEBUG] ✅ MATCH! Calling mcp_content_get_raw`); result = await toolHandlers.mcp_content_get_raw(input as any); logToFile(`[DEBUG] ✅ Result: ${JSON.stringify(result)}`);
- src/tools/types.ts:1-4 (helper)Defines the ToolResult type used for the return type of the handler (success/data or error).// Base types following MCPQL patterns export type ToolSuccessResult<T> = { success: true; data: T; }; export type ToolErrorResult = { success: false; error: string; }; export type ToolResult<T> = ToolSuccessResult<T> | ToolErrorResult;