dotnet-ai-mcp-server 1.0.2 → 1.0.3

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/README.md CHANGED
@@ -1,99 +1,50 @@
1
- # DotNet AI MCP Server
1
+ # dotnet-ai-mcp-server
2
2
 
3
- The essential Model Context Protocol server for .NET developers building AI applications.
3
+ MCP Server for .NET AI development - provides real code samples from Semantic Kernel, OpenAI .NET, MCP C# SDK, and more.
4
4
 
5
- ## Quick Start
5
+ ## Installation
6
6
 
7
- ### Using npx (Recommended)
7
+ ```bash
8
+ npm install -g dotnet-ai-mcp-server
9
+ ```
8
10
 
9
- Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
11
+ Or use with npx (no installation needed):
10
12
 
11
- ```json
12
- {
13
- "mcpServers": {
14
- "dotnet-ai": {
15
- "command": "npx",
16
- "args": ["-y", "dotnet-ai-mcp-server"]
17
- }
18
- }
19
- }
13
+ ```bash
14
+ npx dotnet-ai-mcp-server
20
15
  ```
21
16
 
22
- ### Using VS Code / GitHub Copilot
17
+ ## Usage with Claude Desktop
23
18
 
24
- Add to your VS Code MCP settings:
19
+ Add to your `claude_desktop_config.json`:
25
20
 
26
21
  ```json
