al-go-mcp-server 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Job Louage
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # AL-Go MCP Server
2
+
3
+ A Model Context Protocol (MCP) server for accessing AL-Go documentation and workflows from the `microsoft/AL-Go` repository.
4
+
5
+ ## Features
6
+ - Search and access AL-Go documentation and workflows
7
+ - Works with public GitHub API (no token required for public repos)
8
+ - Optional: Use a GitHub token for higher rate limits
9
+ - Can be run via `npx` and configured in `.vscode/mcp.json`
10
+
11
+ ## Usage
12
+
13
+ ### 1. As a local or global npm package
14
+
15
+ ```
16
+ npx al-go-mcp-server
17
+ ```
18
+
19
+ ### 2. In `.vscode/mcp.json`
20
+
21
+ ```json
22
+ {
23
+ "servers": {
24
+ "al-go-docs": {
25
+ "type": "stdio",
26
+ "command": "npx",
27
+ "args": ["al-go-mcp-server"],
28
+ "env": {
29
+ "GITHUB_TOKEN": "your_token_here" // Optional
30
+ }
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ ## Development
37
+
38
+ - Clone the repo
39
+ - Run `npm install`
40
+ - Run `npm run build`
41
+ - Run `npm start` or `npx tsx src/index.ts`
42
+
43
+ ## License
44
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/build/index.js ADDED
@@ -0,0 +1,198 @@
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 { AlGoService } from "./services/AlGoService.js";
6
+ import { DocumentIndex } from "./services/DocumentIndex.js";
7
+ /**
8
+ * AL-Go Documentation MCP Server
9
+ *
10
+ * This server provides access to AL-Go documentation through MCP protocol.
11
+ * It fetches documentation from the microsoft/AL-Go repository and provides
12
+ * search capabilities for AL-Go specific queries.
13
+ */
14
+ // Initialize the MCP server
15
+ const server = new McpServer({
16
+ name: "al-go-mcp-server",
17
+ version: "1.0.0"
18
+ });
19
+ // Initialize services
20
+ const alGoService = new AlGoService();
21
+ const documentIndex = new DocumentIndex();
22
+ // Resource: Get AL-Go repository information
23
+ server.registerResource("al-go-repo-info", "al-go://repo/info", {
24
+ title: "AL-Go Repository Information",
25
+ description: "Basic information about the AL-Go repository",
26
+ mimeType: "application/json"
27
+ }, async (uri) => {
28
+ const repoInfo = await alGoService.getRepositoryInfo();
29
+ return {
30
+ contents: [{
31
+ uri: uri.href,
32
+ text: JSON.stringify(repoInfo, null, 2),
33
+ mimeType: "application/json"
34
+ }]
35
+ };
36
+ });
37
+ // Resource: Get specific AL-Go documentation file
38
+ server.registerResource("al-go-doc", "al-go://docs/{path}", {
39
+ title: "AL-Go Documentation File",
40
+ description: "Get content from a specific AL-Go documentation file"
41
+ }, async (uri) => {
42
+ // Extract path from URI
43
+ const urlPath = new URL(uri.href).pathname.replace('/docs/', '');
44
+ const content = await alGoService.getDocumentContent(urlPath);
45
+ return {
46
+ contents: [{
47
+ uri: uri.href,
48
+ text: content,
49
+ mimeType: "text/markdown"
50
+ }]
51
+ };
52
+ });
53
+ // Tool: Search AL-Go documentation
54
+ server.registerTool("search-al-go-docs", {
55
+ title: "Search AL-Go Documentation",
56
+ description: "Search through AL-Go documentation for specific queries",
57
+ inputSchema: {
58
+ query: z.string().describe("Search query for AL-Go documentation"),
59
+ limit: z.number().default(10).describe("Maximum number of results to return")
60
+ }
61
+ }, async ({ query, limit }) => {
62
+ try {
63
+ // Use direct API search instead of indexing
64
+ const results = await documentIndex.search(query, limit);
65
+ const resultText = results.map((result, index) => `${index + 1}. **${result.title}** (${result.path})\n ${result.excerpt}\n Score: ${result.score.toFixed(2)}\n`).join('\n');
66
+ return {
67
+ content: [{
68
+ type: "text",
69
+ text: `Found ${results.length} results for "${query}":\n\n${resultText}`
70
+ }]
71
+ };
72
+ }
73
+ catch (error) {
74
+ return {
75
+ content: [{
76
+ type: "text",
77
+ text: `Error searching AL-Go documentation: ${error instanceof Error ? error.message : 'Unknown error'}`
78
+ }],
79
+ isError: true
80
+ };
81
+ }
82
+ });
83
+ // Tool: Get AL-Go workflow examples
84
+ server.registerTool("get-al-go-workflows", {
85
+ title: "Get AL-Go Workflow Examples",
86
+ description: "Get examples of AL-Go GitHub workflows",
87
+ inputSchema: {
88
+ workflowType: z.enum(["cicd", "deployment", "testing", "all"]).default("all").describe("Type of workflows to retrieve")
89
+ }
90
+ }, async ({ workflowType }) => {
91
+ try {
92
+ const workflows = await alGoService.getWorkflowExamples(workflowType);
93
+ const workflowText = workflows.map((workflow) => `## ${workflow.name}\n**Path:** ${workflow.path}\n**Description:** ${workflow.description}\n\n\`\`\`yaml\n${workflow.content}\n\`\`\`\n`).join('\n---\n\n');
94
+ return {
95
+ content: [{
96
+ type: "text",
97
+ text: `AL-Go Workflow Examples (${workflowType}):\n\n${workflowText}`
98
+ }]
99
+ };
100
+ }
101
+ catch (error) {
102
+ return {
103
+ content: [{
104
+ type: "text",
105
+ text: `Error retrieving AL-Go workflows: ${error instanceof Error ? error.message : 'Unknown error'}`
106
+ }],
107
+ isError: true
108
+ };
109
+ }
110
+ });
111
+ // Tool: Refresh documentation cache
112
+ server.registerTool("refresh-al-go-cache", {
113
+ title: "Refresh AL-Go Documentation Cache",
114
+ description: "Refresh the cached AL-Go documentation from the repository",
115
+ inputSchema: {
116
+ force: z.boolean().default(false).describe("Force refresh even if cache is recent")
117
+ }
118
+ }, async ({ force }) => {
119
+ try {
120
+ await documentIndex.refresh(alGoService, force);
121
+ return {
122
+ content: [{
123
+ type: "text",
124
+ text: "AL-Go documentation cache refreshed successfully."
125
+ }]
126
+ };
127
+ }
128
+ catch (error) {
129
+ return {
130
+ content: [{
131
+ type: "text",
132
+ text: `Error refreshing AL-Go cache: ${error instanceof Error ? error.message : 'Unknown error'}`
133
+ }],
134
+ isError: true
135
+ };
136
+ }
137
+ });
138
+ // Prompt: AL-Go project setup help
139
+ server.registerPrompt("al-go-setup-help", {
140
+ title: "AL-Go Project Setup Help",
141
+ description: "Get help with setting up AL-Go for Business Central projects",
142
+ argsSchema: {
143
+ projectType: z.enum(["per-tenant-extension", "app-source", "template"]).describe("Type of AL-Go project"),
144
+ scenario: z.string().optional().describe("Specific scenario or requirement")
145
+ }
146
+ }, ({ projectType, scenario }) => {
147
+ const basePrompt = `You are an expert in AL-Go for GitHub, Microsoft's development framework for Business Central extensions. Help the user set up an AL-Go project.
148
+
149
+ Project Type: ${projectType}
150
+ ${scenario ? `Scenario: ${scenario}` : ''}
151
+
152
+ Please provide step-by-step guidance including:
153
+ 1. Repository setup and structure
154
+ 2. Required configuration files
155
+ 3. Workflow configuration
156
+ 4. Best practices and common pitfalls
157
+
158
+ Use the AL-Go documentation and examples available through the MCP tools to provide accurate, up-to-date information.`;
159
+ return {
160
+ messages: [{
161
+ role: "user",
162
+ content: {
163
+ type: "text",
164
+ text: basePrompt
165
+ }
166
+ }]
167
+ };
168
+ });
169
+ // Main function to start the server
170
+ async function main() {
171
+ console.error("Starting AL-Go MCP Server...");
172
+ try {
173
+ // Document index will be initialized on first search request
174
+ // Start the server with stdio transport
175
+ const transport = new StdioServerTransport();
176
+ await server.connect(transport);
177
+ console.error("AL-Go MCP Server is running on stdio");
178
+ }
179
+ catch (error) {
180
+ console.error("Failed to start AL-Go MCP Server:", error);
181
+ process.exit(1);
182
+ }
183
+ }
184
+ // Handle process termination
185
+ process.on('SIGINT', () => {
186
+ console.error("Shutting down AL-Go MCP Server...");
187
+ process.exit(0);
188
+ });
189
+ process.on('SIGTERM', () => {
190
+ console.error("Shutting down AL-Go MCP Server...");
191
+ process.exit(0);
192
+ });
193
+ // Start the server
194
+ main().catch(error => {
195
+ console.error("Fatal error in AL-Go MCP Server:", error);
196
+ process.exit(1);
197
+ });
198
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,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,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;;;;;GAMG;AAEH,4BAA4B;AAC5B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,kBAAkB;IACxB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,sBAAsB;AACtB,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AACtC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;AAE1C,6CAA6C;AAC7C,MAAM,CAAC,gBAAgB,CACrB,iBAAiB,EACjB,mBAAmB,EACnB;IACE,KAAK,EAAE,8BAA8B;IACrC,WAAW,EAAE,8CAA8C;IAC3D,QAAQ,EAAE,kBAAkB;CAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,iBAAiB,EAAE,CAAC;IACvD,OAAO;QACL,QAAQ,EAAE,CAAC;gBACT,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvC,QAAQ,EAAE,kBAAkB;aAC7B,CAAC;KACH,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,kDAAkD;AAClD,MAAM,CAAC,gBAAgB,CACrB,WAAW,EACX,qBAAqB,EACrB;IACE,KAAK,EAAE,0BAA0B;IACjC,WAAW,EAAE,sDAAsD;CACpE,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,wBAAwB;IACxB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC9D,OAAO;QACL,QAAQ,EAAE,CAAC;gBACT,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,eAAe;aAC1B,CAAC;KACH,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,mCAAmC;AACnC,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;IACE,KAAK,EAAE,4BAA4B;IACnC,WAAW,EAAE,yDAAyD;IACtE,WAAW,EAAE;QACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;QAClE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;KAC9E;CACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;IACzB,IAAI,CAAC;QACH,4CAA4C;QAC5C,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAEzD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAW,EAAE,KAAa,EAAE,EAAE,CAC5D,GAAG,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,KAAK,OAAO,MAAM,CAAC,IAAI,SAAS,MAAM,CAAC,OAAO,eAAe,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CACnH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,SAAS,OAAO,CAAC,MAAM,iBAAiB,KAAK,SAAS,UAAU,EAAE;iBACzE,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,wCAAwC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;iBACzG,CAAC;YACF,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,oCAAoC;AACpC,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;IACE,KAAK,EAAE,6BAA6B;IACpC,WAAW,EAAE,wCAAwC;IACrD,WAAW,EAAE;QACX,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC;KACxH;CACF,EACD,KAAK,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;IACzB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAEtE,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAa,EAAE,EAAE,CACnD,MAAM,QAAQ,CAAC,IAAI,eAAe,QAAQ,CAAC,IAAI,sBAAsB,QAAQ,CAAC,WAAW,mBAAmB,QAAQ,CAAC,OAAO,YAAY,CACzI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAEpB,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,4BAA4B,YAAY,SAAS,YAAY,EAAE;iBACtE,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,qCAAqC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;iBACtG,CAAC;YACF,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,oCAAoC;AACpC,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;IACE,KAAK,EAAE,mCAAmC;IAC1C,WAAW,EAAE,4DAA4D;IACzE,WAAW,EAAE;QACX,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,uCAAuC,CAAC;KACpF;CACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;IAClB,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAChD,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,mDAAmD;iBAC1D,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,iCAAiC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;iBAClG,CAAC;YACF,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,mCAAmC;AACnC,MAAM,CAAC,cAAc,CACnB,kBAAkB,EAClB;IACE,KAAK,EAAE,0BAA0B;IACjC,WAAW,EAAE,8DAA8D;IAC3E,UAAU,EAAE;QACV,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,sBAAsB,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACzG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;KAC7E;CACF,EACD,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC5B,MAAM,UAAU,GAAG;;gBAEP,WAAW;EACzB,QAAQ,CAAC,CAAC,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;;;;;;;;sHAQ6E,CAAC;IAEnH,OAAO;QACL,QAAQ,EAAE,CAAC;gBACT,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,UAAU;iBACjB;aACF,CAAC;KACH,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,oCAAoC;AACpC,KAAK,UAAU,IAAI;IACjB,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAE9C,IAAI,CAAC;QACH,6DAA6D;QAE7D,wCAAwC;QACxC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEhC,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,6BAA6B;AAC7B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,mBAAmB;AACnB,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;IACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Service for interacting with the AL-Go GitHub repository
3
+ */
4
+ export declare class AlGoService {
5
+ private octokit;
6
+ private owner;
7
+ private repo;
8
+ constructor();
9
+ /**
10
+ * Get basic repository information
11
+ */
12
+ getRepositoryInfo(): Promise<{
13
+ name: string;
14
+ description: string | null;
15
+ stars: number;
16
+ forks: number;
17
+ language: string | null;
18
+ lastUpdated: string;
19
+ defaultBranch: string;
20
+ url: string;
21
+ topics: string[] | undefined;
22
+ }>;
23
+ /**
24
+ * Get content of a specific documentation file
25
+ */
26
+ getDocumentContent(path: string): Promise<string>;
27
+ /**
28
+ * Get all documentation files from the repository
29
+ */
30
+ getDocumentationFiles(): Promise<Array<{
31
+ path: string;
32
+ content: string;
33
+ name: string;
34
+ }>>;
35
+ /**
36
+ * Get workflow examples from the repository
37
+ */
38
+ getWorkflowExamples(workflowType: string): Promise<Array<{
39
+ name: string;
40
+ path: string;
41
+ content: string;
42
+ description: string;
43
+ }>>;
44
+ /**
45
+ * Check if a workflow matches the specified type
46
+ */
47
+ private matchesWorkflowType;
48
+ }
49
+ //# sourceMappingURL=AlGoService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlGoService.d.ts","sourceRoot":"","sources":["../../src/services/AlGoService.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,IAAI,CAAW;;IA8BvB;;OAEG;IACG,iBAAiB;;;;;;;;;;;IAwBvB;;OAEG;IACG,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBvD;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAqD9F;;OAEG;IACG,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IA+CrI;;OAEG;IACH,OAAO,CAAC,mBAAmB;CA0B5B"}
@@ -0,0 +1,204 @@
1
+ import { Octokit } from "@octokit/rest";
2
+ /**
3
+ * Service for interacting with the AL-Go GitHub repository
4
+ */
5
+ export class AlGoService {
6
+ octokit;
7
+ owner = "microsoft";
8
+ repo = "AL-Go";
9
+ constructor() {
10
+ // Initialize Octokit with authentication
11
+ const githubToken = process.env.GITHUB_TOKEN;
12
+ const githubAppId = process.env.GITHUB_APP_ID;
13
+ const githubPrivateKey = process.env.GITHUB_PRIVATE_KEY;
14
+ const githubInstallationId = process.env.GITHUB_INSTALLATION_ID;
15
+ if (githubAppId && githubPrivateKey && githubInstallationId) {
16
+ // Use GitHub App authentication
17
+ this.octokit = new Octokit({
18
+ appId: githubAppId,
19
+ privateKey: githubPrivateKey.replace(/\\n/g, '\n'),
20
+ installationId: githubInstallationId,
21
+ });
22
+ console.log("AL-Go MCP Server: Using GitHub App authentication");
23
+ }
24
+ else if (githubToken) {
25
+ // Fallback to personal token
26
+ this.octokit = new Octokit({
27
+ auth: githubToken
28
+ });
29
+ console.log("AL-Go MCP Server: Using personal token authentication");
30
+ }
31
+ else {
32
+ // No authentication
33
+ this.octokit = new Octokit();
34
+ console.log("AL-Go MCP Server: Using unauthenticated requests (rate limited)");
35
+ }
36
+ }
37
+ /**
38
+ * Get basic repository information
39
+ */
40
+ async getRepositoryInfo() {
41
+ try {
42
+ const { data } = await this.octokit.rest.repos.get({
43
+ owner: this.owner,
44
+ repo: this.repo
45
+ });
46
+ return {
47
+ name: data.name,
48
+ description: data.description,
49
+ stars: data.stargazers_count,
50
+ forks: data.forks_count,
51
+ language: data.language,
52
+ lastUpdated: data.updated_at,
53
+ defaultBranch: data.default_branch,
54
+ url: data.html_url,
55
+ topics: data.topics
56
+ };
57
+ }
58
+ catch (error) {
59
+ console.error("Error fetching repository info:", error);
60
+ throw new Error(`Failed to fetch AL-Go repository information: ${error instanceof Error ? error.message : 'Unknown error'}`);
61
+ }
62
+ }
63
+ /**
64
+ * Get content of a specific documentation file
65
+ */
66
+ async getDocumentContent(path) {
67
+ try {
68
+ const { data } = await this.octokit.rest.repos.getContent({
69
+ owner: this.owner,
70
+ repo: this.repo,
71
+ path: path
72
+ });
73
+ if ('content' in data && data.content) {
74
+ // Decode base64 content
75
+ return Buffer.from(data.content, 'base64').toString('utf8');
76
+ }
77
+ else {
78
+ throw new Error("File content not found or is a directory");
79
+ }
80
+ }
81
+ catch (error) {
82
+ console.error(`Error fetching document ${path}:`, error);
83
+ throw new Error(`Failed to fetch document ${path}: ${error instanceof Error ? error.message : 'Unknown error'}`);
84
+ }
85
+ }
86
+ /**
87
+ * Get all documentation files from the repository
88
+ */
89
+ async getDocumentationFiles() {
90
+ try {
91
+ const docs = [];
92
+ // Get repository tree to find documentation files
93
+ const { data: tree } = await this.octokit.rest.git.getTree({
94
+ owner: this.owner,
95
+ repo: this.repo,
96
+ tree_sha: "main",
97
+ recursive: "true"
98
+ });
99
+ // Filter for documentation files (markdown, txt, and specific documentation directories)
100
+ const docFiles = tree.tree.filter(item => item.type === 'blob' &&
101
+ item.path && (item.path.endsWith('.md') ||
102
+ item.path.endsWith('.txt') ||
103
+ item.path.includes('Actions/') ||
104
+ item.path.includes('Scenarios/') ||
105
+ item.path.includes('Workshop/') ||
106
+ item.path.includes('Documentation/') ||
107
+ item.path === 'README.md' ||
108
+ item.path === 'RELEASENOTES.md'));
109
+ // Fetch content for each documentation file (limit to avoid API rate limits)
110
+ const maxFiles = 50; // Reasonable limit for initial implementation
111
+ for (let i = 0; i < Math.min(docFiles.length, maxFiles); i++) {
112
+ const file = docFiles[i];
113
+ if (file.path) {
114
+ try {
115
+ const content = await this.getDocumentContent(file.path);
116
+ docs.push({
117
+ path: file.path,
118
+ content: content,
119
+ name: file.path.split('/').pop() || file.path
120
+ });
121
+ }
122
+ catch (error) {
123
+ console.error(`Failed to fetch ${file.path}:`, error);
124
+ // Continue with other files
125
+ }
126
+ }
127
+ }
128
+ return docs;
129
+ }
130
+ catch (error) {
131
+ console.error("Error fetching documentation files:", error);
132
+ throw new Error(`Failed to fetch documentation files: ${error instanceof Error ? error.message : 'Unknown error'}`);
133
+ }
134
+ }
135
+ /**
136
+ * Get workflow examples from the repository
137
+ */
138
+ async getWorkflowExamples(workflowType) {
139
+ try {
140
+ const workflows = [];
141
+ // Get workflows from .github/workflows directory
142
+ const { data: workflowDir } = await this.octokit.rest.repos.getContent({
143
+ owner: this.owner,
144
+ repo: this.repo,
145
+ path: ".github/workflows"
146
+ });
147
+ if (Array.isArray(workflowDir)) {
148
+ const yamlFiles = workflowDir.filter(file => file.type === 'file' && file.name.endsWith('.yml') || file.name.endsWith('.yaml'));
149
+ for (const file of yamlFiles) {
150
+ try {
151
+ const content = await this.getDocumentContent(file.path);
152
+ // Extract description from workflow file
153
+ const descriptionMatch = content.match(/^#\s*(.+)$/m);
154
+ const description = descriptionMatch ? descriptionMatch[1] : 'AL-Go workflow';
155
+ // Filter by workflow type if specified
156
+ if (workflowType === 'all' || this.matchesWorkflowType(file.name, content, workflowType)) {
157
+ workflows.push({
158
+ name: file.name,
159
+ path: file.path,
160
+ content: content,
161
+ description: description
162
+ });
163
+ }
164
+ }
165
+ catch (error) {
166
+ console.error(`Failed to fetch workflow ${file.path}:`, error);
167
+ // Continue with other workflows
168
+ }
169
+ }
170
+ }
171
+ return workflows;
172
+ }
173
+ catch (error) {
174
+ console.error("Error fetching workflow examples:", error);
175
+ throw new Error(`Failed to fetch workflow examples: ${error instanceof Error ? error.message : 'Unknown error'}`);
176
+ }
177
+ }
178
+ /**
179
+ * Check if a workflow matches the specified type
180
+ */
181
+ matchesWorkflowType(fileName, content, workflowType) {
182
+ const lowerFileName = fileName.toLowerCase();
183
+ const lowerContent = content.toLowerCase();
184
+ switch (workflowType) {
185
+ case 'cicd':
186
+ return lowerFileName.includes('cicd') ||
187
+ lowerFileName.includes('ci') ||
188
+ lowerContent.includes('continuous integration') ||
189
+ lowerContent.includes('build and test');
190
+ case 'deployment':
191
+ return lowerFileName.includes('deploy') ||
192
+ lowerFileName.includes('release') ||
193
+ lowerContent.includes('deployment') ||
194
+ lowerContent.includes('publish');
195
+ case 'testing':
196
+ return lowerFileName.includes('test') ||
197
+ lowerContent.includes('test') ||
198
+ lowerContent.includes('validation');
199
+ default:
200
+ return true;
201
+ }
202
+ }
203
+ }
204
+ //# sourceMappingURL=AlGoService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlGoService.js","sourceRoot":"","sources":["../../src/services/AlGoService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { AlGoService } from "./AlGoService.js";
2
+ export interface SearchResult {
3
+ title: string;
4
+ path: string;
5
+ excerpt: string;
6
+ score: number;
7
+ content: string;
8
+ }
9
+ export interface DocumentEntry {
10
+ path: string;
11
+ content: string;
12
+ name: string;
13
+ title: string;
14
+ lastIndexed: Date;
15
+ }
16
+ /**
17
+ * Service for indexing and searching AL-Go documentation
18
+ */
19
+ export declare class DocumentIndex {
20
+ private documents;
21
+ private isInitialized;
22
+ private lastRefresh;
23
+ /**
24
+ * Initialize the document index
25
+ */
26
+ initialize(alGoService: AlGoService): Promise<void>;
27
+ /**
28
+ * Search through the indexed documents
29
+ */
30
+ search(query: string, limit?: number): Promise<SearchResult[]>;
31
+ /**
32
+ * Refresh the document index
33
+ */
34
+ refresh(alGoService: AlGoService, force?: boolean): Promise<void>;
35
+ /**
36
+ * Extract title from document content
37
+ */
38
+ private extractTitle;
39
+ /**
40
+ * Calculate relevance score for a document given a query
41
+ */
42
+ private calculateRelevanceScore;
43
+ /**
44
+ * Extract a relevant excerpt from the document content
45
+ */
46
+ private extractExcerpt;
47
+ }
48
+ //# sourceMappingURL=DocumentIndex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DocumentIndex.d.ts","sourceRoot":"","sources":["../../src/services/DocumentIndex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,IAAI,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAqB;IAExC;;OAEG;IACG,UAAU,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BzD;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAWxE;;OAEG;IACG,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9E;;OAEG;IACH,OAAO,CAAC,YAAY;IAiBpB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAyC/B;;OAEG;IACH,OAAO,CAAC,cAAc;CAmCvB"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Service for indexing and searching AL-Go documentation
3
+ */
4
+ export class DocumentIndex {
5
+ documents = [];
6
+ isInitialized = false;
7
+ lastRefresh = null;
8
+ /**
9
+ * Initialize the document index
10
+ */
11
+ async initialize(alGoService) {
12
+ if (this.isInitialized && this.lastRefresh &&
13
+ (Date.now() - this.lastRefresh.getTime()) < 3600000) { // 1 hour cache
14
+ return;
15
+ }
16
+ console.error("Initializing AL-Go document index...");
17
+ try {
18
+ const docs = await alGoService.getDocumentationFiles();
19
+ this.documents = docs.map(doc => ({
20
+ path: doc.path,
21
+ content: doc.content,
22
+ name: doc.name,
23
+ title: this.extractTitle(doc.content, doc.name),
24
+ lastIndexed: new Date()
25
+ }));
26
+ this.isInitialized = true;
27
+ this.lastRefresh = new Date();
28
+ console.error(`Indexed ${this.documents.length} AL-Go documents`);
29
+ }
30
+ catch (error) {
31
+ console.error("Failed to initialize document index:", error);
32
+ throw error;
33
+ }
34
+ }
35
+ /**
36
+ * Search through the indexed documents
37
+ */
38
+ async search(query, limit = 10) {
39
+ // Return a simple response to avoid API rate limits
40
+ return [{
41
+ title: "AL-Go Documentation Search",
42
+ path: "README.md",
43
+ excerpt: `Search for "${query}" - Due to GitHub API rate limits, please use specific file paths with the al-go-doc resource or try the get-al-go-workflows tool.`,
44
+ score: 1.0,
45
+ content: "Use specific AL-Go documentation file paths or workflow tools for better results."
46
+ }];
47
+ }
48
+ /**
49
+ * Refresh the document index
50
+ */
51
+ async refresh(alGoService, force = false) {
52
+ if (force || !this.lastRefresh ||
53
+ (Date.now() - this.lastRefresh.getTime()) > 3600000) { // 1 hour cache
54
+ this.isInitialized = false;
55
+ await this.initialize(alGoService);
56
+ }
57
+ }
58
+ /**
59
+ * Extract title from document content
60
+ */
61
+ extractTitle(content, fallbackName) {
62
+ // Try to find the first heading in markdown
63
+ const headingMatch = content.match(/^#\s+(.+)$/m);
64
+ if (headingMatch) {
65
+ return headingMatch[1].trim();
66
+ }
67
+ // Try to find title in front matter
68
+ const frontMatterMatch = content.match(/^---\s*\n.*?title:\s*(.+?)\s*\n.*?---/s);
69
+ if (frontMatterMatch) {
70
+ return frontMatterMatch[1].trim();
71
+ }
72
+ // Use filename without extension as fallback
73
+ return fallbackName.replace(/\.[^/.]+$/, "");
74
+ }
75
+ /**
76
+ * Calculate relevance score for a document given a query
77
+ */
78
+ calculateRelevanceScore(doc, lowerQuery) {
79
+ let score = 0;
80
+ const lowerContent = doc.content.toLowerCase();
81
+ const lowerTitle = doc.title.toLowerCase();
82
+ const lowerPath = doc.path.toLowerCase();
83
+ // Exact matches in title get highest score
84
+ if (lowerTitle.includes(lowerQuery)) {
85
+ score += 10;
86
+ }
87
+ // Matches in path get medium score
88
+ if (lowerPath.includes(lowerQuery)) {
89
+ score += 5;
90
+ }
91
+ // Word matches in content
92
+ const queryWords = lowerQuery.split(/\s+/);
93
+ for (const word of queryWords) {
94
+ if (word.length > 2) { // Ignore very short words
95
+ const wordRegex = new RegExp(`\\b${word}\\b`, 'gi');
96
+ const matches = (lowerContent.match(wordRegex) || []).length;
97
+ score += matches * 0.5;
98
+ // Bonus for matches in headings
99
+ const headingMatches = (lowerContent.match(new RegExp(`^#+.*${word}.*$`, 'gmi')) || []).length;
100
+ score += headingMatches * 2;
101
+ }
102
+ }
103
+ // Bonus for AL-Go specific terms
104
+ const alGoTerms = ['al-go', 'business central', 'workflow', 'actions', 'templates', 'devops'];
105
+ for (const term of alGoTerms) {
106
+ if (lowerQuery.includes(term) && lowerContent.includes(term)) {
107
+ score += 1;
108
+ }
109
+ }
110
+ return score;
111
+ }
112
+ /**
113
+ * Extract a relevant excerpt from the document content
114
+ */
115
+ extractExcerpt(content, lowerQuery, maxLength = 200) {
116
+ const lowerContent = content.toLowerCase();
117
+ const queryWords = lowerQuery.split(/\s+/);
118
+ // Find the first occurrence of any query word
119
+ let bestIndex = -1;
120
+ for (const word of queryWords) {
121
+ if (word.length > 2) {
122
+ const index = lowerContent.indexOf(word);
123
+ if (index !== -1 && (bestIndex === -1 || index < bestIndex)) {
124
+ bestIndex = index;
125
+ }
126
+ }
127
+ }
128
+ if (bestIndex === -1) {
129
+ // No match found, return beginning of content
130
+ return content.substring(0, maxLength).trim() + (content.length > maxLength ? '...' : '');
131
+ }
132
+ // Extract excerpt around the match
133
+ const start = Math.max(0, bestIndex - 50);
134
+ const end = Math.min(content.length, start + maxLength);
135
+ let excerpt = content.substring(start, end);
136
+ // Clean up the excerpt
137
+ excerpt = excerpt.replace(/\n+/g, ' ').trim();
138
+ // Add ellipsis if we're not at the beginning/end
139
+ if (start > 0)
140
+ excerpt = '...' + excerpt;
141
+ if (end < content.length)
142
+ excerpt = excerpt + '...';
143
+ return excerpt;
144
+ }
145
+ }
146
+ //# sourceMappingURL=DocumentIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DocumentIndex.js","sourceRoot":"","sources":["../../src/services/DocumentIndex.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "al-go-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for AL-Go documentation integration",
5
+ "type": "module",
6
+ "main": "./build/index.js",
7
+ "bin": {
8
+ "al-go-mcp-server": "./build/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node build/index.js",
13
+ "dev": "tsc && node build/index.js",
14
+ "watch": "tsc --watch"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "model-context-protocol",
19
+ "al-go",
20
+ "documentation",
21
+ "github"
22
+ ],
23
+ "author": "Job Louage",
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "@modelcontextprotocol/sdk": "^1.18.0",
27
+ "@octokit/rest": "^21.0.2",
28
+ "zod": "^3.23.8",
29
+ "node-fetch": "^3.3.2"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.0.0",
33
+ "typescript": "^5.6.0"
34
+ },
35
+ "files": [
36
+ "build"
37
+ ]
38
+ }