Skip to content

Commit 3186b50

Browse files
committed
Implement search function
1 parent 29d2f7f commit 3186b50

File tree

1 file changed

+50
-6
lines changed
  • packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/mcp

1 file changed

+50
-6
lines changed

packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/mcp/route.ts

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,67 @@
11
import { type RouteLayoutParams, getStaticSiteContext } from '@/app/utils';
2+
import { throwIfDataError } from '@/lib/data';
3+
import { joinPathWithBaseURL } from '@/lib/paths';
4+
import { findSiteSpaceBy } from '@/lib/sites';
25
import { createMcpHandler } from 'mcp-handler';
36
import type { NextRequest } from 'next/server';
47
import { z } from 'zod';
58

69
async function handler(request: NextRequest, { params }: { params: Promise<RouteLayoutParams> }) {
710
const { context } = await getStaticSiteContext(await params);
11+
const { dataFetcher, linker, site } = context;
812

913
const mcpHandler = createMcpHandler(
1014
(server) => {
1115
server.tool(
12-
'roll_dice',
13-
'Rolls an N-sided die',
16+
'searchDocumentation',
17+
`Search across the documentation to find relevant information, code examples, API references, and guides. Use this tool when you need to answer questions about ${site.title}, find specific documentation, understand how features work, or locate implementation details. The search returns contextual content with titles and direct links to the documentation pages.`,
1418
{
15-
sides: z.number().int().min(2),
19+
query: z.string(),
1620
},
17-
async ({ sides }) => {
18-
const value = 1 + Math.floor(Math.random() * sides);
21+
async ({ query }) => {
22+
const results = await throwIfDataError(
23+
dataFetcher.searchSiteContent({
24+
organizationId: context.organizationId,
25+
siteId: site.id,
26+
query,
27+
scope: { mode: 'all' },
28+
})
29+
);
30+
1931
return {
20-
content: [{ type: 'text', text: `🎲 You rolled a ${value}!` }],
32+
content: results.flatMap((spaceResult) => {
33+
const found = findSiteSpaceBy(
34+
context.structure,
35+
(siteSpace) => siteSpace.space.id === spaceResult.id
36+
);
37+
const spaceURL = found?.siteSpace.urls.published;
38+
if (!spaceURL) {
39+
return [];
40+
}
41+
42+
return spaceResult.pages.map((pageResult) => {
43+
const pageURL = linker.toAbsoluteURL(
44+
linker.toLinkForContent(
45+
joinPathWithBaseURL(spaceURL, pageResult.path)
46+
)
47+
);
48+
49+
const body = pageResult.sections
50+
?.map((section) => section.body)
51+
.join('\n');
52+
53+
return {
54+
type: 'text',
55+
text: [
56+
`Title: ${pageResult.title}`,
57+
`Link: ${pageURL}`,
58+
body ? `Content: ${body}` : '',
59+
]
60+
.filter(Boolean)
61+
.join('\n'),
62+
};
63+
});
64+
}),
2165
};
2266
}
2367
);

0 commit comments

Comments
 (0)