# 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 "" *.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 ``` **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(); }) .Build(); // Start MCP server on stdio var mcpServer = host.Services.GetRequiredService(); 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 { ["parameter1"] = new() { Type = "string", Description = "Description of parameter1", Required = true }, ["parameter2"] = new() { Type = "number", Description = "Optional numeric parameter", Required = false } } }; public async Task ExecuteAsync( Dictionary 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 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 { ["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 ExecuteAsync( Dictionary 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 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 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(); ``` #### If API Endpoints Detected: ```csharp public class ListEndpointsTool : IMcpTool { private readonly ILogger _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() }; public async Task ExecuteAsync( Dictionary 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 { ["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 ExecuteAsync( Dictionary 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(); // Register CODEX tools builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); 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.