check_file
Analyze text files for style and grammar issues using Vale's linting rules. Identifies problems with location details and severity levels to help improve writing quality.
Instructions
Lint a file at a specific path against Vale style rules. Returns issues found with their locations and severity. If Vale is not installed, returns error with installation guidance.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute or relative path to the file to check |
Implementation Reference
- src/vale-runner.ts:270-336 (handler)Core handler function that runs the Vale CLI on the specified file path, parses the JSON output, normalizes issues, generates a summary, formats the results as Markdown, and returns a CheckFileResult.export async function checkFile( filePath: string, configPath?: string ): Promise<CheckFileResult> { // Verify file exists and is readable (Fix #9: async file operations) try { await fs.access(filePath, fsSync.constants.R_OK); } catch { throw new Error(`File not found or not readable: ${filePath}`); } // Resolve to absolute path const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(process.cwd(), filePath); // Build Vale command let command = `vale --output=JSON`; // Only use --config if explicitly provided (e.g., from VALE_CONFIG_PATH env var) // Otherwise let Vale do its natural upward search from the file's location if (configPath) { command += ` --config="${configPath}"`; console.error(`Using explicit config: ${configPath}`); } else { console.error(`Letting Vale search for config from: ${path.dirname(absolutePath)}`); } command += ` "${absolutePath}"`; // Run Vale from the file's directory so it searches upward from there const execOptions: any = { encoding: 'utf-8', cwd: path.dirname(absolutePath) }; // Execute Vale let stdout = ""; try { const result = await execAsync(command, execOptions); stdout = typeof result.stdout === 'string' ? result.stdout : result.stdout.toString('utf-8'); } catch (error: any) { // Vale returns non-zero exit code when there are issues // But it still outputs JSON to stdout if (error.stdout) { stdout = error.stdout; } else { const errorMessage = error.stderr || error.message || "Unknown error"; throw new Error( `Vale execution failed: ${errorMessage}` ); } } // Parse output const rawOutput = parseValeOutput(stdout); const issues = normalizeIssues(rawOutput); const summary = generateSummary(issues); const formatted = formatValeResults(issues, summary, absolutePath); return { formatted, file: absolutePath, issues, summary, }; }
- src/index.ts:226-240 (registration)Registration of the 'check_file' tool in the MCP server's TOOLS array. Defines the tool name, description, and input schema requiring a 'path' parameter.{ name: "check_file", description: "Lint a file at a specific path against Vale style rules. Returns issues found with their locations and severity. If Vale is not installed, returns error with installation guidance.", inputSchema: { type: "object", properties: { path: { type: "string", description: "Absolute or relative path to the file to check", }, }, required: ["path"], }, },
- src/types.ts:56-61 (schema)TypeScript interface defining the output structure returned by the check_file tool handler.export interface CheckFileResult { formatted: string; file: string; issues: NormalizedValeIssue[]; summary: ValeSummary; }
- src/index.ts:340-383 (handler)MCP server request handler for executing the 'check_file' tool: extracts path argument, validates, checks Vale installation, invokes the core checkFile function, and constructs the MCP response.case "check_file": { const { path: filePath } = args as { path: string }; debug(`check_file called - path: ${filePath}`); if (!filePath) { return { content: [ { type: "text", text: JSON.stringify({ error: "Missing required parameter: path", }), }, ], }; } // Check if Vale is available const valeCheck = await checkValeInstalled(); if (!valeCheck.installed) { return createValeNotInstalledResponse(); } const result = await checkFile(filePath, valeConfigPath); debug(`check_file result - file: ${result.file}, issues found: ${result.issues.length}, errors: ${result.summary.errors}, warnings: ${result.summary.warnings}, suggestions: ${result.summary.suggestions}`); return { content: [ { type: "text", text: result.formatted, }, ], _meta: { structured_data: { file: result.file, issues: result.issues, summary: result.summary, }, }, }; }