svrnty-mcp-server/AGENT-PRIMER.md
Svrnty 0c27de4162 refactor: rename OpenHarbor.MCP to Svrnty.MCP across all libraries
- Renamed all directories: OpenHarbor.MCP.* → Svrnty.MCP.*
- Updated all namespaces in 179 C# files
- Renamed 20 .csproj files and 3 .sln files
- Updated 193 documentation references
- Updated 33 references in main CODEX codebase
- Updated Codex.sln with new paths
- Build verified: 0 errors

Preparing for extraction to standalone repositories.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 21:04:17 -04:00

833 lines
22 KiB
Markdown

# AGENT-PRIMER: Svrnty.MCP Automated Setup
**Purpose**: This document guides AI agents to automatically analyze a target system and configure Svrnty.MCP integration with minimal human intervention.
**Target Audience**: AI assistants (Claude, ChatGPT, etc.) helping developers integrate MCP server capabilities into .NET applications.
---
## Overview
Svrnty.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/Svrnty.MCP/src/Svrnty.MCP.AspNetCore/Svrnty.MCP.AspNetCore.csproj" />
<!-- OR use NuGet when published -->
<!-- <PackageReference Include="Svrnty.MCP.AspNetCore" Version="1.0.0" /> -->
</ItemGroup>
```
**Installation command**:
```bash
# Via project reference (development)
dotnet add reference /path/to/Svrnty.MCP/src/Svrnty.MCP.AspNetCore/Svrnty.MCP.AspNetCore.csproj
# Via NuGet (when published)
# dotnet add package Svrnty.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 Svrnty.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 Svrnty.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 Svrnty.MCP.Core.Abstractions;
using Svrnty.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 Svrnty.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 Svrnty.MCP root)
**Copy to target project** if needed:
```bash
cp /path/to/Svrnty.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 Svrnty.MCP:
```
samples/CodexMcpServer/
├── CodexMcpServer.csproj # References Svrnty.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/Svrnty.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 Svrnty.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 Svrnty.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
- **Svrnty.MCP Documentation**: `/docs/` folder in this repository
- **MCP Specification**: https://spec.modelcontextprotocol.io
- **CODEX Integration Example**: `samples/CodexMcpServer/`
- **Test Examples**: `tests/Svrnty.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.