search_documents
Find documents and folders in Dynalist by name to quickly access specific content using search queries and type filters.
Instructions
Search for documents and folders by name. Returns matching items with their ID, title, URL, and type.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Text to search for in document/folder names (case-insensitive) | |
| type | No | Filter by type: 'document', 'folder', or 'all' | all |
Implementation Reference
- src/tools/index.ts:202-231 (handler)Executes the search_documents tool: fetches all files via client.listFiles(), filters by query (case-insensitive title match) and optional type, maps to structured output with ID, title, type, URL (for docs), permission, children (for folders), and returns as JSON text content.async ({ query, type }) => { const response = await client.listFiles(); const queryLower = query.toLowerCase(); const matches = response.files .filter((f) => { const nameMatch = f.title?.toLowerCase().includes(queryLower); const typeMatch = type === "all" || f.type === type; return nameMatch && typeMatch; }) .map((f) => ({ id: f.id, title: f.title, type: f.type, url: f.type === "document" ? buildDynalistUrl(f.id) : undefined, permission: f.type === "document" ? getPermissionLabel(f.permission) : undefined, children: f.type === "folder" ? f.children : undefined, })); return { content: [ { type: "text", text: matches.length > 0 ? JSON.stringify(matches, null, 2) : `No ${type === "all" ? "documents or folders" : type + "s"} found matching "${query}"`, }, ], }; }
- src/tools/index.ts:198-201 (schema)Zod schema defining input parameters: query (string, required), type (enum: all/document/folder, optional default 'all').{ query: z.string().describe("Text to search for in document/folder names (case-insensitive)"), type: z.enum(["all", "document", "folder"]).optional().default("all").describe("Filter by type: 'document', 'folder', or 'all'"), },
- src/tools/index.ts:195-232 (registration)Registers the search_documents tool on the MCP server using server.tool(), including name, description, input schema, and inline handler function.server.tool( "search_documents", "Search for documents and folders by name. Returns matching items with their ID, title, URL, and type.", { query: z.string().describe("Text to search for in document/folder names (case-insensitive)"), type: z.enum(["all", "document", "folder"]).optional().default("all").describe("Filter by type: 'document', 'folder', or 'all'"), }, async ({ query, type }) => { const response = await client.listFiles(); const queryLower = query.toLowerCase(); const matches = response.files .filter((f) => { const nameMatch = f.title?.toLowerCase().includes(queryLower); const typeMatch = type === "all" || f.type === type; return nameMatch && typeMatch; }) .map((f) => ({ id: f.id, title: f.title, type: f.type, url: f.type === "document" ? buildDynalistUrl(f.id) : undefined, permission: f.type === "document" ? getPermissionLabel(f.permission) : undefined, children: f.type === "folder" ? f.children : undefined, })); return { content: [ { type: "text", text: matches.length > 0 ? JSON.stringify(matches, null, 2) : `No ${type === "all" ? "documents or folders" : type + "s"} found matching "${query}"`, }, ], }; } );
- src/tools/index.ts:999-1014 (helper)Helper function used in the handler to convert numeric permission to readable label (none/read/edit/manage/owner).function getPermissionLabel(permission: number): string { switch (permission) { case 0: return "none"; case 1: return "read"; case 2: return "edit"; case 3: return "manage"; case 4: return "owner"; default: return "unknown"; } }