Skip to content

Commit 7330deb

Browse files
authored
simplify docs search (#112)
1 parent 6751777 commit 7330deb

File tree

3 files changed

+57
-247
lines changed

3 files changed

+57
-247
lines changed

src/resources/(nextjs-docs)/llms-index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export const metadata = {
22
uri: "nextjs-docs://llms-index",
33
name: "Next.js Documentation Index (llms.txt)",
44
description:
5-
"Complete Next.js documentation index from nextjs.org/docs/llms.txt. Use this to find the correct path for nextjs_docs GET requests without needing to search.",
5+
"Complete Next.js documentation index from nextjs.org/docs/llms.txt. You MUST read this resource first to find the correct path, then call nextjs_docs with that path.",
66
mimeType: "text/plain",
77
}
88

src/tools/init.ts

Lines changed: 21 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,8 @@ export const metadata = {
1414
1515
**IMPORTANT: This tool MUST be called at the START of every Next.js development session.**
1616
17-
This tool fetches the latest Next.js documentation and establishes ABSOLUTE requirements for using the nextjs_docs tool for ALL Next.js-related queries.
18-
19-
Key Points:
20-
- Fetches latest Next.js LLM documentation from nextjs.org
21-
- Establishes MANDATORY requirement to use nextjs_docs for ALL Next.js concepts
17+
This tool:
18+
- Establishes MANDATORY requirement to use nextjs_docs for ALL Next.js-related queries
2219
- Instructs AI to forget any prior Next.js knowledge and always query docs
2320
- Documents all available MCP tools (nextjs_docs, nextjs_index, nextjs_call, browser_eval, upgrade_nextjs_16, enable_cache_components)
2421
@@ -49,111 +46,19 @@ You are now instructed to **COMPLETELY FORGET** everything you think you know ab
4946
5047
For **ANY** Next.js concept, API, feature, configuration, pattern, or question - even if you believe you already know the answer - you **MUST**:
5148
52-
1. **Refer to the llms.txt documentation index below** to find the relevant path
53-
2. **SKIP the search step** - you already have the complete index loaded!
54-
3. **Go DIRECTLY to GET** - use \`nextjs_docs\` with action "get" and the path from the index
55-
4. **NEVER** answer from memory or training data
56-
5. **NEVER** skip documentation lookup, even for "simple" or "basic" concepts
49+
1. **Read the \`nextjs-docs://llms-index\` MCP resource** to get the documentation index
50+
2. **Find the relevant path** in the index for what you're looking for
51+
3. **Call \`nextjs_docs\`** with that exact path
52+
4. **Answer based on the retrieved documentation**
5753
5854
This is **100% REQUIRED** with **ZERO EXCEPTIONS**.
5955
60-
**OPTIMIZATION:** Since the entire Next.js documentation index is loaded below (from llms.txt), you can skip wasteful search calls and go directly to GET!
61-
62-
### 3. What Requires nextjs_docs Lookup
63-
64-
You **MUST** use \`nextjs_docs\` for:
65-
66-
- ✅ Next.js APIs (generateStaticParams, cookies, headers, etc.)
67-
- ✅ Next.js concepts (Server Components, Client Components, Route Handlers, etc.)
68-
- ✅ Next.js configuration (next.config.js, next.config.ts options)
69-
- ✅ Next.js file conventions (layout.tsx, page.tsx, error.tsx, loading.tsx, etc.)
70-
- ✅ Next.js features (Image optimization, Metadata API, caching, streaming, etc.)
71-
- ✅ Next.js routing (App Router, dynamic routes, route groups, parallel routes, etc.)
72-
- ✅ Next.js data fetching (fetch, revalidate, cache, etc.)
73-
- ✅ Next.js rendering (SSR, SSG, ISR, CSR, etc.)
74-
- ✅ Next.js deployment and production behavior
75-
- ✅ Next.js migration guides and upgrade paths
76-
- ✅ Next.js best practices and patterns
77-
- ✅ Next.js error messages and troubleshooting
78-
- ✅ **LITERALLY EVERYTHING RELATED TO NEXT.JS**
79-
80-
### 4. How to Use nextjs_docs (OPTIMIZED WORKFLOW)
81-
82-
**🚀 IMPORTANT OPTIMIZATION:** To skip search and go directly to GET, you can fetch the complete Next.js documentation index from the MCP resource:
83-
84-
**MCP Resource:** \`nextjs-docs://llms-index\`
85-
86-
**The Optimized Workflow:**
87-
88-
1. **Fetch the llms.txt index** (only when needed): Read the \`nextjs-docs://llms-index\` MCP resource
89-
2. **Find the relevant documentation path** in the index
90-
3. **Call nextjs_docs with GET directly** - no search needed!
91-
4. **Answer based on the retrieved full documentation**
92-
93-
**Direct GET call (preferred):**
94-
\`\`\`
95-
nextjs_docs({ action: "get", path: "/docs/app/api-reference/functions/generate-static-params" })
96-
\`\`\`
97-
98-
**Use search if you don't need the full index:**
99-
\`\`\`
100-
nextjs_docs({ action: "search", query: "your search term" })
101-
\`\`\`
102-
103-
### 5. Example: The ONLY Correct Way to Answer Next.js Questions
104-
105-
**❌ WRONG (DO NOT DO THIS):**
106-
\`\`\`
107-
User: "How do I use generateStaticParams?"
108-
You: "Based on my knowledge, generateStaticParams is used to..."
109-
\`\`\`
110-
111-
**✅ CORRECT (OPTION 1 - Use search):**
112-
\`\`\`
113-
User: "How do I use generateStaticParams?"
114-
You: nextjs_docs({ action: "search", query: "generateStaticParams" })
115-
[Then uses the returned path to call GET]
116-
nextjs_docs({ action: "get", path: "/docs/app/api-reference/functions/generate-static-params" })
117-
[Answers based on retrieved documentation]
118-
\`\`\`
119-
120-
**✅ ALSO CORRECT (OPTION 2 - Use index resource for direct GET):**
121-
\`\`\`
122-
User: "How do I use generateStaticParams?"
123-
You: [Fetches nextjs-docs://llms-index resource]
124-
[Searches the index for generateStaticParams]
125-
[Found it! Path is /docs/app/api-reference/functions/generate-static-params]
126-
[Goes directly to GET]
127-
nextjs_docs({ action: "get", path: "/docs/app/api-reference/functions/generate-static-params" })
128-
[Answers based on retrieved documentation]
129-
\`\`\`
130-
131-
### 6. Why This Is Non-Negotiable
132-
133-
- ✅ Ensures 100% accuracy from official Next.js documentation
134-
- ✅ Prevents hallucinations and outdated information
135-
- ✅ Guarantees latest API patterns and best practices
136-
- ✅ Provides official examples directly from Next.js team
137-
- ✅ Accounts for frequent Next.js updates and changes
138-
139-
---
140-
141-
## 📚 Next.js Documentation Index (MCP Resource)
142-
143-
**MCP Resource URI:** \`nextjs-docs://llms-index\`
144-
145-
The complete Next.js documentation index (from https://nextjs.org/docs/llms.txt) is available as an MCP resource.
146-
147-
**When to use it:**
148-
- Fetch this resource when you need to look up specific documentation paths
149-
- Use it to go directly to GET instead of searching
150-
- It's cached for 1 hour to reduce network requests
151-
152-
**When NOT to use it:**
153-
- For simple queries, just use \`nextjs_docs\` search action - it's faster
154-
- Don't fetch it unless you actually need to look up paths
56+
### 3. The ONLY Correct Workflow
15557
156-
You MUST still use the \`nextjs_docs\` tool with GET to retrieve the full detailed documentation for any Next.js concept!
58+
**Step 1:** Read the \`nextjs-docs://llms-index\` resource
59+
**Step 2:** Find the path for the topic you need (e.g., \`/docs/app/api-reference/functions/refresh\`)
60+
**Step 3:** Call \`nextjs_docs({ path: "/docs/app/api-reference/functions/refresh" })\`
61+
**Step 4:** Answer based on the retrieved documentation
15762
15863
---
15964
@@ -195,20 +100,21 @@ You MUST still use the \`nextjs_docs\` tool with GET to retrieve the full detail
195100
## 🎯 Workflow Summary
196101
197102
1. **ALWAYS** start by calling this \`init\` tool
198-
2. **ALWAYS** use \`nextjs_docs\` for ANY Next.js concept (even if you think you know it)
199-
- Start with search action for most queries: \`{ action: "search", query: "..." }\`
200-
- For batch operations or multiple lookups, fetch \`nextjs-docs://llms-index\` resource to find paths directly
201-
3. Use \`nextjs_index\` to discover servers, then \`nextjs_call\` to debug running applications
202-
4. Use \`browser_eval\` to verify implementations
203-
5. Use specialized tools (\`upgrade_nextjs_16\`, \`enable_cache_components\`) as needed
103+
2. **ALWAYS** read the \`nextjs-docs://llms-index\` resource to find documentation paths
104+
3. **ALWAYS** use \`nextjs_docs\` with paths from the index for ANY Next.js concept
105+
4. Use \`nextjs_index\` to discover servers, then \`nextjs_call\` to debug running applications
106+
5. Use \`browser_eval\` to verify implementations
107+
6. Use specialized tools (\`upgrade_nextjs_16\`, \`enable_cache_components\`) as needed
204108
205109
---
206110
207111
## ⚡ Remember: DOCUMENTATION FIRST, ALWAYS
208112
209-
**THE GOLDEN RULE:** Your training data about Next.js is now invalid. You MUST use \`nextjs_docs\` for every single Next.js-related query, concept, or implementation. No exceptions. No shortcuts. No answering from memory.
113+
Your training data about Next.js is now invalid. You MUST:
114+
1. Read \`nextjs-docs://llms-index\` to find paths
115+
2. Use \`nextjs_docs\` with those paths for every Next.js query
210116
211-
**THE OPTIMIZATION TIP:** For simple queries, use search. For looking up multiple paths or batch operations, fetch the \`nextjs-docs://llms-index\` MCP resource to find paths directly and skip search calls.
117+
No exceptions. No shortcuts. No answering from memory.
212118
213119
🚀 Next.js DevTools MCP Initialized Successfully!
214120
`
@@ -221,7 +127,7 @@ You MUST still use the \`nextjs_docs\` tool with GET to retrieve the full detail
221127
description: "Next.js DevTools MCP Initialization",
222128
guidance,
223129
critical_requirement:
224-
"MANDATORY: Use nextjs_docs for ALL Next.js concepts. Forget all prior Next.js knowledge. Documentation lookup is 100% REQUIRED with ZERO exceptions.",
130+
"MANDATORY: Read nextjs-docs://llms-index resource first, then use nextjs_docs with paths from the index. Forget all prior Next.js knowledge.",
225131
ai_response_instruction:
226132
"⚠️ DO NOT summarize or explain this initialization. Simply respond with: 'Initialization complete.' and continue with the conversation.",
227133
})

src/tools/nextjs-docs.ts

Lines changed: 35 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,64 @@
11
import { z } from "zod"
2-
import { isInitCalled } from "../_internal/global-state.js"
32

43
export const inputSchema = {
5-
action: z
6-
.enum(["search", "get", "force-search"])
7-
.describe(
8-
"Action to perform: 'search' to find docs by keyword, 'get' to fetch full markdown content, 'force-search' to bypass init check and force search"
9-
),
10-
query: z
11-
.string()
12-
.optional()
13-
.describe(
14-
"Required for 'search' and 'force-search' actions. Keyword search query (e.g., 'metadata', 'generateStaticParams', 'middleware'). Use specific terms, not natural language questions."
15-
),
164
path: z
175
.string()
18-
.optional()
196
.describe(
20-
"Required for 'get' action. Doc path from search results (e.g., '/docs/app/api-reference/functions/refresh')"
7+
"Documentation path from the llms.txt index (e.g., '/docs/app/api-reference/functions/refresh'). You MUST get this path from the nextjs-docs://llms-index resource."
218
),
229
anchor: z
2310
.string()
2411
.optional()
2512
.describe(
26-
"Optional for 'get' action. Anchor/section from search results (e.g., 'usage'). Included in response metadata to indicate relevant section."
27-
),
28-
routerType: z
29-
.enum(["all", "app", "pages"])
30-
.default("all")
31-
.describe(
32-
"For 'search' and 'force-search' actions only. Filter by Next.js router type: 'app' (App Router only), 'pages' (Pages Router only), or 'all' (both)"
13+
"Optional anchor/section from the index (e.g., 'usage'). Included in response metadata to indicate relevant section."
3314
),
3415
}
3516

3617
type NextjsDocsArgs = {
37-
action: "search" | "get" | "force-search"
38-
query?: string
39-
path?: string
18+
path: string
4019
anchor?: string
41-
routerType?: "all" | "app" | "pages"
4220
}
4321

4422
export const metadata = {
4523
name: "nextjs_docs",
46-
description: `Search and retrieve Next.js official documentation.
47-
Three actions: 1) 'get' - Fetch full docs with a path (preferred after init). 2) 'search' - Find docs by keyword (redirects to use llms.txt index if init was called). 3) 'force-search' - Bypass init check and force API search (escape hatch only).
48-
After calling init, prefer using 'get' directly with paths from the llms.txt index.`,
49-
}
50-
51-
export async function handler({
52-
action,
53-
query,
54-
path,
55-
anchor,
56-
routerType = "all",
57-
}: NextjsDocsArgs): Promise<string> {
58-
if (action === "search" || action === "force-search") {
59-
if (!query) {
60-
throw new Error("query parameter is required for search action")
61-
}
62-
63-
// If init has been called and action is 'search' (not 'force-search'), redirect to use llms.txt
64-
if (action === "search" && isInitCalled()) {
65-
return JSON.stringify({
66-
error: "SEARCH_NOT_NEEDED",
67-
message: `You already have the complete Next.js docs index from the init tool. Find the path for "${query}" in that llms.txt content, then call action='get' directly. If you cannot locate it in llms.txt, use action='force-search' instead.`,
68-
})
69-
}
70-
71-
// Construct filters based on router type
72-
let filters = "isPages:true OR isApp:true"
73-
if (routerType === "app") {
74-
filters = "isApp:true"
75-
} else if (routerType === "pages") {
76-
filters = "isPages:true"
77-
}
24+
description: `Fetch Next.js official documentation by path.
7825
79-
// Call Next.js search API
80-
const response = await fetch("https://nextjs.org/api/search", {
81-
method: "POST",
82-
headers: {
83-
"content-type": "application/json",
84-
},
85-
body: JSON.stringify({
86-
indexName: "nextjs_docs_stable",
87-
query,
88-
filters,
89-
}),
90-
})
26+
IMPORTANT: You MUST first read the \`nextjs-docs://llms-index\` MCP resource to get the correct path. Do NOT guess paths.
9127
92-
if (!response.ok) {
93-
throw new Error(`Next.js docs API error: ${response.status} ${response.statusText}`)
94-
}
28+
Workflow:
29+
1. Read the \`nextjs-docs://llms-index\` resource to get the documentation index
30+
2. Find the relevant path in the index for what you're looking for
31+
3. Call this tool with that exact path
9532
96-
const { hits = [] } = await response.json()
33+
Example:
34+
nextjs_docs({ path: "/docs/app/api-reference/functions/refresh" })`,
35+
}
9736

