readSheetNames
Retrieve all sheet names from an Excel file to identify available worksheets and navigate the workbook structure.
Instructions
Get all sheet names from the Excel file
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| fileAbsolutePath | Yes | The absolute path of the Excel file |
Implementation Reference
- src/handlers/excelHandlers.ts:6-31 (handler)Core handler function that reads sheet names from an Excel file. First checks cache via workbookCache.ensureWorkbook(); if not cached, calls readAndCacheFile() to read and parse the file, then returns the SheetNames array.
export async function readSheetNames(filePathWithName: string): Promise<string[]> { try { //从缓存中获取workbook const workbookResult: EnsureWorkbookResult = workbookCache.ensureWorkbook(filePathWithName); if (!workbookResult.success) { // 缓存中没有workbook,尝试读取并缓存文件 const readResult: ReadSheetNamesResult = await readAndCacheFile(filePathWithName); if (!readResult.success) { // 读取文件失败,返回错误信息 throw new Error(`read file failure: ${readResult.data.errors}`); } else { return readResult.data.SheetNames; } } else { const workbook = workbookResult.data as XLSX.WorkBook; return workbook.SheetNames } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); throw new Error(`read file failure: ${errorMessage}`); } - src/tools/readTools.ts:5-56 (registration)Registers the 'readSheetNames' tool on the MCP server with a Zod schema for fileAbsolutePath input. The handler validates the path, checks file existence, then calls readSheetNames() from handlers.
export const readTools = (server: any) => { server.tool("readSheetNames", 'Get all sheet names from the Excel file', { fileAbsolutePath: z.string().describe("The absolute path of the Excel file") }, async (params: { fileAbsolutePath: string }) => { try { const normalizedPath = await normalizePath(params.fileAbsolutePath); if (normalizedPath === 'error') { return { content: [{ type: "text", text: JSON.stringify({ error: `path is not valid: ${params.fileAbsolutePath}`, suggestion: "please check the path and filename" }) }] }; } if (!(await fileExists(normalizedPath))) { return { content: [{ type: "text", text: JSON.stringify({ error: `file is not exist: ${params.fileAbsolutePath}`, suggestion: "please check the path and filename" }) }] }; } const result = await readSheetNames(normalizedPath); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ error: `read sheet names failure: ${error}`, suggestion: "please check the path and filename" }) }] }; } } ); - src/types/index.ts:15-21 (schema)Type interface for ReadSheetNamesResult, containing success boolean and data object with SheetNames string array and errors string.
export interface ReadSheetNamesResult { success: boolean; data: { SheetNames: string[]; errors: string; }; } - src/utils/excelUtils.ts:9-71 (helper)Helper that reads an Excel file in chunks using fs.createReadStream, parses it with the 'xlsx' library, caches the workbook, and returns ReadSheetNamesResult with SheetNames.
export async function readAndCacheFile(filePathWithName: string): Promise<ReadSheetNamesResult> { try { const timeout = new Promise((_, reject) => { setTimeout(() => reject(new Error('File reading timeout')), READ_TIMEOUT); }); const readOperation = new Promise<ReadSheetNamesResult>(async (resolve, reject) => { try { // Read file in chunks const fileStream = fs.createReadStream(filePathWithName, { highWaterMark: 1024 * 1024 // 1MB chunks }); const chunks: Buffer[] = []; fileStream.on('data', (chunk: string | Buffer) => { if (Buffer.isBuffer(chunk)) { chunks.push(chunk); } else { chunks.push(Buffer.from(chunk)); } }); fileStream.on('end', () => { const buffer = Buffer.concat(chunks); const workbook = XLSX.read(buffer, { type: 'buffer', cellDates: true, cellNF: false, cellText: false, }); workbookCache.set(filePathWithName, workbook); resolve({ success: true, data: { SheetNames: workbook.SheetNames, errors: '' } }); }); fileStream.on('error', (error) => { reject(error); }); } catch (error) { reject(error); } }); const result = await Promise.race([readOperation, timeout]); return result as ReadSheetNamesResult; } catch (bufferError) { await logToFile(`[read-and-cache-file] Buffer read failure: ${bufferError}`); return { success: false, data: { SheetNames: [], errors: JSON.stringify(bufferError) } }; } }