svrnty-mcp-server/AGENT-PRIMER.md
Svrnty 516e1479c6 docs: comprehensive AI coding assistant research and MCP-first implementation plan
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>
2025-10-22 21:00:34 -04:00

22 KiB

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

# 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

# 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

# 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

{
  "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:

<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:

# 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:

{
  "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):

{
  "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:

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):

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:

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:

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:

services.AddTransient<IMcpTool, SearchDatabaseTool>();

If API Endpoints Detected:

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:

{
  "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:

cp /path/to/OpenHarbor.MCP/.editorconfig /path/to/YourApp/.editorconfig

4.3 .gitignore Updates

Add MCP-specific entries to target project's .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

# 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:

# 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):

# Run with HTTP transport
dotnet run --launch-profile McpHttp

# Test MCP endpoint
curl http://localhost:5000/mcp/tools

Expected response:

{
  "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:

#!/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:

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

{
  "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:

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:

{
  "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:

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

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

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:

{
  "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.jsonMcp.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.