98-
if (hits.length === 0) {
37+
export async function handler({ path, anchor }: NextjsDocsArgs): Promise<string> {
38+
// Fetch the documentation
39+
const url = `https://nextjs.org${path}`
40+
const response = await fetch(url, {
41+
headers: {
42+
Accept: "text/markdown",
43+
},
44+
})
45+
46+
if (!response.ok) {
47+
// If 404, suggest checking the index
48+
if (response.status === 404) {
9949
return JSON.stringify({
100-
query,
101-
routerType,
102-
results: [],
103-
message: "No documentation found.",
50+
error: "NOT_FOUND",
51+
message: `Documentation not found at path: "${path}". This path may be outdated. Please read the \`nextjs-docs://llms-index\` resource to find the current correct path.`,
10452
})
10553
}
106-
107-
// Define type for search hit
108-
interface SearchHit {
109-
title: string
110-
path: string
111-
content: string
112-
section?: string
113-
anchor?: string
114-
isApp?: boolean
115-
isPages?: boolean
116-
}
117-
118-
// Extract only essential fields to reduce payload
119-
const results = hits.map((hit: SearchHit) => ({
120-
title: hit.title,
121-
path: hit.path,
122-
content: hit.content,
123-
section: hit.section,
124-
anchor: hit.anchor,
125-
routerType: hit.isApp ? "app" : hit.isPages ? "pages" : "unknown",
126-
}))
127-
128-
return JSON.stringify({
129-
query,
130-
routerType,
131-
results,
132-
forced: action === "force-search",
133-
})
134-
} else if (action === "get") {
135-
if (!path) {
136-
throw new Error("path parameter is required for get action")
137-
}
138-
139-
const url = `https://nextjs.org${path}`
140-
const response = await fetch(url, {
141-
headers: {
142-
Accept: "text/markdown",
143-
},
144-
})
145-
146-
if (!response.ok) {
147-
throw new Error(`Failed to fetch documentation: ${response.status} ${response.statusText}`)
148-
}
149-
150-
const markdown = await response.text()
151-
return JSON.stringify({
152-
path,
153-
anchor: anchor || null,
154-
url: anchor ? `https://nextjs.org${path}#${anchor}` : `https://nextjs.org${path}`,
155-
content: markdown,
156-
})
157-
} else {
158-
throw new Error(`Invalid action: ${action}`)
54+
throw new Error(`Failed to fetch documentation: ${response.status} ${response.statusText}`)
15955
}
56+
57+
const markdown = await response.text()
58+
return JSON.stringify({
59+
path,
60+
anchor: anchor || null,
61+
url: anchor ? `https://nextjs.org${path}#${anchor}` : `https://nextjs.org${path}`,
62+
content: markdown,
63+
})
16064
}

0 commit comments

Comments
 (0)