27
22
  {
28
- "mcp": {
29
- "servers": {
30
- "dotnet-ai": {
31
- "command": "npx",
32
- "args": ["-y", "dotnet-ai-mcp-server"]
33
- }
23
+ "mcpServers": {
24
+ "dotnet-ai": {
25
+ "command": "npx",
26
+ "args": ["-y", "dotnet-ai-mcp-server"]
34
27
  }
35
28
  }
36
29
  }
37
30
  ```
38
31
 
39
- ## Prerequisites
40
-
41
- - [.NET 9.0 SDK](https://dotnet.microsoft.com/download) - Required for the underlying dotnet tool
42
- - Node.js 16+ - For npx
43
-
44
- ## What This Does
45
-
46
- This MCP server provides real, up-to-date code samples from the .NET AI ecosystem:
32
+ ### Config file locations:
33
+ - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
34
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
47
35
 
48
- - **Semantic Kernel** - AI orchestration framework
49
- - **OpenAI .NET SDK** - Official OpenAI client
50
- - **MCP C# SDK** - Model Context Protocol for .NET
51
- - **Microsoft.Extensions.AI** - AI abstractions
52
- - **Anthropic SDK** - Claude SDK for .NET
53
- - **Google GenAI** - Gemini SDK for .NET
54
- - **Vector DBs** - Pinecone, Qdrant, Weaviate, Redis
36
+ ## Features
55
37
 
56
- ## Why Use This?
38
+ - **Real code samples** from official Microsoft repositories
39
+ - **GitHub integration** - fetches live code from Semantic Kernel, OpenAI .NET, MCP C# SDK, and more
40
+ - **Microsoft Learn docs** - searches official documentation
41
+ - **No .NET SDK required** - self-contained executable
57
42
 
58
- LLMs hallucinate .NET AI APIs. Training data can't keep up with rapidly evolving libraries like Semantic Kernel. This server fetches real code from live GitHub repositories.
43
+ ## Supported Platforms
59
44
 
60
- ## Available Tools
61
-
62
- | Tool | Description |
63
- |------|-------------|
64
- | `Start_DotNet_Reasoning` | Entry point - lists tracked repositories |
65
- | `GitHubGetFolders` | Shows folder structure |
66
- | `GitHubListFiles` | Lists files in folders |
67
- | `GitHubFetchFiles` | Fetches actual code |
68
- | `MicrosoftDocsSearch` | Searches Microsoft Learn |
69
- | `MicrosoftDocsFetch` | Fetches documentation |
70
- | `MicrosoftCodeSampleSearch` | Finds code samples |
71
-
72
- ## How It Works
73
-
74
- 1. The npm package installs the .NET global tool (`dotnet tool install -g DotNetAIMcpServer`)
75
- 2. When invoked via npx, it runs the dotnet tool which communicates via stdio
76
- 3. The tool fetches live code from GitHub and Microsoft Learn
77
-
78
- ## Manual Installation
79
-
80
- If you prefer to install the dotnet tool directly:
81
-
82
- ```bash
83
- dotnet tool install -g DotNetAIMcpServer
84
- ```
85
-
86
- Then configure your MCP client to use:
87
-
88
- ```json
89
- {
90
- "mcpServers": {
91
- "dotnet-ai": {
92
- "command": "dotnet-ai-mcp"
93
- }
94
- }
95
- }
96
- ```
45
+ - macOS (Intel & Apple Silicon)
46
+ - Linux (x64 & ARM64)
47
+ - Windows (x64)
97
48
 
98
49
  ## License
99
50
 
package/bin/cli.js CHANGED
@@ -1,93 +1,31 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const { spawn } = require('child_process');
4
- const { existsSync } = require('fs');
5
- const { join } = require('path');
4
+ const path = require('path');
6
5
  const os = require('os');
6
+ const fs = require('fs');
7
7
 
8
- const TOOL_NAME = 'dotnet-ai-mcp';
9
- const NUGET_PACKAGE = 'DotNetAIMcpServer';
8
+ const isWindows = os.platform() === 'win32';
9
+ const binaryName = isWindows ? 'dotnet-ai-mcp-server.exe' : 'dotnet-ai-mcp-server';
10
+ const binaryPath = path.join(__dirname, binaryName);
10
11
 
11
- async function checkDotnetInstalled() {
12
- return new Promise((resolve) => {
13
- const proc = spawn('dotnet', ['--version'], { stdio: 'pipe' });
14
- proc.on('close', (code) => resolve(code === 0));
15
- proc.on('error', () => resolve(false));
16
- });
12
+ if (!fs.existsSync(binaryPath)) {
13
+ console.error('Binary not found. Please reinstall the package:');
14
+ console.error(' npm uninstall -g dotnet-ai-mcp-server');
15
+ console.error(' npm install -g dotnet-ai-mcp-server');
16
+ process.exit(1);
17
17
  }
18
18
 
19
- async function checkToolInstalled() {
20
- return new Promise((resolve) => {
21
- const proc = spawn('dotnet', ['tool', 'list', '-g'], { stdio: 'pipe' });
22
- let output = '';
23
- proc.stdout.on('data', (data) => { output += data.toString(); });
24
- proc.on('close', () => {
25
- resolve(output.toLowerCase().includes(NUGET_PACKAGE.toLowerCase()));
26
- });
27
- proc.on('error', () => resolve(false));
28
- });
29
- }
30
-
31
- async function installTool() {
32
- console.error(`Installing ${NUGET_PACKAGE}...`);
33
- return new Promise((resolve, reject) => {
34
- const proc = spawn('dotnet', ['tool', 'install', '-g', NUGET_PACKAGE], {
35
- stdio: 'inherit'
36
- });
37
- proc.on('close', (code) => {
38
- if (code === 0) resolve();
39
- else reject(new Error(`Failed to install ${NUGET_PACKAGE}`));
40
- });
41
- proc.on('error', reject);
42
- });
43
- }
44
-
45
- async function runTool() {
46
- const isWindows = os.platform() === 'win32';
47
- const toolPath = isWindows
48
- ? join(os.homedir(), '.dotnet', 'tools', `${TOOL_NAME}.exe`)
49
- : join(os.homedir(), '.dotnet', 'tools', TOOL_NAME);
50
-
51
- // Always use full path for reliability
52
- const proc = spawn(toolPath, [], {
53
- stdio: 'inherit',
54
- shell: false
55
- });
56
-
57
- proc.on('error', (err) => {
58
- console.error(`Error running ${TOOL_NAME}: ${err.message}`);
59
- console.error(`Tried path: ${toolPath}`);
60
- console.error('Make sure the dotnet tool is installed: dotnet tool install -g DotNetAIMcpServer');
61
- process.exit(1);
62
- });
19
+ const proc = spawn(binaryPath, process.argv.slice(2), {
20
+ stdio: 'inherit',
21
+ shell: false
22
+ });
63
23
 
64
- proc.on('close', (code) => {
65
- process.exit(code || 0);
66
- });
67
- }
68
-
69
- async function main() {
70
- try {
71
- // Check if .NET is installed
72
- const dotnetInstalled = await checkDotnetInstalled();
73
- if (!dotnetInstalled) {
74
- console.error('ERROR: .NET SDK is not installed.');
75
- console.error('Please install .NET 9.0 SDK from: https://dotnet.microsoft.com/download');
76
- process.exit(1);
77
- }
78
-
79
- // Check if the tool is installed
80
- const toolInstalled = await checkToolInstalled();
81
- if (!toolInstalled) {
82
- await installTool();
83
- }
84
-
85
- // Run the tool
86
- await runTool();
87
- } catch (error) {
88
- console.error(`Error: ${error.message}`);
89
- process.exit(1);
90
- }
91
- }
24
+ proc.on('error', (err) => {
25
+ console.error(`Failed to start server: ${err.message}`);
26
+ process.exit(1);
27
+ });
92
28
 
93
- main();
29
+ proc.on('close', (code) => {
30
+ process.exit(code || 0);
31
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotnet-ai-mcp-server",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "MCP Server for .NET AI development - provides real code samples from Semantic Kernel, OpenAI .NET, MCP C# SDK, and more",
5
5
  "bin": {
6
6
  "dotnet-ai-mcp-server": "bin/cli.js"
@@ -1,85 +1,104 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { spawn } = require('child_process');
3
+ const https = require('https');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const os = require('os');
7
+ const { execSync } = require('child_process');
4
8
 
5
- const NUGET_PACKAGE = 'DotNetAIMcpServer';
9
+ const REPO = 'ArbelH/dotnet-ai-mcp-server';
10
+ const VERSION = require('../package.json').version;
6
11
 
7
- async function checkDotnetInstalled() {
8
- return new Promise((resolve) => {
9
- const proc = spawn('dotnet', ['--version'], { stdio: 'pipe' });
10
- proc.on('close', (code) => resolve(code === 0));
11
- proc.on('error', () => resolve(false));
12
- });
13
- }
12
+ function getPlatformInfo() {
13
+ const platform = os.platform();
14
+ const arch = os.arch();
14
15
 
15
- async function checkToolInstalled() {
16
- return new Promise((resolve) => {
17
- const proc = spawn('dotnet', ['tool', 'list', '-g'], { stdio: 'pipe' });
18
- let output = '';
19
- proc.stdout.on('data', (data) => { output += data.toString(); });
20
- proc.on('close', () => {
21
- resolve(output.toLowerCase().includes(NUGET_PACKAGE.toLowerCase()));
22
- });
23
- proc.on('error', () => resolve(false));
24
- });
16
+ const platformMap = {
17
+ 'darwin-x64': 'dotnet-ai-mcp-server-darwin-x64',
18
+ 'darwin-arm64': 'dotnet-ai-mcp-server-darwin-arm64',
19
+ 'linux-x64': 'dotnet-ai-mcp-server-linux-x64',
20
+ 'linux-arm64': 'dotnet-ai-mcp-server-linux-arm64',
21
+ 'win32-x64': 'dotnet-ai-mcp-server-win-x64.exe',
22
+ };
23
+
24
+ const key = `${platform}-${arch}`;
25
+ const binaryName = platformMap[key];
26
+
27
+ if (!binaryName) {
28
+ console.error(`Unsupported platform: ${platform}-${arch}`);
29
+ console.error('Supported platforms: darwin-x64, darwin-arm64, linux-x64, linux-arm64, win32-x64');
30
+ process.exit(1);
31
+ }
32
+
33
+ return { binaryName, isWindows: platform === 'win32' };
25
34
  }
26
35
 
27
- async function installTool() {
28
- console.log(`Installing ${NUGET_PACKAGE} dotnet tool...`);
36
+ function downloadFile(url, dest) {
29
37
  return new Promise((resolve, reject) => {
30
- const proc = spawn('dotnet', ['tool', 'install', '-g', NUGET_PACKAGE], {
31
- stdio: 'inherit'
32
- });
33
- proc.on('close', (code) => {
34
- if (code === 0) {
35
- console.log(`${NUGET_PACKAGE} installed successfully!`);
36
- resolve();
37
- } else {
38
- // Tool might already be installed, try update
39
- const updateProc = spawn('dotnet', ['tool', 'update', '-g', NUGET_PACKAGE], {
40
- stdio: 'inherit'
38
+ const follow = (url, redirectCount = 0) => {
39
+ if (redirectCount > 5) {
40
+ reject(new Error('Too many redirects'));
41
+ return;
42
+ }
43
+
44
+ https.get(url, { headers: { 'User-Agent': 'dotnet-ai-mcp-server-npm' } }, (response) => {
45
+ if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
46
+ follow(response.headers.location, redirectCount + 1);
47
+ return;
48
+ }
49
+
50
+ if (response.statusCode !== 200) {
51
+ reject(new Error(`Failed to download: ${response.statusCode}`));
52
+ return;
53
+ }
54
+
55
+ const file = fs.createWriteStream(dest);
56
+ response.pipe(file);
57
+ file.on('finish', () => {
58
+ file.close();
59
+ resolve();
41
60
  });
42
- updateProc.on('close', (updateCode) => {
43
- if (updateCode === 0) {
44
- console.log(`${NUGET_PACKAGE} updated successfully!`);
45
- resolve();
46
- } else {
47
- reject(new Error(`Failed to install/update ${NUGET_PACKAGE}`));
48
- }
61
+ file.on('error', (err) => {
62
+ fs.unlink(dest, () => {});
63
+ reject(err);
49
64
  });
50
- updateProc.on('error', reject);
51
- }
52
- });
53
- proc.on('error', reject);
65
+ }).on('error', reject);
66
+ };
67
+
68
+ follow(url);
54
69
  });
55
70
  }
56
71
 
57
72
  async function main() {
73
+ const { binaryName, isWindows } = getPlatformInfo();
74
+ const binDir = path.join(__dirname, '..', 'bin');
75
+ const binaryPath = path.join(binDir, isWindows ? 'dotnet-ai-mcp-server.exe' : 'dotnet-ai-mcp-server');
76
+
77
+ // Skip if binary already exists
78
+ if (fs.existsSync(binaryPath)) {
79
+ console.log('Binary already exists, skipping download.');
80
+ return;
81
+ }
82
+
83
+ const downloadUrl = `https://github.com/${REPO}/releases/download/v${VERSION}/${binaryName}`;
84
+
85
+ console.log(`Downloading ${binaryName}...`);
86
+ console.log(`URL: ${downloadUrl}`);
87
+
58
88
  try {
59
- // Check if .NET is installed
60
- const dotnetInstalled = await checkDotnetInstalled();
61
- if (!dotnetInstalled) {
62
- console.log('\n========================================');
63
- console.log(' .NET SDK Required');
64
- console.log('========================================');
65
- console.log('This package requires .NET 9.0 SDK.');
66
- console.log('Please install from: https://dotnet.microsoft.com/download');
67
- console.log('========================================\n');
68
- return; // Don't fail, just warn
69
- }
89
+ await downloadFile(downloadUrl, binaryPath);
70
90
 
71
- // Check if already installed
72
- const toolInstalled = await checkToolInstalled();
73
- if (toolInstalled) {
74
- console.log(`${NUGET_PACKAGE} is already installed.`);
75
- return;
91
+ if (!isWindows) {
92
+ fs.chmodSync(binaryPath, 0o755);
76
93
  }
77
94
 
78
- // Install the tool
79
- await installTool();
95
+ console.log('Download complete!');
80
96
  } catch (error) {
81
- console.error(`Warning: Could not install ${NUGET_PACKAGE}: ${error.message}`);
82
- console.error('You can install it manually with: dotnet tool install -g DotNetAIMcpServer');
97
+ console.error(`Failed to download binary: ${error.message}`);
98
+ console.error('');
99
+ console.error('You may need to download it manually from:');
100
+ console.error(`https://github.com/${REPO}/releases`);
101
+ process.exit(1);
83
102
  }
84
103
  }
85
104