Skip to content

Commit 04e0415

Browse files
MCP
1 parent 0ddf9bf commit 04e0415

File tree

10 files changed

+753
-156
lines changed

10 files changed

+753
-156
lines changed

RestClient.Net.McpGenerator/McpToolGenerator.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,18 +137,31 @@ string responseType
137137
var methodParams = new List<string>();
138138
var extensionCallArgs = new List<string>();
139139

140-
foreach (var param in parameters)
140+
// Separate required and optional parameters
141+
var requiredParams = parameters.Where(p => p.Required || (!p.Type.Contains('?', StringComparison.Ordinal) && p.DefaultValue == null)).ToList();
142+
var optionalParams = parameters.Where(p => !p.Required && (p.Type.Contains('?', StringComparison.Ordinal) || p.DefaultValue != null)).ToList();
143+
144+
// Add required parameters first
145+
foreach (var param in requiredParams)
141146
{
142-
methodParams.Add(FormatParameter(param));
147+
methodParams.Add($"{param.Type} {param.Name}");
143148
extensionCallArgs.Add(param.Name);
144149
}
145150

151+
// Add body if required (body is always required when present)
146152
if (hasBody)
147153
{
148154
methodParams.Add($"{bodyType} body");
149155
extensionCallArgs.Add("body");
150156
}
151157

