dotnet-ai-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/README.md +100 -0
- package/bin/cli.js +96 -0
- package/package.json +36 -0
- package/scripts/postinstall.js +86 -0
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# DotNet AI MCP Server
|
|
2
|
+
|
|
3
|
+
The essential Model Context Protocol server for .NET developers building AI applications.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Using npx (Recommended)
|
|
8
|
+
|
|
9
|
+
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"mcpServers": {
|
|
14
|
+
"dotnet-ai": {
|
|
15
|
+
"command": "npx",
|
|
16
|
+
"args": ["-y", "dotnet-ai-mcp-server"]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Using VS Code / GitHub Copilot
|
|
23
|
+
|
|
24
|
+
Add to your VS Code MCP settings:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"mcp": {
|
|
29
|
+
"servers": {
|
|
30
|
+
"dotnet-ai": {
|
|
31
|
+
"command": "npx",
|
|
32
|
+
"args": ["-y", "dotnet-ai-mcp-server"]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
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:
|
|
47
|
+
|
|
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
|
|
55
|
+
|
|
56
|
+
## Why Use This?
|
|
57
|
+
|
|
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.
|
|
59
|
+
|
|
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
|
+
```
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const { existsSync } = require('fs');
|
|
5
|
+
const { join } = require('path');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
|
|
8
|
+
const TOOL_NAME = 'dotnet-ai-mcp';
|
|
9
|
+
const NUGET_PACKAGE = 'DotNetAIMcpServer';
|
|
10
|
+
|
|
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
|
+
});
|
|
17
|
+
}
|
|
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
|
+
// On Windows, the tool might be in a different location
|
|
47
|
+
const isWindows = os.platform() === 'win32';
|
|
48
|
+
const toolPath = isWindows
|
|
49
|
+
? join(os.homedir(), '.dotnet', 'tools', `${TOOL_NAME}.exe`)
|
|
50
|
+
: join(os.homedir(), '.dotnet', 'tools', TOOL_NAME);
|
|
51
|
+
|
|
52
|
+
// Try running the tool directly first
|
|
53
|
+
const proc = spawn(TOOL_NAME, [], {
|
|
54
|
+
stdio: 'inherit',
|
|
55
|
+
shell: isWindows
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
proc.on('error', () => {
|
|
59
|
+
// If direct execution fails, try the full path
|
|
60
|
+
const proc2 = spawn(toolPath, [], { stdio: 'inherit' });
|
|
61
|
+
proc2.on('error', (err) => {
|
|
62
|
+
console.error(`Error running ${TOOL_NAME}: ${err.message}`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
proc.on('close', (code) => {
|
|
68
|
+
process.exit(code || 0);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function main() {
|
|
73
|
+
try {
|
|
74
|
+
// Check if .NET is installed
|
|
75
|
+
const dotnetInstalled = await checkDotnetInstalled();
|
|
76
|
+
if (!dotnetInstalled) {
|
|
77
|
+
console.error('ERROR: .NET SDK is not installed.');
|
|
78
|
+
console.error('Please install .NET 9.0 SDK from: https://dotnet.microsoft.com/download');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Check if the tool is installed
|
|
83
|
+
const toolInstalled = await checkToolInstalled();
|
|
84
|
+
if (!toolInstalled) {
|
|
85
|
+
await installTool();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Run the tool
|
|
89
|
+
await runTool();
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error(`Error: ${error.message}`);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dotnet-ai-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP Server for .NET AI development - provides real code samples from Semantic Kernel, OpenAI .NET, MCP C# SDK, and more",
|
|
5
|
+
"bin": {
|
|
6
|
+
"dotnet-ai-mcp-server": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node ./scripts/postinstall.js"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"mcp",
|
|
13
|
+
"dotnet",
|
|
14
|
+
"ai",
|
|
15
|
+
"semantic-kernel",
|
|
16
|
+
"openai",
|
|
17
|
+
"claude",
|
|
18
|
+
"copilot",
|
|
19
|
+
"llm",
|
|
20
|
+
"model-context-protocol"
|
|
21
|
+
],
|
|
22
|
+
"author": "Arbel Hodesman",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/ArbelH/dotnet-ai-mcp-server"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=16.0.0"
|
|
30
|
+
},
|
|
31
|
+
"os": [
|
|
32
|
+
"darwin",
|
|
33
|
+
"linux",
|
|
34
|
+
"win32"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
|
|
5
|
+
const NUGET_PACKAGE = 'DotNetAIMcpServer';
|
|
6
|
+
|
|
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
|
+
}
|
|
14
|
+
|
|
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
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function installTool() {
|
|
28
|
+
console.log(`Installing ${NUGET_PACKAGE} dotnet tool...`);
|
|
29
|
+
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'
|
|
41
|
+
});
|
|
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
|
+
}
|
|
49
|
+
});
|
|
50
|
+
updateProc.on('error', reject);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
proc.on('error', reject);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function main() {
|
|
58
|
+
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
|
+
}
|
|
70
|
+
|
|
71
|
+
// Check if already installed
|
|
72
|
+
const toolInstalled = await checkToolInstalled();
|
|
73
|
+
if (toolInstalled) {
|
|
74
|
+
console.log(`${NUGET_PACKAGE} is already installed.`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Install the tool
|
|
79
|
+
await installTool();
|
|
80
|
+
} 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');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
main();
|