Research conducted on modern AI coding assistants (Cursor, GitHub Copilot, Cline,
Aider, Windsurf, Replit Agent) to understand architecture patterns, context management,
code editing workflows, and tool use protocols.
Key Decision: Pivoted from building full CLI (40-50h) to validation-driven MCP-first
approach (10-15h). Build 5 core CODEX MCP tools that work with ANY coding assistant,
validate adoption over 2-4 weeks, then decide on full CLI if demand proven.
Files:
- research/ai-systems/modern-coding-assistants-architecture.md (comprehensive research)
- research/ai-systems/codex-coding-assistant-implementation-plan.md (original CLI plan, preserved)
- research/ai-systems/codex-mcp-tools-implementation-plan.md (approved MCP-first plan)
- ideas/registry.json (updated with approved MCP tools proposal)
Architech Validation: APPROVED with pivot to MCP-first approach
Human Decision: Approved (pragmatic validation-driven development)
Next: Begin Phase 1 implementation (10-15 hours, 5 core MCP tools)
🤖 Generated with CODEX Research System
Co-Authored-By: The Archivist <archivist@codex.svrnty.io>
Co-Authored-By: The Architech <architech@codex.svrnty.io>
Co-Authored-By: Mathias Beaulieu-Duncan <mat@svrnty.io>
833 lines
22 KiB
Markdown
833 lines
22 KiB
Markdown
# AGENT-PRIMER: OpenHarbor.MCP Automated Setup
|
|
|
|
**Purpose**: This document guides AI agents to automatically analyze a target system and configure OpenHarbor.MCP integration with minimal human intervention.
|
|
|
|
**Target Audience**: AI assistants (Claude, ChatGPT, etc.) helping developers integrate MCP server capabilities into .NET applications.
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
OpenHarbor.MCP is a **standalone, reusable .NET library** that adds Model Context Protocol (MCP) server capabilities to any .NET application. This primer enables AI-automated configuration by walking through system analysis, configuration generation, and validation.
|
|
|
|
**What you'll automate:**
|
|
1. System analysis (detect .NET version, project type, dependencies)
|
|
2. Configuration file generation (appsettings.json, mcp-config.json, Program.cs)
|
|
3. Sample MCP tool creation based on detected features
|
|
4. Environment setup and validation
|
|
|
|
---
|
|
|
|
## Step 1: System Analysis
|
|
|
|
**Goal**: Understand the target system to generate appropriate configuration.
|
|
|
|
### Tasks for AI Agent:
|
|
|
|
#### 1.1 Detect .NET Environment
|
|
```bash
|
|
# Check .NET SDK version
|
|
dotnet --version
|
|
|
|
# List installed SDKs
|
|
dotnet --list-sdks
|
|
|
|
# List installed runtimes
|
|
dotnet --list-runtimes
|
|
```
|
|
|
|
**Required**: .NET 8.0 SDK or higher
|
|
**Action if missing**: Provide installation instructions for user's OS
|
|
|
|
#### 1.2 Analyze Project Structure
|
|
```bash
|
|
# Find .csproj files
|
|
find . -name "*.csproj" -type f
|
|
|
|
# Examine project type
|
|
grep -E "<Project Sdk|<TargetFramework>" *.csproj
|
|
```
|
|
|
|
**Detect**:
|
|
- Project type (Web API, Console, Worker Service, etc.)
|
|
- Target framework (net8.0, net9.0)
|
|
- Existing dependencies
|
|
|
|
#### 1.3 Identify Integration Points
|
|
```bash
|
|
# Check for existing HTTP endpoints
|
|
grep -r "MapControllers\|MapGet\|MapPost" --include="*.cs"
|
|
|
|
# Check for dependency injection setup
|
|
grep -r "AddScoped\|AddSingleton\|AddTransient" --include="*.cs"
|
|
|
|
# Detect database usage
|
|
grep -r "DbContext\|AddDbContext" --include="*.cs"
|
|
```
|
|
|
|
**Output**: JSON summary of detected features
|
|
```json
|
|
{
|
|
"dotnetVersion": "8.0.100",
|
|
"projectType": "AspNetCore.WebApi",
|
|
"targetFramework": "net8.0",
|
|
"features": {
|
|
"hasDatabase": true,
|
|
"databaseProvider": "PostgreSQL",
|
|
"hasAuthentication": true,
|
|
"hasSwagger": true,
|
|
"hasCQRS": true
|
|
},
|
|
"dependencies": [
|
|
"Microsoft.EntityFrameworkCore",
|
|
"Npgsql.EntityFrameworkCore.PostgreSQL",
|
|
"Swashbuckle.AspNetCore"
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Step 2: Generate Configuration
|
|
|
|
**Goal**: Create configuration files tailored to the detected system.
|
|
|
|
### 2.1 NuGet Package References
|
|
|
|
**Add to project's .csproj**:
|
|
```xml
|
|
<ItemGroup>
|
|
<!-- Core MCP library -->
|
|
<ProjectReference Include="/path/to/OpenHarbor.MCP/src/OpenHarbor.MCP.AspNetCore/OpenHarbor.MCP.AspNetCore.csproj" />
|
|
|
|
<!-- OR use NuGet when published -->
|
|
<!-- <PackageReference Include="OpenHarbor.MCP.AspNetCore" Version="1.0.0" /> -->
|
|
</ItemGroup>
|
|
```
|
|
|
|
**Installation command**:
|
|
```bash
|
|
# Via project reference (development)
|
|
dotnet add reference /path/to/OpenHarbor.MCP/src/OpenHarbor.MCP.AspNetCore/OpenHarbor.MCP.AspNetCore.csproj
|
|
|
|
# Via NuGet (when published)
|
|
# dotnet add package OpenHarbor.MCP.AspNetCore
|
|
```
|
|
|
|
### 2.2 appsettings.json Configuration
|
|
|
|
**Create/update `appsettings.json`** with MCP section:
|
|
```json
|
|
{
|
|
"Mcp": {
|
|
"Server": {
|
|
"Name": "YourAppMcpServer",
|
|
"Version": "1.0.0",
|
|
"Description": "MCP server for YourApp - provides AI agents access to application features",
|
|
"Vendor": "YourCompany"
|
|
},
|
|
"Transport": {
|
|
"Type": "Http",
|
|
"Options": {
|
|
"BufferSize": 8192,
|
|
"EnableLogging": true
|
|
}
|
|
},
|
|
"Security": {
|
|
"EnablePermissions": true,
|
|
"DefaultDenyAll": true,
|
|
"RateLimit": {
|
|
"Enabled": true,
|
|
"RequestsPerMinute": 60,
|
|
"BurstSize": 10
|
|
},
|
|
"AuditLogging": {
|
|
"Enabled": true,
|
|
"LogLevel": "Information"
|
|
}
|
|
},
|
|
"Agents": {
|
|
"Default": {
|
|
"Permissions": ["tools:list", "tools:execute"],
|
|
"RateLimitOverride": null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Customize based on detected features**:
|
|
- **If database detected**: Add `"tools:database:*"` permissions for agents needing DB access
|
|
- **If authentication exists**: Add agent-specific scopes
|
|
- **If production**: Set `"DefaultDenyAll": true` and explicit permissions only
|
|
|
|
### 2.3 mcp-config.json (Optional)
|
|
|
|
**Create standalone MCP configuration** (CLI usage):
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"yourapp": {
|
|
"command": "dotnet",
|
|
"args": ["run", "--project", "/path/to/YourApp.csproj"],
|
|
"transport": "http",
|
|
"permissions": {
|
|
"allowedTools": ["tool1", "tool2"],
|
|
"rateLimitRpm": 60
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2.4 Program.cs Integration
|
|
|
|
**Add MCP services to dependency injection**:
|
|
|
|
#### For ASP.NET Core Web API:
|
|
```csharp
|
|
using OpenHarbor.MCP.AspNetCore;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Existing services...
|
|
builder.Services.AddControllers();
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
builder.Services.AddSwaggerGen();
|
|
|
|
// ADD: MCP Server
|
|
builder.Services.AddMcpServer(builder.Configuration.GetSection("Mcp"));
|
|
|
|
var app = builder.Build();
|
|
|
|
// Existing middleware...
|
|
if (app.Environment.IsDevelopment())
|
|
{
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI();
|
|
}
|
|
|
|
app.UseHttpsRedirection();
|
|
app.UseAuthorization();
|
|
|
|
// ADD: MCP endpoints
|
|
app.MapMcpEndpoints();
|
|
|
|
app.MapControllers();
|
|
|
|
app.Run();
|
|
```
|
|
|
|
#### For Console Application (HTTP transport):
|
|
```csharp
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using OpenHarbor.MCP.Infrastructure;
|
|
|
|
var host = Host.CreateDefaultBuilder(args)
|
|
.ConfigureServices((context, services) =>
|
|
{
|
|
// Add MCP Server
|
|
services.AddMcpServer(context.Configuration.GetSection("Mcp"));
|
|
|
|
// Register custom tools
|
|
services.AddTransient<IYourCustomTool, YourCustomToolImplementation>();
|
|
})
|
|
.Build();
|
|
|
|
// Start MCP server on stdio
|
|
var mcpServer = host.Services.GetRequiredService<IMcpServer>();
|
|
await mcpServer.StartAsync(CancellationToken.None);
|
|
|
|
await host.RunAsync();
|
|
```
|
|
|
|
---
|
|
|
|
## Step 3: Create Sample Tools
|
|
|
|
**Goal**: Generate MCP tools based on detected system features.
|
|
|
|
### 3.1 Tool Template
|
|
|
|
**Basic tool structure**:
|
|
```csharp
|
|
using OpenHarbor.MCP.Core.Abstractions;
|
|
using OpenHarbor.MCP.Core.Models;
|
|
|
|
namespace YourApp.Mcp.Tools;
|
|
|
|
public class SampleTool : IMcpTool
|
|
{
|
|
public string Name => "sample_tool";
|
|
public string Description => "Describes what this tool does for AI agents";
|
|
|
|
public McpToolSchema Schema => new()
|
|
{
|
|
Type = "object",
|
|
Properties = new Dictionary<string, McpProperty>
|
|
{
|
|
["parameter1"] = new()
|
|
{
|
|
Type = "string",
|
|
Description = "Description of parameter1",
|
|
Required = true
|
|
},
|
|
["parameter2"] = new()
|
|
{
|
|
Type = "number",
|
|
Description = "Optional numeric parameter",
|
|
Required = false
|
|
}
|
|
}
|
|
};
|
|
|
|
public async Task<McpToolResult> ExecuteAsync(
|
|
Dictionary<string, object> parameters,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
// Extract parameters
|
|
var param1 = parameters["parameter1"].ToString();
|
|
var param2 = parameters.ContainsKey("parameter2")
|
|
? Convert.ToDouble(parameters["parameter2"])
|
|
: 0.0;
|
|
|
|
// Execute tool logic
|
|
var result = await PerformWorkAsync(param1, param2, cancellationToken);
|
|
|
|
// Return result
|
|
return McpToolResult.Success(result);
|
|
}
|
|
|
|
private async Task<object> PerformWorkAsync(
|
|
string param1,
|
|
double param2,
|
|
CancellationToken ct)
|
|
{
|
|
// TODO: Implement tool logic
|
|
return new { message = "Tool executed successfully" };
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3.2 Auto-Generated Tools Based on Detected Features
|
|
|
|
#### If Database Detected:
|
|
```csharp
|
|
public class SearchDatabaseTool : IMcpTool
|
|
{
|
|
private readonly YourDbContext _context;
|
|
|
|
public SearchDatabaseTool(YourDbContext context)
|
|
{
|
|
_context = context;
|
|
}
|
|
|
|
public string Name => "search_database";
|
|
public string Description => "Search database entities by query string";
|
|
|
|
public McpToolSchema Schema => new()
|
|
{
|
|
Type = "object",
|
|
Properties = new Dictionary<string, McpProperty>
|
|
{
|
|
["query"] = new()
|
|
{
|
|
Type = "string",
|
|
Description = "Search query",
|
|
Required = true
|
|
},
|
|
["entityType"] = new()
|
|
{
|
|
Type = "string",
|
|
Description = "Entity type to search (e.g., 'users', 'products')",
|
|
Required = true
|
|
},
|
|
["limit"] = new()
|
|
{
|
|
Type = "number",
|
|
Description = "Max results to return (default: 10)",
|
|
Required = false
|
|
}
|
|
}
|
|
};
|
|
|
|
public async Task<McpToolResult> ExecuteAsync(
|
|
Dictionary<string, object> parameters,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var query = parameters["query"].ToString();
|
|
var entityType = parameters["entityType"].ToString();
|
|
var limit = parameters.ContainsKey("limit")
|
|
? Convert.ToInt32(parameters["limit"])
|
|
: 10;
|
|
|
|
// Route to appropriate entity search
|
|
var results = entityType.ToLower() switch
|
|
{
|
|
"users" => await SearchUsersAsync(query, limit, cancellationToken),
|
|
"products" => await SearchProductsAsync(query, limit, cancellationToken),
|
|
_ => throw new ArgumentException($"Unknown entity type: {entityType}")
|
|
};
|
|
|
|
return McpToolResult.Success(results);
|
|
}
|
|
|
|
private async Task<object> SearchUsersAsync(string query, int limit, CancellationToken ct)
|
|
{
|
|
return await _context.Users
|
|
.Where(u => u.Name.Contains(query) || u.Email.Contains(query))
|
|
.Take(limit)
|
|
.Select(u => new { u.Id, u.Name, u.Email })
|
|
.ToListAsync(ct);
|
|
}
|
|
|
|
private async Task<object> SearchProductsAsync(string query, int limit, CancellationToken ct)
|
|
{
|
|
return await _context.Products
|
|
.Where(p => p.Name.Contains(query) || p.Description.Contains(query))
|
|
.Take(limit)
|
|
.Select(p => new { p.Id, p.Name, p.Description, p.Price })
|
|
.ToListAsync(ct);
|
|
}
|
|
}
|
|
```
|
|
|
|
**Register in Program.cs**:
|
|
```csharp
|
|
services.AddTransient<IMcpTool, SearchDatabaseTool>();
|
|
```
|
|
|
|
#### If API Endpoints Detected:
|
|
```csharp
|
|
public class ListEndpointsTool : IMcpTool
|
|
{
|
|
private readonly ILogger<ListEndpointsTool> _logger;
|
|
|
|
public string Name => "list_endpoints";
|
|
public string Description => "List all available API endpoints in the application";
|
|
|
|
public McpToolSchema Schema => new()
|
|
{
|
|
Type = "object",
|
|
Properties = new Dictionary<string, McpProperty>()
|
|
};
|
|
|
|
public async Task<McpToolResult> ExecuteAsync(
|
|
Dictionary<string, object> parameters,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
// Return list of endpoints (could introspect from routing)
|
|
var endpoints = new[]
|
|
{
|
|
new { Method = "GET", Path = "/api/users", Description = "List users" },
|
|
new { Method = "POST", Path = "/api/users", Description = "Create user" },
|
|
new { Method = "GET", Path = "/api/products", Description = "List products" }
|
|
};
|
|
|
|
return McpToolResult.Success(endpoints);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Step 4: Setup Development Environment
|
|
|
|
**Goal**: Configure IDE and development tools for OpenHarbor.MCP.
|
|
|
|
### 4.1 Launch Settings (launchSettings.json)
|
|
|
|
**Create/update `Properties/launchSettings.json`**:
|
|
```json
|
|
{
|
|
"profiles": {
|
|
"McpStdio": {
|
|
"commandName": "Project",
|
|
"launchBrowser": false,
|
|
"environmentVariables": {
|
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
|
"MCP_TRANSPORT": "stdio"
|
|
}
|
|
},
|
|
"McpHttp": {
|
|
"commandName": "Project",
|
|
"launchBrowser": true,
|
|
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
|
"environmentVariables": {
|
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
|
"MCP_TRANSPORT": "http"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 4.2 .editorconfig (Already provided in OpenHarbor.MCP root)
|
|
|
|
**Copy to target project** if needed:
|
|
```bash
|
|
cp /path/to/OpenHarbor.MCP/.editorconfig /path/to/YourApp/.editorconfig
|
|
```
|
|
|
|
### 4.3 .gitignore Updates
|
|
|
|
**Add MCP-specific entries** to target project's `.gitignore`:
|
|
```gitignore
|
|
# MCP logs and temp files
|
|
mcp-logs/
|
|
*.mcp.log
|
|
mcp-config.local.json
|
|
```
|
|
|
|
---
|
|
|
|
## Step 5: Validation
|
|
|
|
**Goal**: Verify setup is correct and functional.
|
|
|
|
### 5.1 Build Verification
|
|
```bash
|
|
# Restore dependencies
|
|
dotnet restore
|
|
|
|
# Build project
|
|
dotnet build
|
|
|
|
# Expected: Build succeeded. 0 Warning(s). 0 Error(s).
|
|
```
|
|
|
|
### 5.2 Test MCP Server Startup
|
|
|
|
#### Console/Stdio Mode:
|
|
```bash
|
|
# Run MCP server
|
|
dotnet run
|
|
|
|
# Expected output:
|
|
# MCP Server started (HTTP transport)
|
|
# Registered tools: sample_tool, search_database, list_endpoints
|
|
# Ready for input...
|
|
```
|
|
|
|
#### HTTP Mode (if applicable):
|
|
```bash
|
|
# Run with HTTP transport
|
|
dotnet run --launch-profile McpHttp
|
|
|
|
# Test MCP endpoint
|
|
curl http://localhost:5000/mcp/tools
|
|
```
|
|
|
|
**Expected response**:
|
|
```json
|
|
{
|
|
"tools": [
|
|
{
|
|
"name": "sample_tool",
|
|
"description": "Describes what this tool does for AI agents",
|
|
"schema": { ... }
|
|
},
|
|
{
|
|
"name": "search_database",
|
|
"description": "Search database entities by query string",
|
|
"schema": { ... }
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 5.3 Test Tool Execution
|
|
|
|
**Create test script** `test-mcp.sh`:
|
|
```bash
|
|
#!/bin/bash
|
|
|
|
# Test listing tools
|
|
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | dotnet run
|
|
|
|
# Test executing a tool
|
|
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"sample_tool","arguments":{"parameter1":"test"}}}' | dotnet run
|
|
```
|
|
|
|
**Run tests**:
|
|
```bash
|
|
chmod +x test-mcp.sh
|
|
./test-mcp.sh
|
|
```
|
|
|
|
### 5.4 Integration Test (Claude Desktop Example)
|
|
|
|
**If Claude Desktop is available**, create MCP config:
|
|
|
|
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"yourapp": {
|
|
"command": "dotnet",
|
|
"args": ["run", "--project", "/absolute/path/to/YourApp.csproj"],
|
|
"transport": "http"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Restart Claude Desktop**, then test:
|
|
1. Type: "List available tools" (should show your MCP tools)
|
|
2. Execute: "Use sample_tool with parameter1='hello'"
|
|
3. Verify: Tool executes and returns expected result
|
|
|
|
---
|
|
|
|
## Example: CODEX Integration Walkthrough
|
|
|
|
**Scenario**: CODEX is a knowledge management system that needs to expose its document search, retrieval, and tagging features to AI agents via MCP.
|
|
|
|
### Step 1: System Analysis (Automated)
|
|
|
|
**Run analysis**:
|
|
```bash
|
|
cd /home/svrnty/codex/CODEX
|
|
dotnet --version # Output: 8.0.100
|
|
find . -name "*.csproj" | head -5
|
|
```
|
|
|
|
**Detected**:
|
|
- Project: ASP.NET Core Web API (Codex.Api)
|
|
- Framework: net8.0
|
|
- Database: PostgreSQL (Npgsql.EntityFrameworkCore.PostgreSQL)
|
|
- Features: CQRS (OpenHarbor.CQRS), vector search (Pgvector), semantic search (ONNX)
|
|
|
|
### Step 2: Generate Configuration
|
|
|
|
**Created** `samples/CodexMcpServer/` in OpenHarbor.MCP:
|
|
```
|
|
samples/CodexMcpServer/
|
|
├── CodexMcpServer.csproj # References OpenHarbor.MCP.AspNetCore
|
|
├── Program.cs # MCP server setup with CODEX API client
|
|
├── appsettings.json # CODEX-specific MCP config
|
|
├── Tools/
|
|
│ ├── SearchCodexTool.cs # search_codex tool
|
|
│ ├── GetDocumentTool.cs # get_document tool
|
|
│ ├── ListDocumentsTool.cs # list_documents tool
|
|
│ ├── SearchByTagTool.cs # search_by_tag tool
|
|
│ ├── GetDocumentSectionsTool.cs # get_document_sections tool
|
|
│ └── ListTagsTool.cs # list_tags tool
|
|
└── Services/
|
|
└── CodexApiClient.cs # HTTP client for CODEX API (localhost:5050)
|
|
```
|
|
|
|
**appsettings.json**:
|
|
```json
|
|
{
|
|
"Mcp": {
|
|
"Server": {
|
|
"Name": "CodexMcpServer",
|
|
"Version": "1.0.0",
|
|
"Description": "CODEX Knowledge Gateway - Provides AI agents secure access to CODEX documents, search, and tags",
|
|
"Vendor": "Svrnty"
|
|
},
|
|
"Transport": {
|
|
"Type": "Http"
|
|
},
|
|
"Security": {
|
|
"EnablePermissions": true,
|
|
"DefaultDenyAll": true,
|
|
"Agents": {
|
|
"claude-desktop": {
|
|
"Permissions": ["tools:codex:search", "tools:codex:read", "tools:codex:tags"],
|
|
"RateLimitOverride": 120
|
|
},
|
|
"public-agent": {
|
|
"Permissions": ["tools:codex:search"],
|
|
"RateLimitOverride": 30
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"CodexApi": {
|
|
"BaseUrl": "http://localhost:5050",
|
|
"Timeout": 30
|
|
}
|
|
}
|
|
```
|
|
|
|
### Step 3: Create CODEX Tools
|
|
|
|
**SearchCodexTool.cs**:
|
|
```csharp
|
|
public class SearchCodexTool : IMcpTool
|
|
{
|
|
private readonly ICodexApiClient _codexApi;
|
|
|
|
public string Name => "search_codex";
|
|
public string Description => "Search CODEX knowledge base using semantic or keyword search";
|
|
|
|
public McpToolSchema Schema => new()
|
|
{
|
|
Type = "object",
|
|
Properties = new Dictionary<string, McpProperty>
|
|
{
|
|
["query"] = new() { Type = "string", Description = "Search query", Required = true },
|
|
["searchType"] = new() { Type = "string", Description = "Search type: 'semantic' or 'keyword' (default: semantic)", Required = false },
|
|
["limit"] = new() { Type = "number", Description = "Max results (default: 10)", Required = false }
|
|
}
|
|
};
|
|
|
|
public async Task<McpToolResult> ExecuteAsync(
|
|
Dictionary<string, object> parameters,
|
|
CancellationToken ct = default)
|
|
{
|
|
var query = parameters["query"].ToString();
|
|
var searchType = parameters.GetValueOrDefault("searchType", "semantic").ToString();
|
|
var limit = Convert.ToInt32(parameters.GetValueOrDefault("limit", 10));
|
|
|
|
var results = await _codexApi.SearchAsync(query, searchType, limit, ct);
|
|
return McpToolResult.Success(results);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Step 4: Register Tools in Program.cs
|
|
|
|
```csharp
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
builder.Services.AddMcpServer(builder.Configuration.GetSection("Mcp"));
|
|
builder.Services.AddSingleton<ICodexApiClient, CodexApiClient>();
|
|
|
|
// Register CODEX tools
|
|
builder.Services.AddTransient<IMcpTool, SearchCodexTool>();
|
|
builder.Services.AddTransient<IMcpTool, GetDocumentTool>();
|
|
builder.Services.AddTransient<IMcpTool, ListDocumentsTool>();
|
|
builder.Services.AddTransient<IMcpTool, SearchByTagTool>();
|
|
builder.Services.AddTransient<IMcpTool, GetDocumentSectionsTool>();
|
|
builder.Services.AddTransient<IMcpTool, ListTagsTool>();
|
|
|
|
var app = builder.Build();
|
|
app.MapMcpEndpoints();
|
|
app.Run();
|
|
```
|
|
|
|
### Step 5: Validate
|
|
|
|
```bash
|
|
cd samples/CodexMcpServer
|
|
dotnet run
|
|
|
|
# Test with echo
|
|
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | dotnet run
|
|
|
|
# Expected: 6 tools listed (search_codex, get_document, etc.)
|
|
```
|
|
|
|
**Claude Desktop Integration**:
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"codex": {
|
|
"command": "dotnet",
|
|
"args": ["run", "--project", "/home/svrnty/codex/OpenHarbor.MCP/samples/CodexMcpServer/CodexMcpServer.csproj"],
|
|
"transport": "http"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Result**: Claude can now search CODEX, retrieve documents, filter by tags, and access document sections with full permission enforcement and rate limiting.
|
|
|
|
---
|
|
|
|
## AI Agent Checklist
|
|
|
|
Use this checklist when assisting a developer with OpenHarbor.MCP integration:
|
|
|
|
- [ ] **System Analysis Complete**
|
|
- [ ] .NET 8.0 SDK detected
|
|
- [ ] Project type identified
|
|
- [ ] Dependencies analyzed
|
|
- [ ] Feature detection done (DB, auth, API, etc.)
|
|
|
|
- [ ] **Configuration Generated**
|
|
- [ ] NuGet package/project reference added
|
|
- [ ] appsettings.json updated with MCP section
|
|
- [ ] Program.cs modified for MCP registration
|
|
- [ ] launchSettings.json created/updated
|
|
|
|
- [ ] **Tools Created**
|
|
- [ ] At least 1 sample tool implemented
|
|
- [ ] Tools registered in DI container
|
|
- [ ] Tool permissions configured in appsettings.json
|
|
- [ ] Tool documentation written
|
|
|
|
- [ ] **Validation Passed**
|
|
- [ ] Project builds successfully
|
|
- [ ] MCP server starts without errors
|
|
- [ ] Tools are listed correctly
|
|
- [ ] Sample tool execution succeeds
|
|
- [ ] (Optional) Claude Desktop integration works
|
|
|
|
- [ ] **Documentation Updated**
|
|
- [ ] README.md includes MCP setup instructions
|
|
- [ ] Tool usage examples documented
|
|
- [ ] Configuration options explained
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Issue: "MCP server not starting"
|
|
**Solution**:
|
|
1. Check .NET version: `dotnet --version` (must be 8.0+)
|
|
2. Verify Program.cs has `services.AddMcpServer(...)` and `app.MapMcpEndpoints()`
|
|
3. Check appsettings.json for valid JSON syntax
|
|
4. Run `dotnet build` to see specific errors
|
|
|
|
### Issue: "Tools not appearing in Claude"
|
|
**Solution**:
|
|
1. Verify `claude_desktop_config.json` path is correct
|
|
2. Check absolute path to .csproj is correct
|
|
3. Restart Claude Desktop completely
|
|
4. Test server manually: `echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | dotnet run`
|
|
|
|
### Issue: "Permission denied when executing tool"
|
|
**Solution**:
|
|
1. Check `appsettings.json` → `Mcp.Security.Agents` section
|
|
2. Ensure agent has required permissions (e.g., `"tools:codex:search"`)
|
|
3. Verify `DefaultDenyAll` is set correctly
|
|
4. Check audit logs for permission failures
|
|
|
|
### Issue: "Rate limit exceeded"
|
|
**Solution**:
|
|
1. Increase `RateLimitOverride` for the agent in appsettings.json
|
|
2. Reduce request frequency from client
|
|
3. Disable rate limiting temporarily: `"RateLimit.Enabled": false`
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
After successful setup:
|
|
|
|
1. **Write Tests**: Create unit tests for custom tools (see OpenHarbor.MCP test examples)
|
|
2. **Add Observability**: Integrate logging, metrics, and tracing
|
|
3. **Secure Production**: Review permission model, enable HTTPS for HTTP transport
|
|
4. **Optimize Performance**: Add caching, connection pooling, batch operations
|
|
5. **Extend Tools**: Add more domain-specific tools based on application features
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
- **OpenHarbor.MCP Documentation**: `/docs/` folder in this repository
|
|
- **MCP Specification**: https://spec.modelcontextprotocol.io
|
|
- **CODEX Integration Example**: `samples/CodexMcpServer/`
|
|
- **Test Examples**: `tests/OpenHarbor.MCP.Integration.Tests/`
|
|
|
|
---
|
|
|
|
**AI Agent Note**: This primer is designed for you to execute autonomously. When a developer asks "set up MCP for my project," follow this guide step-by-step, adapting configurations to their specific environment. Always validate each step before proceeding to the next.
|