@fernforestgames/mcp-server-godot-docs 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +39 -0
  3. package/dist/config.d.ts +4 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +10 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/docs/fetcher.d.ts +18 -0
  8. package/dist/docs/fetcher.d.ts.map +1 -0
  9. package/dist/docs/fetcher.js +129 -0
  10. package/dist/docs/fetcher.js.map +1 -0
  11. package/dist/docs/format.d.ts +6 -0
  12. package/dist/docs/format.d.ts.map +1 -0
  13. package/dist/docs/format.js +153 -0
  14. package/dist/docs/format.js.map +1 -0
  15. package/dist/docs/index.d.ts +44 -0
  16. package/dist/docs/index.d.ts.map +1 -0
  17. package/dist/docs/index.js +99 -0
  18. package/dist/docs/index.js.map +1 -0
  19. package/dist/docs/parser.d.ts +6 -0
  20. package/dist/docs/parser.d.ts.map +1 -0
  21. package/dist/docs/parser.js +206 -0
  22. package/dist/docs/parser.js.map +1 -0
  23. package/dist/docs/search.d.ts +14 -0
  24. package/dist/docs/search.d.ts.map +1 -0
  25. package/dist/docs/search.js +195 -0
  26. package/dist/docs/search.js.map +1 -0
  27. package/dist/docs/types.d.ts +62 -0
  28. package/dist/docs/types.d.ts.map +1 -0
  29. package/dist/docs/types.js +3 -0
  30. package/dist/docs/types.js.map +1 -0
  31. package/dist/docs/version.d.ts +25 -0
  32. package/dist/docs/version.d.ts.map +1 -0
  33. package/dist/docs/version.js +76 -0
  34. package/dist/docs/version.js.map +1 -0
  35. package/dist/handlers/tools/get-class.d.ts +9 -0
  36. package/dist/handlers/tools/get-class.d.ts.map +1 -0
  37. package/dist/handlers/tools/get-class.js +52 -0
  38. package/dist/handlers/tools/get-class.js.map +1 -0
  39. package/dist/handlers/tools/search-docs.d.ts +10 -0
  40. package/dist/handlers/tools/search-docs.d.ts.map +1 -0
  41. package/dist/handlers/tools/search-docs.js +62 -0
  42. package/dist/handlers/tools/search-docs.js.map +1 -0
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +31 -0
  46. package/dist/index.js.map +1 -0
  47. package/package.json +52 -0
