Skip to content

Commit f8286f2

Browse files
committed
Update index.ts
Fix remaining issues
1 parent 3153d15 commit f8286f2

1 file changed

Lines changed: 185 additions & 101 deletions

File tree

src/index.ts

Lines changed: 185 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,122 +1,210 @@
1-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
22
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3-
import { z } from "zod";
4-
import { ensureDocs, updateDocs, getDocsDir, initLocalDocs } from './cache.js';
3+
import {
4+
CallToolRequestSchema,
5+
ListToolsRequestSchema,
6+
ListResourcesRequestSchema,
7+
ReadResourceRequestSchema
8+
} from "@modelcontextprotocol/sdk/types.js";
9+
import { ensureDocs, updateDocs, initLocalDocs } from './cache.js';
510
import { searchDocs } from './tools/search.js';
611
import { readDoc } from './tools/read.js';
712
import { handleDocsResource } from './resources/docs.js';
813
import path from 'path';
914
import fs from 'fs';
10-
import { fileURLToPath } from 'url';
1115

12-
// Initialize server
13-
export const server = new McpServer({
14-
name: "baritone-docs-mcp",
15-
version: "1.0.0",
16-
});
17-
18-
// -- Tools --
19-
20-
// Tool: Refresh Docs
21-
server.tool(
22-
"baritone_refresh_docs",
23-
"Download and update the local documentation cache from the GitHub repository.",
16+
// Tool definitions
17+
const TOOLS = [
18+
{
19+
name: "baritone_refresh_docs",
20+
description: "Download and update the local documentation cache from the GitHub repository.",
21+
inputSchema: {
22+
type: "object",
23+
properties: {
24+
force: {
25+
type: "boolean",
26+
description: "Force re-download even if cache exists"
27+
}
28+
}
29+
}
30+
},
2431
{
25-
force: z.boolean().optional().describe("Force re-download even if cache exists")
32+
name: "baritone_search_docs",
33+
description: "Search the Baritone documentation for a specific query.",
34+
inputSchema: {
35+
type: "object",
36+
properties: {
37+
query: {
38+
type: "string",
39+
description: "The search query (e.g., 'GoalBlock', 'pathing')"
40+
}
41+
},
42+
required: ["query"]
43+
}
2644
},
27-
async ({ force }) => {
28-
try {
29-
await updateDocs();
30-
return {
31-
content: [{ type: "text", text: "Documentation updated successfully." }]
32-
};
33-
} catch (err: any) {
34-
return {
35-
content: [{ type: "text", text: `Failed to update docs: ${err.message}` }],
36-
isError: true
37-
};
45+
{
46+
name: "baritone_read_doc",
47+
description: "Read the full content of a specific documentation file.",
48+
inputSchema: {
49+
type: "object",
50+
properties: {
51+
path: {
52+
type: "string",
53+
description: "The relative path to the file (as returned by search results)"
54+
}
55+
},
56+
required: ["path"]
3857
}
3958
}
40-
);
59+
];
4160

42-
// Tool: Search Docs
43-
server.tool(
44-
"baritone_search_docs",
45-
"Search the Baritone documentation for a specific query.",
61+
// Resource definitions
62+
const RESOURCES = [
4663
{
47-
query: z.string().describe("The search query (e.g., 'GoalBlock', 'pathing')")
64+
uri: "docs://{path}",
65+
name: "Baritone Documentation",
66+
description: "Access Baritone documentation files",
67+
mimeType: "text/markdown"
68+
}
69+
];
70+
71+
// Initialize server
72+
export const server = new Server(
73+
{
74+
name: "baritone-docs-mcp",
75+
version: "1.0.0",
4876
},
49-
async ({ query }) => {
50-
if (!ensureDocs()) {
51-
return {
52-
content: [{ type: "text", text: "Documentation not found. Please run baritone_refresh_docs first." }],
53-
isError: true
54-
};
77+
{
78+
capabilities: {
79+
tools: {},
80+
resources: {}
5581
}
82+
}
83+
);
5684

57-
const results = await searchDocs(query);
85+
// -- Request Handlers --
5886

59-
if (results.length === 0) {
60-
return {
61-
content: [{ type: "text", text: "No results found." }]
62-
};
63-
}
87+
// List available tools
88+
server.setRequestHandler(ListToolsRequestSchema, async () => {
89+
return { tools: TOOLS };
90+
});
6491

65-
const text = results.map(r =>
66-
`### [${r.file.name}](${r.file.path})\n` +
67-
`**Score**: ${r.score}\n` +
68-
`**Matches**: \n${r.matches?.map(m => `> ${m}`).join('\n')}\n`
69-
).join('\n---\n');
92+
// Handle tool calls
93+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
94+
const { name, arguments: args } = request.params;
95+
96+
try {
97+
switch (name) {
98+
case "baritone_refresh_docs": {
99+
try {
100+
await updateDocs();
101+
return {
102+
content: [{ type: "text", text: "Documentation updated successfully." }]
103+
};
104+
} catch (err: any) {
105+
return {
106+
content: [{ type: "text", text: `Failed to update docs: ${err.message}` }],
107+
isError: true
108+
};
109+
}
110+
}
70111

71-
return {
72-
content: [{ type: "text", text }]
73-
};
74-
}
75-
);
112+
case "baritone_search_docs": {
113+
const query = (args as any)?.query;
114+
115+
if (!query) {
116+
return {
117+
content: [{ type: "text", text: "Query parameter is required." }],
118+
isError: true
119+
};
120+
}
121+
122+
if (!ensureDocs()) {
123+
return {
124+
content: [{ type: "text", text: "Documentation not found. Please run baritone_refresh_docs first." }],
125+
isError: true
126+
};
127+
}
128+
129+
const results = await searchDocs(query);
130+
131+
if (results.length === 0) {
132+
return {
133+
content: [{ type: "text", text: "No results found." }]
134+
};
135+
}
136+
137+
const text = results.map(r =>
138+
`### [${r.file.name}](${r.file.path})\n` +
139+
`**Score**: ${r.score}\n` +
140+
`**Matches**: \n${r.matches?.map(m => `> ${m}`).join('\n')}\n`
141+
).join('\n---\n');
76142

77-
// Tool: Read Doc
78-
server.tool(
79-
"baritone_read_doc",
80-
"Read the full content of a specific documentation file.",
81-
{
82-
path: z.string().describe("The relative path to the file (as returned by search results)")
83-
},
84-
async ({ path }) => {
85-
if (!ensureDocs()) {
86-
return {
87-
content: [{ type: "text", text: "Documentation not found. Please run baritone_refresh_docs first." }],
88-
isError: true
89-
};
90-
}
143+
return {
144+
content: [{ type: "text", text }]
145+
};
146+
}
91147

92-
try {
93-
const content = readDoc(path);
94-
if (content === null) {
148+
case "baritone_read_doc": {
149+
const docPath = (args as any)?.path;
150+
151+
if (!docPath) {
152+
return {
153+
content: [{ type: "text", text: "Path parameter is required." }],
154+
isError: true
155+
};
156+
}
157+
158+
if (!ensureDocs()) {
159+
return {
160+
content: [{ type: "text", text: "Documentation not found. Please run baritone_refresh_docs first." }],
161+
isError: true
162+
};
163+
}
164+
165+
try {
166+
const content = readDoc(docPath);
167+
if (content === null) {
168+
return {
169+
content: [{ type: "text", text: "File not found." }],
170+
isError: true
171+
};
172+
}
173+
return {
174+
content: [{ type: "text", text: content }]
175+
};
176+
} catch (err: any) {
177+
return {
178+
content: [{ type: "text", text: `Error reading file: ${err.message}` }],
179+
isError: true
180+
};
181+
}
182+
}
183+
184+
default:
95185
return {
96-
content: [{ type: "text", text: "File not found." }],
186+
content: [{ type: "text", text: `Unknown tool: ${name}` }],
97187
isError: true
98188
};
99-
}
100-
return {
101-
content: [{ type: "text", text: content }]
102-
};
103-
} catch (err: any) {
104-
return {
105-
content: [{ type: "text", text: `Error reading file: ${err.message}` }],
106-
isError: true
107-
};
108189
}
190+
} catch (error: any) {
191+
return {
192+
content: [{ type: "text", text: `Error: ${error.message}` }],
193+
isError: true
194+
};
109195
}
110-
);
196+
});
111197

112-
// Resource: Docs
113-
server.resource(
114-
"docs",
115-
"docs://{path}",
116-
async (uri) => {
117-
return handleDocsResource(uri);
118-
}
119-
);
198+
// List available resources
199+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
200+
return { resources: RESOURCES };
201+
});
202+
203+
// Handle resource reads
204+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
205+
const uri = new URL(request.params.uri);
206+
return handleDocsResource(uri);
207+
});
120208

121209
// -- Setup --
122210

@@ -140,12 +228,8 @@ export async function main() {
140228
await server.connect(transport);
141229
}
142230

143-
// Only run main if executed directly (ESM entry point check)
144-
const isMainModule = import.meta.url === `file://${process.argv[1]}` ||
145-
import.meta.url.endsWith(process.argv[1]);
146-
147-
if (isMainModule) {
148-
main().catch((error) => {
149-
process.exit(1);
150-
});
151-
}
231+
// Start the MCP server
232+
main().catch((error) => {
233+
console.error('Fatal error:', error);
234+
process.exit(1);
235+
});

0 commit comments

Comments
 (0)