Skip to content

Commit d532a58

Browse files
committed
Stream media file reads
1 parent 11a064c commit d532a58

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

src/filesystem/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ The server's directory access control follows this flow:
8181
- **read_media_file**
8282
- Read an image or audio file
8383
- Input: `path` (string)
84-
- Returns base64 data and MIME type based on the file extension
84+
- Streams the file and returns base64 data with the corresponding MIME type
8585

8686
- **read_multiple_files**
8787
- Read multiple files simultaneously

src/filesystem/index.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
type Root,
1111
} from "@modelcontextprotocol/sdk/types.js";
1212
import fs from "fs/promises";
13+
import { createReadStream } from "fs";
1314
import path from "path";
1415
import os from 'os';
1516
import { randomBytes } from 'crypto';
@@ -475,6 +476,21 @@ async function headFile(filePath: string, numLines: number): Promise<string> {
475476
}
476477
}
477478

479+
// Stream a file and return its Base64 representation without loading the
480+
// entire file into memory at once. Chunks are encoded individually and
481+
// concatenated into the final string.
482+
async function readFileAsBase64Stream(filePath: string): Promise<string> {
483+
return new Promise((resolve, reject) => {
484+
const stream = createReadStream(filePath, { encoding: 'base64' });
485+
let data = '';
486+
stream.on('data', (chunk) => {
487+
data += chunk;
488+
});
489+
stream.on('end', () => resolve(data));
490+
stream.on('error', (err) => reject(err));
491+
});
492+
}
493+
478494
// Tool handlers
479495
server.setRequestHandler(ListToolsRequestSchema, async () => {
480496
return {
@@ -663,7 +679,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
663679
".flac": "audio/flac",
664680
};
665681
const mimeType = mimeTypes[extension] || "application/octet-stream";
666-
const data = (await fs.readFile(validPath)).toString("base64");
682+
const data = await readFileAsBase64Stream(validPath);
667683
const type = mimeType.startsWith("image/")
668684
? "image"
669685
: mimeType.startsWith("audio/")

0 commit comments

Comments
 (0)