@@ -42,10 +42,11 @@ server.tool(
4242 {
4343 name : "search_docs" ,
4444 description :
45- "Search through indexed documentation libraries for relevant information. " +
46- "Returns ranked documentation sections with code examples and source URLs. " +
47- "Use this when you need to find information about a library, framework, API, " +
48- "or any technical concept." ,
45+ "Search indexed docs by keyword or library. Returns ranked sections with URLs." ,
46+ annotations : {
47+ readOnlyHint : true ,
48+ idempotentHint : true ,
49+ } ,
4950 schema : v . object ( {
5051 query : v . pipe (
5152 v . string ( ) ,
@@ -61,11 +62,16 @@ server.tool(
6162 } ) ,
6263 } ,
6364 async ( { query, library, limit } ) => {
64- const results = searchEngine . search ( query , { library, limit } ) ;
65- if ( results . length === 0 )
66- return tool . text ( `No results found for "${ query } ".` ) ;
65+ try {
66+ const results = searchEngine . search ( query , { library, limit } ) ;
67+ if ( results . length === 0 )
68+ return tool . text ( `No results found for "${ query } ".` ) ;
6769
68- return tool . text ( formatSearchResults ( query , results ) ) ;
70+ return tool . text ( formatSearchResults ( query , results ) ) ;
71+ } catch ( err : unknown ) {
72+ const message = err instanceof Error ? err . message : "Search failed" ;
73+ return tool . text ( `❌ Error: ${ message } ` ) ;
74+ }
6975 } ,
7076) ;
7177
@@ -108,14 +114,16 @@ function formatLibraryInfo(libraryId: string): string {
108114}
109115
110116// ──────────────────────────────────────
111- // Tool 2: list_libraries — Discovery tool
117+ // Tool 2: list_libraries — Discovery tool with pagination
112118// ──────────────────────────────────────
113119server . tool (
114120 {
115121 name : "list_libraries" ,
116- description :
117- "List all documentation libraries currently indexed and available for searching. " +
118- "Use this to discover what docs are available before running search_docs." ,
122+ description : "List indexed documentation libraries. Paginated results." ,
123+ annotations : {
124+ readOnlyHint : true ,
125+ idempotentHint : true ,
126+ } ,
119127 schema : v . object ( {
120128 status : v . optional (
121129 v . pipe (
@@ -124,23 +132,46 @@ server.tool(
124132 ) ,
125133 "all" ,
126134 ) ,
135+ page : v . optional ( v . pipe ( v . number ( ) , v . integer ( ) , v . minValue ( 1 ) ) , 1 ) ,
136+ limit : v . optional (
137+ v . pipe ( v . number ( ) , v . integer ( ) , v . minValue ( 1 ) , v . maxValue ( 50 ) ) ,
138+ 20 ,
139+ ) ,
127140 } ) ,
128141 } ,
129- async ( { status } ) => {
130- const libraries = db . listLibraries ( status ) ;
131- if ( libraries . length === 0 ) {
132- return tool . text (
133- "No libraries indexed yet. Use manage_library with action=add to add a documentation website." ,
134- ) ;
135- }
142+ async ( { status, page = 1 , limit = 20 } ) => {
143+ try {
144+ const libraries = db . listLibraries ( status ) ;
145+ if ( libraries . length === 0 ) {
146+ return tool . text (
147+ "No libraries indexed yet. Use manage_library with action=add to add a documentation website." ,
148+ ) ;
149+ }
136150
137- let output = `## Indexed Libraries (${ libraries . length } total)\n\n` ;
138- output += "| Library | URL | Pages | Chunks | Status |\n" ;
139- output += "| ------- | --- | ----- | ------ | ------ |\n" ;
140- for ( const lib of libraries ) {
141- output += `| ${ lib . name } | ${ lib . url } | ${ lib . page_count } | ${ lib . chunk_count } | ${ lib . status } |\n` ;
151+ // Paginate results
152+ const start = ( page - 1 ) * limit ;
153+ const end = start + limit ;
154+ const paginated = libraries . slice ( start , end ) ;
155+ const hasMore = end < libraries . length ;
156+
157+ // Minified response (no pretty-printing)
158+ let output = `## Libraries (${ start + 1 } -${ Math . min ( end , libraries . length ) } of ${ libraries . length } )\n\n` ;
159+ output += "| Library | URL | Pages | Chunks | Status |\n" ;
160+ output += "| ------- | --- | ----- | ------ | ------ |\n" ;
161+ for ( const lib of paginated ) {
162+ output += `|${ lib . name } |${ lib . url } |${ lib . page_count } |${ lib . chunk_count } |${ lib . status } |\n` ;
163+ }
164+
165+ if ( hasMore ) {
166+ output += `\n**More available.** Use page=${ page + 1 } to fetch next page.` ;
167+ }
168+
169+ return tool . text ( output ) ;
170+ } catch ( err : unknown ) {
171+ const message =
172+ err instanceof Error ? err . message : "Failed to list libraries" ;
173+ return tool . text ( `❌ Error: ${ message } ` ) ;
142174 }
143- return tool . text ( output ) ;
144175 } ,
145176) ;
146177
@@ -150,9 +181,11 @@ server.tool(
150181server . tool (
151182 {
152183 name : "get_doc_page" ,
153- description :
154- "Retrieve the complete content of a specific documentation page as markdown. " +
155- "Use when search results reference a page and you need full context." ,
184+ description : "Retrieve complete documentation page as markdown." ,
185+ annotations : {
186+ readOnlyHint : true ,
187+ idempotentHint : true ,
188+ } ,
156189 schema : v . object ( {
157190 url : v . optional (
158191 v . pipe (
@@ -169,14 +202,20 @@ server.tool(
169202 } ) ,
170203 } ,
171204 async ( { url, library, path } ) => {
172- const page = db . getPage ( { url, library, path } ) ;
173- if ( ! page )
205+ try {
206+ const page = db . getPage ( { url, library, path } ) ;
207+ if ( ! page )
208+ return tool . text (
209+ "Page not found. Use search_docs to find the correct page." ,
210+ ) ;
174211 return tool . text (
175- "Page not found. Use search_docs to find the correct page." ,
212+ `# ${ page . title } \n**Source:** ${ page . url } \n\n ${ page . content_markdown } ` ,
176213 ) ;
177- return tool . text (
178- `# ${ page . title } \n**Source:** ${ page . url } \n\n${ page . content_markdown } ` ,
179- ) ;
214+ } catch ( err : unknown ) {
215+ const message =
216+ err instanceof Error ? err . message : "Failed to fetch page" ;
217+ return tool . text ( `❌ Error: ${ message } ` ) ;
218+ }
180219 } ,
181220) ;
182221
@@ -187,7 +226,10 @@ server.tool(
187226 {
188227 name : "manage_library" ,
189228 description :
190- "Manage a documentation library lifecycle. Use action=add to crawl a new source, action=rename to change the library name, action=refresh to re-crawl, action=remove to delete it, or action=info to inspect its pages and stats." ,
229+ "Manage library lifecycle: add/rename/refresh/remove/info. Destructive actions require confirmation." ,
230+ annotations : {
231+ destructiveHint : true ,
232+ } ,
191233 schema : v . object ( {
192234 action : v . pipe (
193235 v . picklist ( [ "add" , "rename" , "refresh" , "remove" , "info" ] ) ,
@@ -268,7 +310,7 @@ server.tool(
268310 const lib = db . getLibraryByName ( libraryName ) ;
269311 if ( ! lib )
270312 return tool . text (
271- `Library "${ libraryName } " not found. Use list_libraries to see available.` ,
313+ `❌ Library "${ libraryName } " not found. Use list_libraries to see available.` ,
272314 ) ;
273315
274316 const job = jobManager . startCrawl ( lib . id , { incremental : true } ) ;
@@ -282,7 +324,7 @@ server.tool(
282324 "library is required for action=remove." ,
283325 ) ;
284326 const lib = db . getLibraryByName ( libraryName ) ;
285- if ( ! lib ) return tool . text ( `Library "${ libraryName } " not found.` ) ;
327+ if ( ! lib ) return tool . text ( `❌ Library "${ libraryName } " not found.` ) ;
286328
287329 db . removeLibrary ( lib . id ) ;
288330 return tool . text (
@@ -297,17 +339,17 @@ server.tool(
297339 const lib = db . getLibraryByName ( libraryName ) ;
298340 if ( ! lib )
299341 return tool . text (
300- `Library "${ libraryName } " not found. Use list_libraries to see available libraries.` ,
342+ `❌ Library "${ libraryName } " not found. Use list_libraries to see available libraries.` ,
301343 ) ;
302344
303345 return tool . text ( formatLibraryInfo ( lib . id ) ) ;
304346 }
305347 }
306348 } catch ( err : unknown ) {
307349 const message = err instanceof Error ? err . message : "Unknown error" ;
308- return tool . text ( `❌ Failed : ${ message } ` ) ;
350+ return tool . text ( `❌ Error : ${ message } ` ) ;
309351 }
310352
311- return tool . text ( `❌ Failed : Unsupported action.` ) ;
353+ return tool . text ( `❌ Error : Unsupported action.` ) ;
312354 } ,
313355) ;
0 commit comments