Skip to main content
Glama

review.test-mapfile

Test and validate #@mapfile macros with security checks to ensure proper configuration and prevent unauthorized tags in Re:VIEW manuscripts.

Instructions

Test #@mapfile macro with security validation (developer tool)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cwdYes
fileYes

Implementation Reference

  • Primary handler case for the review.test-mapfile tool in the CallToolRequestSchema switch statement. Performs security validations and delegates to hybridCommands.testMapfile.
    case "review.test-mapfile": { const securityConfig = await loadSecurityConfig(args.cwd as string); const pathValidation = validateMapfilePath(args.file as string, securityConfig); if (!pathValidation.valid) { return { content: [ { type: "text", text: JSON.stringify({ success: false, error: `Security validation failed: ${pathValidation.reason}` }) } ] }; } const sizeValidation = await validateMapfileSize( args.file as string, args.cwd as string, securityConfig ); if (!sizeValidation.valid) { return { content: [ { type: "text", text: JSON.stringify({ success: false, error: `File size validation failed: ${sizeValidation.reason}` }) } ] }; } const result = await hybridCommands.testMapfile({ file: args.file as string, cwd: args.cwd as string }); return { content: [ { type: "text", text: JSON.stringify(result) } ] }; }
  • Tool schema definition, including name, description, and input schema. Part of the tools array returned by ListToolsRequestHandler.
    { name: "review.test-mapfile", description: "Test #@mapfile macro with security validation (developer tool)", inputSchema: { type: "object", properties: { cwd: { type: "string" }, file: { type: "string" } }, required: ["cwd", "file"] } },
  • Core implementation of the mapfile test: creates a temporary Re:VIEW file using the #@mapfile macro, preprocesses it, and returns the processed content.
    export async function testMapfileCommand(options: TestMapfileOptions) { const { file, cwd } = options; const testFile = path.join(cwd, "test-mapfile.re"); const testContent = `//list[test]{ #@mapfile(${file}) #@end //} `; try { await fs.writeFile(testFile, testContent, "utf-8"); const result = await preprocessCommand({ pattern: "test-mapfile.re", output: ".out", stats: true, cwd }); await fs.unlink(testFile).catch(() => {}); if (result.success) { const outputFile = path.join(cwd, ".out", "test-mapfile.re"); const processedContent = await fs.readFile(outputFile, "utf-8").catch(() => ""); return { success: true, processedContent, stats: result.stats }; } return result; } catch (error: any) { await fs.unlink(testFile).catch(() => {}); return { success: false, error: error.message }; } }
  • Security helper function validateMapfilePath used in the tool handler to check mapfile path against security policy.
    export function validateMapfilePath( filepath: string, config: SecurityConfig ): { valid: boolean; reason?: string } { if (config.blockAbsolutePaths && path.isAbsolute(filepath)) { return { valid: false, reason: "Absolute paths are not allowed" }; } if (config.blockTraversal && (filepath.includes("../") || filepath.includes("..\\"))) { return { valid: false, reason: "Path traversal is not allowed" }; } const ext = path.extname(filepath).toLowerCase(); if (config.allowedExtensions.length > 0 && !config.allowedExtensions.includes(ext)) { return { valid: false, reason: `File extension '${ext}' is not allowed. Allowed: ${config.allowedExtensions.join(", ")}` }; } const normalizedPath = filepath.replace(/\\/g, "/"); const isInAllowedPath = config.allowedPaths.length === 0 || config.allowedPaths.some(allowed => normalizedPath.startsWith(allowed)); if (!isInAllowedPath) { return { valid: false, reason: `Path must be within allowed directories: ${config.allowedPaths.join(", ")}` }; } return { valid: true }; }
  • Security helper function validateMapfileSize used in the tool handler to check mapfile size against security policy.
    export async function validateMapfileSize( filepath: string, cwd: string, config: SecurityConfig ): Promise<{ valid: boolean; reason?: string; size?: number }> { const fullPath = path.join(cwd, filepath); try { const stats = await fs.stat(fullPath); if (stats.size > config.maxFileSize) { return { valid: false, reason: `File size (${stats.size} bytes) exceeds maximum allowed size (${config.maxFileSize} bytes)`, size: stats.size }; } return { valid: true, size: stats.size }; } catch (error: any) { return { valid: false, reason: `Cannot access file: ${error.message}` }; } }

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/dsgarage/ReviewMCP'

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