158+
// Add optional parameters last
159+
foreach (var param in optionalParams)
160+
{
161+
methodParams.Add(FormatParameter(param));
162+
extensionCallArgs.Add(param.Name);
163+
}
164+
152165
var paramDescriptions = string.Join(
153166
"\n ",
154167
parameters.Select(p =>
@@ -174,7 +187,7 @@ string responseType
174187
return $$"""
175188
/// <summary>{{SanitizeDescription(summary)}}</summary>
176189
{{paramDescriptions}}
177-
[McpTool]
190+
[McpServerTool]
178191
[Description("{{SanitizeDescription(summary)}}")]
179192
public async Task<string> {{toolName}}({{methodParamsStr}})
180193
{
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<NoWarn>CA1303;CA2000</NoWarn>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.0" />
9+
<PackageReference Include="ModelContextProtocol" Version="0.4.0-preview.2" />
10+
<PackageReference Include="Urls" Version="1.0.0" />
11+
</ItemGroup>
12+
<ItemGroup>
13+
<ProjectReference Include="..\..\RestClient.Net\RestClient.Net.csproj" />
14+
<ProjectReference Include="..\NucliaDbClient\NucliaDbClient.csproj" />
15+
</ItemGroup>
16+
<ItemGroup>
17+
<!-- Include the generated MCP tools -->
18+
<Compile Include="..\NucliaDbClient\Generated\NucliaDbMcpTools.g.cs" Link="Generated\NucliaDbMcpTools.g.cs" />
19+
</ItemGroup>
20+
</Project>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.Extensions.Hosting;
3+
using ModelContextProtocol;
4+
5+
var builder = Host.CreateApplicationBuilder(args);
6+
7+
// Get the NucliaDB base URL from environment or use default
8+
var nucleaBaseUrl =
9+
Environment.GetEnvironmentVariable("NUCLIA_BASE_URL") ?? "http://localhost:8080/api/v1";
10+
11+
// Configure HttpClient with base URL
12+
builder.Services.AddHttpClient(
13+
Options.DefaultName,
14+
client =>
15+
{
16+
client.BaseAddress = new Uri(nucleaBaseUrl);
17+
client.Timeout = TimeSpan.FromSeconds(30);
18+
}
19+
);
20+
21+
// Add MCP server with NucliaDB tools
22+
builder.Services
23+
.AddMcpServer(new ServerInfo(name: "nuclia-db-mcp-server", version: "1.0.0"))
24+
.WithToolsFromAssembly();
25+
26+
var host = builder.Build();
27+
await host.RunAsync();
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# NucliaDB MCP Server
2+
3+
This is a Model Context Protocol (MCP) server that provides Claude Code with access to NucliaDB REST API operations.
4+
5+
## Prerequisites
6+
7+
- .NET 9.0 SDK
8+
- Docker and Docker Compose
9+
- Claude Code (latest version)
10+
11+
## Quick Start
12+
13+
### 1. Start NucliaDB and MCP Server
14+
15+
```bash
16+
cd Samples/NucliaDbClient.McpServer
17+
./start-mcp-server.sh
18+
```
19+
20+
This will:
21+
- Start NucliaDB via docker-compose (PostgreSQL + NucliaDB containers)
22+
- Wait for NucliaDB to be ready
23+
- Build and run the MCP server
24+
25+
### 2. Alternative: Run MCP Server Only
26+
27+
If NucliaDB is already running:
28+
29+
```bash
30+
./run-mcp-server.sh
31+
```
32+
33+
### 3. Stop NucliaDB
34+
35+
```bash
36+
./stop-nucliadb.sh
37+
```
38+
39+
## Configuration for Claude Code
40+
41+
### Option 1: Add to your existing MCP settings
42+
43+
Open your Claude Code MCP settings file and add the NucliaDB server configuration:
44+
45+
**Location:** `~/.config/Claude/claude_desktop_config.json` (Linux/macOS) or `%APPDATA%/Claude/claude_desktop_config.json` (Windows)
46+
47+
Add this to the `mcpServers` section:
48+
49+
```json
50+
{
51+
"mcpServers": {
52+
"nuclia-db": {
53+
"command": "/usr/local/share/dotnet/dotnet",
54+
"args": [
55+
"run",
56+
"--project",
57+
"/Users/christianfindlay/Documents/Code/RestClient.Net/Samples/NucliaDbClient.McpServer/NucliaDbClient.McpServer.csproj"
58+
],
59+
"env": {
60+
"NUCLIA_BASE_URL": "http://localhost:8080/api/v1"
61+
}
62+
}
63+
}
64+
}
65+
```
66+
67+
**Note:** Update the paths to match your system:
68+
- Replace `/usr/local/share/dotnet/dotnet` with your `dotnet` path (run `which dotnet` to find it)
69+
- Replace the project path with the actual path on your system
70+
71+
### Option 2: Use the provided configuration file
72+
73+
Copy the example configuration:
74+
75+
```bash
76+
cp claude-mcp-config.example.json ~/.config/Claude/claude_desktop_config.json
77+
```
78+
79+
Then edit the file to update paths for your system.
80+
81+
## Testing the MCP Server
82+
83+
1. Ensure NucliaDB is running:
84+
```bash
85+
curl http://localhost:8080
86+
```
87+
88+
2. In Claude Code, you should now see NucliaDB tools available in the MCP tools list
89+
90+
3. Try asking Claude to:
91+
- "List all knowledge boxes"
92+
- "Search for documents in knowledge box X"
93+
- "Ask a question on knowledge box Y"
94+
95+
## Available Tools
96+
97+
The MCP server provides access to all NucliaDB REST API operations, including:
98+
99+
- **Knowledge Box Management**: Get, create, delete knowledge boxes
100+
- **Search**: Full-text search, semantic search, catalog search
101+
- **Ask**: Question-answering on knowledge bases
102+
- **Resources**: Create, read, update, delete resources
103+
- **Labels & Entities**: Manage labels and entity recognition
104+
- **Configuration**: Configure models and settings
105+
106+
See the [generated MCP tools](../NucliaDbClient/Generated/NucliaDbMcpTools.g.cs) for the complete list.
107+
108+
## Environment Variables
109+
110+
- `NUCLIA_BASE_URL`: NucliaDB API base URL (default: `http://localhost:8080/api/v1`)
111+
112+
## Troubleshooting
113+
114+
### NucliaDB won't start
115+
116+
```bash
117+
# Check if ports are in use
118+
lsof -i :8080
119+
lsof -i :5432
120+
121+
# Check docker logs
122+
docker-compose logs
123+
```
124+
125+
### MCP Server connection issues
126+
127+
1. Check that NucliaDB is accessible:
128+
```bash
129+
curl http://localhost:8080/api/v1
130+
```
131+
132+
2. Verify the `dotnet` path in your Claude Code config:
133+
```bash
134+
which dotnet
135+
```
136+
137+
3. Check Claude Code logs for MCP connection errors
138+
139+
### Build errors
140+
141+
```bash
142+
cd /Users/christianfindlay/Documents/Code/RestClient.Net
143+
dotnet build
144+
```
145+
146+
## Architecture
147+
148+
This MCP server is automatically generated from the NucliaDB OpenAPI specification:
149+
150+
1. **OpenAPI Spec** (`Samples/NucliaDbClient/api.yaml`) defines the NucliaDB REST API
151+
2. **RestClient.Net.OpenApiGenerator** generates C# extension methods from the spec
152+
3. **RestClient.Net.McpGenerator** generates MCP tool wrappers around the extension methods
153+
4. **NucliaDbClient.McpServer** hosts the MCP server using the generated tools
154+
155+
## Development
156+
157+
To regenerate the MCP tools after updating the OpenAPI spec:
158+
159+
```bash
160+
cd /Users/christianfindlay/Documents/Code/RestClient.Net
161+
162+
# Regenerate the API client
163+
dotnet run --project RestClient.Net.OpenApiGenerator.Cli/RestClient.Net.OpenApiGenerator.Cli.csproj -- \
164+
-u Samples/NucliaDbClient/api.yaml \
165+
-o Samples/NucliaDbClient/Generated \
166+
-n NucliaDB.Generated \
167+
-c NucliaDBApiExtensions
168+
169+
# Regenerate the MCP tools
170+
dotnet run --project RestClient.Net.McpGenerator.Cli/RestClient.Net.McpGenerator.Cli.csproj -- \
171+
--openapi-url Samples/NucliaDbClient/api.yaml \
172+
--output-file Samples/NucliaDbClient/Generated/NucliaDbMcpTools.g.cs \
173+
--namespace NucliaDB.Mcp \
174+
--server-name NucliaDb \
175+
--ext-namespace NucliaDB.Generated
176+
177+
# Rebuild the MCP server
178+
dotnet build Samples/NucliaDbClient.McpServer
179+
```

0 commit comments

Comments
 (0)