@@ -0,0 +1,52 @@
1
+ // MCP tool handler for getting full Godot class documentation
2
+ import { docsIndex } from '../../docs/index.js';
3
+ import { formatClassAsText } from '../../docs/format.js';
4
+ export async function getGodotClass({ className, }) {
5
+ try {
6
+ await docsIndex.ensureInitialized();
7
+ let godotClass = docsIndex.getClass(className);
8
+ // Try case-insensitive search if not found
9
+ if (!godotClass) {
10
+ const allClasses = docsIndex.getAllClassNames();
11
+ const match = allClasses.find(c => c.toLowerCase() === className.toLowerCase());
12
+ if (match) {
13
+ godotClass = docsIndex.getClass(match);
14
+ }
15
+ }
16
+ if (!godotClass) {
17
+ // Suggest similar classes
18
+ const allClasses = docsIndex.getAllClassNames();
19
+ const similar = allClasses
20
+ .filter(c => c.toLowerCase().includes(className.toLowerCase()) ||
21
+ className.toLowerCase().includes(c.toLowerCase().slice(0, 4)))
22
+ .slice(0, 5);
23
+ let errorMsg = `Class '${className}' not found.`;
24
+ if (similar.length > 0) {
25
+ errorMsg += ` Did you mean: ${similar.join(', ')}?`;
26
+ }
27
+ errorMsg += ' Use search_godot_docs to find the correct class name.';
28
+ return {
29
+ content: [{
30
+ type: "text",
31
+ text: errorMsg
32
+ }]
33
+ };
34
+ }
35
+ return {
36
+ content: [{
37
+ type: "text",
38
+ text: formatClassAsText(godotClass)
39
+ }]
40
+ };
41
+ }
42
+ catch (error) {
43
+ const message = error instanceof Error ? error.message : 'Unknown error';
44
+ return {
45
+ content: [{
46
+ type: "text",
47
+ text: `Failed to get class documentation: ${message}`
48
+ }]
49
+ };
50
+ }
51
+ }
52
+ //# sourceMappingURL=get-class.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-class.js","sourceRoot":"","sources":["../../../src/handlers/tools/get-class.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAClC,SAAS,GAGV;IACC,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,iBAAiB,EAAE,CAAC;QAEpC,IAAI,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAE/C,2CAA2C;QAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,UAAU,GAAG,SAAS,CAAC,gBAAgB,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;YAEhF,IAAI,KAAK,EAAE,CAAC;gBACV,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,0BAA0B;YAC1B,MAAM,UAAU,GAAG,SAAS,CAAC,gBAAgB,EAAE,CAAC;YAChD,MAAM,OAAO,GAAG,UAAU;iBACvB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;gBACjD,SAAS,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;iBAC1E,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAEf,IAAI,QAAQ,GAAG,UAAU,SAAS,cAAc,CAAC;YACjD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,QAAQ,IAAI,kBAAkB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;YACtD,CAAC;YACD,QAAQ,IAAI,wDAAwD,CAAC;YAErE,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,QAAQ;qBACf,CAAC;aACH,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,iBAAiB,CAAC,UAAU,CAAC;iBACpC,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,sCAAsC,OAAO,EAAE;iBACtD,CAAC;SACH,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare function searchGodotDocs({ query, limit, }: {
2
+ query: string;
3
+ limit?: number;
4
+ }): Promise<{
5
+ content: {
6
+ type: "text";
7
+ text: string;
8
+ }[];
9
+ }>;
10
+ //# sourceMappingURL=search-docs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-docs.d.ts","sourceRoot":"","sources":["../../../src/handlers/tools/search-docs.ts"],"names":[],"mappings":"AAuBA,wBAAsB,eAAe,CAAC,EACpC,KAAK,EACL,KAAU,GACX,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;;;GA2CA"}
@@ -0,0 +1,62 @@
1
+ // MCP tool handler for searching Godot documentation
2
+ import { searchDocs } from '../../docs/search.js';
3
+ /**
4
+ * Strip BBCode and clean up excerpt text
5
+ */
6
+ function cleanExcerpt(text) {
7
+ return text
8
+ .replace(/\[code\](.*?)\[\/code\]/g, '`$1`')
9
+ .replace(/\[codeblock\][\s\S]*?\[\/codeblock\]/g, '')
10
+ .replace(/\[param\s+(\w+)\]/g, '`$1`')
11
+ .replace(/\[method\s+(\w+)\]/g, '`$1()`')
12
+ .replace(/\[member\s+(\w+)\]/g, '`$1`')
13
+ .replace(/\[signal\s+(\w+)\]/g, '`$1`')
14
+ .replace(/\[constant\s+([^\]]+)\]/g, '`$1`')
15
+ .replace(/\[[^\]]+\]/g, '')
16
+ .replace(/\t+/g, ' ')
17
+ .replace(/\n+/g, ' ')
18
+ .replace(/\s+/g, ' ')
19
+ .trim()
20
+ .slice(0, 150);
21
+ }
22
+ export async function searchGodotDocs({ query, limit = 10, }) {
23
+ try {
24
+ const results = await searchDocs(query, limit);
25
+ if (results.length === 0) {
26
+ return {
27
+ content: [{
28
+ type: "text",
29
+ text: `No results found for "${query}".`
30
+ }]
31
+ };
32
+ }
33
+ // Format as compact text
34
+ const lines = [`Found ${results.length} result(s) for "${query}":\n`];
35
+ for (const r of results) {
36
+ const prefix = r.matchType === 'class' ? '' : `${r.className}.`;
37
+ const typeLabel = r.matchType.charAt(0).toUpperCase() + r.matchType.slice(1);
38
+ const excerpt = cleanExcerpt(r.excerpt);
39
+ lines.push(`[${typeLabel}] ${prefix}${r.name}`);
40
+ if (excerpt) {
41
+ lines.push(` ${excerpt}`);
42
+ }
43
+ lines.push('');
44
+ }
45
+ return {
46
+ content: [{
47
+ type: "text",
48
+ text: lines.join('\n').trim()
49
+ }]
50
+ };
51
+ }
52
+ catch (error) {
53
+ const message = error instanceof Error ? error.message : 'Unknown error';
54
+ return {
55
+ content: [{
56
+ type: "text",
57
+ text: `Failed to search documentation: ${message}`
58
+ }]
59
+ };
60
+ }
61
+ }
62
+ //# sourceMappingURL=search-docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-docs.js","sourceRoot":"","sources":["../../../src/handlers/tools/search-docs.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD;;GAEG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,IAAI;SACR,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC;SAC3C,OAAO,CAAC,uCAAuC,EAAE,EAAE,CAAC;SACpD,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC;SACrC,OAAO,CAAC,qBAAqB,EAAE,QAAQ,CAAC;SACxC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;SACtC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;SACtC,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC;SAC3C,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;SAC1B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE;SACN,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EACpC,KAAK,EACL,KAAK,GAAG,EAAE,GAIX;IACC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAE/C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,yBAAyB,KAAK,IAAI;qBACzC,CAAC;aACH,CAAC;QACJ,CAAC;QAED,yBAAyB;QACzB,MAAM,KAAK,GAAa,CAAC,SAAS,OAAO,CAAC,MAAM,mBAAmB,KAAK,MAAM,CAAC,CAAC;QAEhF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC;YAChE,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC7E,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAExC,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,KAAK,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAChD,IAAI,OAAO,EAAE,CAAC;gBACZ,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE;iBAC9B,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,mCAAmC,OAAO,EAAE;iBACnD,CAAC;SACH,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import "./config.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ import "./config.js"; // Validate configuration on startup
6
+ import { searchGodotDocs } from "./handlers/tools/search-docs.js";
7
+ import { getGodotClass } from "./handlers/tools/get-class.js";
8
+ const server = new McpServer({
9
+ name: "mcp-server-godot-docs",
10
+ version: "0.4.0",
11
+ });
12
+ // Documentation search tools
13
+ server.registerTool("search_godot_docs", {
14
+ title: "Search Godot Documentation",
15
+ description: "Search the Godot engine documentation for classes, methods, properties, signals, and constants. On first use, downloads docs matching your Godot version.",
16
+ inputSchema: {
17
+ query: z.string().describe("Search query (class name, method name, or keyword)"),
18
+ limit: z.number().default(10).describe("Maximum number of results to return")
19
+ }
20
+ }, searchGodotDocs);
21
+ server.registerTool("get_godot_class", {
22
+ title: "Get Godot Class Documentation",
23
+ description: "Get the full documentation for a specific Godot class, including all methods, properties, signals, and constants.",
24
+ inputSchema: {
25
+ className: z.string().describe("Exact class name (e.g., 'RigidBody3D', 'Node', 'Control')")
26
+ }
27
+ }, getGodotClass);
28
+ // Start receiving messages on stdin and sending messages on stdout
29
+ const transport = new StdioServerTransport();
30
+ await server.connect(transport);
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,aAAa,CAAC,CAAC,oCAAoC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,uBAAuB;IAC7B,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,6BAA6B;AAC7B,MAAM,CAAC,YAAY,CAAC,mBAAmB,EACrC;IACE,KAAK,EAAE,4BAA4B;IACnC,WAAW,EAAE,2JAA2J;IACxK,WAAW,EAAE;QACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QAChF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;KAC9E;CACF,EACD,eAAe,CAChB,CAAC;AAEF,MAAM,CAAC,YAAY,CAAC,iBAAiB,EACnC;IACE,KAAK,EAAE,+BAA+B;IACtC,WAAW,EAAE,mHAAmH;IAChI,WAAW,EAAE;QACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2DAA2D,CAAC;KAC5F;CACF,EACD,aAAa,CACd,CAAC;AAEF,mEAAmE;AACnE,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@fernforestgames/mcp-server-godot-docs",
3
+ "version": "0.1.0",
4
+ "description": "MCP server to help agents search Godot engine documentation",
5
+ "author": "Justin Spahr-Summers <justin@fernforestgames.com> (https://fernforestgames.com)",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/fernforestgames/mcp-server-godot-docs",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/fernforestgames/mcp-server-godot-docs.git"
11
+ },
12
+ "type": "module",
13
+ "scripts": {
14
+ "build": "tsc && shx chmod +x dist/*.js",
15
+ "dev": "tsx src/index.ts",
16
+ "start": "node dist/index.js",
17
+ "lint": "eslint src/**/*.ts"
18
+ },
19
+ "bin": {
20
+ "mcp-server-godot-docs": "dist/index.js"
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "keywords": [
26
+ "mcp",
27
+ "godot",
28
+ "documentation",
29
+ "typescript"
30
+ ],
31
+ "engines": {
32
+ "node": ">=22.0.0"
33
+ },
34
+ "dependencies": {
35
+ "@modelcontextprotocol/sdk": "^1.0.0",
36
+ "dotenv": "^17.2.3",
37
+ "env-paths": "^3.0.0",
38
+ "fast-xml-parser": "^5.3.3",
39
+ "tar": "^7.5.2"
40
+ },
41
+ "devDependencies": {
42
+ "@eslint/js": "^9.36.0",
43
+ "@types/node": "^24.5.2",
44
+ "@typescript-eslint/eslint-plugin": "^8.44.1",
45
+ "@typescript-eslint/parser": "^8.44.1",
46
+ "eslint": "^9.36.0",
47
+ "globals": "^16.4.0",
48
+ "shx": "^0.4.0",
49
+ "tsx": "^4.20.6",
50
+ "typescript": "^5.9.2"
51
+ }
52
+ }