MCPcopy Create free account
hub / github.com/modelcontextprotocol/ext-apps / createServer

Function createServer

examples/pdf-server/server.ts:1273–2943  ·  view source on GitHub ↗
(options: CreateServerOptions = {})

Source from the content-addressed store, hash-verified

1271let cachedAppHtml: string | undefined;
1272
1273export function createServer(options: CreateServerOptions = {}): McpServer {
1274 const { enableInteract = false, useClientRoots = false } = options;
1275 const debug = options.debug ?? false;
1276 const disableInteract = !enableInteract;
1277 const server = new McpServer({ name: "PDF Server", version: "2.0.0" });
1278
1279 if (useClientRoots) {
1280 // Fetch roots on initialization and subscribe to changes
1281 server.server.oninitialized = () => {
1282 refreshRoots(server.server);
1283 };
1284 server.server.setNotificationHandler(
1285 RootsListChangedNotificationSchema,
1286 async () => {
1287 await refreshRoots(server.server);
1288 },
1289 );
1290 }
1291
1292 const { readPdfRange } = sharedPdfCache;
1293
1294 // Tool: list_pdfs - List available PDFs
1295 server.tool(
1296 "list_pdfs",
1297 "List available PDFs that can be displayed",
1298 {},
1299 async (): Promise<CallToolResult> => {
1300 const seen = new Set<string>();
1301 const localFiles: string[] = [];
1302 const addLocal = (filePath: string) => {
1303 const url = pathToFileUrl(filePath);
1304 if (seen.has(url)) return;
1305 seen.add(url);
1306 localFiles.push(url);
1307 };
1308
1309 // Explicitly registered files (CLI args + file roots)
1310 for (const filePath of allowedLocalFiles) addLocal(filePath);
1311
1312 // Walk directory roots for *.pdf files
1313 const WALK_MAX_DEPTH = 8;
1314 const WALK_MAX_FILES = 500;
1315 let truncated = false;
1316 const walk = async (dir: string, depth: number): Promise<void> => {
1317 if (depth > WALK_MAX_DEPTH || localFiles.length >= WALK_MAX_FILES) {
1318 truncated ||= localFiles.length >= WALK_MAX_FILES;
1319 return;
1320 }
1321 let entries;
1322 try {
1323 entries = await fs.promises.readdir(dir, { withFileTypes: true });
1324 } catch {
1325 return; // unreadable — skip silently
1326 }
1327 for (const e of entries) {
1328 if (localFiles.length >= WALK_MAX_FILES) {
1329 truncated = true;
1330 return;

Callers 2

server.test.tsFile · 0.90
connectFunction · 0.90

Calls 15

registerAppToolFunction · 0.90
registerAppResourceFunction · 0.90
refreshRootsFunction · 0.85
addLocalFunction · 0.85
walkFunction · 0.85
validateUrlFunction · 0.85
isArxivUrlFunction · 0.85
normalizeArxivUrlFunction · 0.85
readPdfRangeFunction · 0.85
touchViewFunction · 0.85
isFileUrlFunction · 0.85
isLocalPathFunction · 0.85

Tested by 1

connectFunction · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…