svrnty-mcp-client/README.md
Svrnty d936ad7856 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

549 lines
16 KiB
Markdown

# OpenHarbor.MCP.Client
**A modular, scalable, secure .NET library for consuming Model Context Protocol (MCP) servers**
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![.NET 8.0](https://img.shields.io/badge/.NET-8.0-512BD4)](https://dotnet.microsoft.com/download/dotnet/8.0)
[![Architecture: Clean](https://img.shields.io/badge/Architecture-Clean-green)](docs/architecture.md)
---
## What is OpenHarbor.MCP.Client?
OpenHarbor.MCP.Client is a **standalone, reusable .NET library** that enables any .NET application to act as an MCP client, allowing your application to discover and call tools exposed by MCP servers.
**Model Context Protocol (MCP)** is an industry-standard protocol backed by Anthropic that defines how AI agents communicate with external tools and data sources. Think of it as a universal adapter that lets your application safely access capabilities from remote MCP servers.
### Key Features
- **Modular & Reusable**: Copy to any .NET project, configure, and go
- **Clean Architecture**: Core abstractions, infrastructure implementation, ASP.NET Core integration
- **Security-First**: Connection validation, timeout handling, error recovery
- **Transport Flexibility**: HTTP (primary for production) and stdio (legacy for local tools)
- **AI-Automated Setup**: AGENT-PRIMER.md guides AI assistants to configure your integration automatically
- **TDD Foundation**: Built with test-driven development, comprehensive test coverage
- **Production-Ready**: Observability, error handling, connection pooling, retry logic
---
## Why OpenHarbor.MCP.Client?
**Problem**: Your .NET application needs to access tools and capabilities exposed by remote MCP servers (search, data processing, API access) but has no standardized way to connect.
**Solution**: OpenHarbor.MCP.Client transforms your application into an MCP client, allowing you to discover, validate, and call tools from any MCP server with proper error handling and connection management.
**Use Cases**:
- Connect your app to Claude Desktop's exposed tools
- Call tools from remote knowledge bases or search engines
- Integrate with third-party MCP servers for document processing
- Build AI-powered workflows that consume multiple MCP services
- Access enterprise MCP servers for data analysis and reporting
---
## Quick Start
### Prerequisites
- .NET 8.0 SDK or higher
- Your existing .NET application (Web API, Console, Worker Service, etc.)
- Access to one or more MCP servers (local or remote)
### Option 1: AI-Automated Setup (Recommended)
If you have access to Claude or another AI assistant:
1. Copy this entire folder to your project directory
2. Open your AI assistant and say: "Read AGENT-PRIMER.md and set up OpenHarbor.MCP.Client for my project"
3. The AI will analyze your system, generate configuration, and create sample client code automatically
### Option 2: Manual Setup
#### Step 1: Add Package Reference
```bash
# Via project reference (development)
dotnet add reference /path/to/OpenHarbor.MCP.Client/src/OpenHarbor.MCP.Client.AspNetCore/OpenHarbor.MCP.Client.AspNetCore.csproj
# OR via NuGet (when published)
# dotnet add package OpenHarbor.MCP.Client.AspNetCore
```
#### Step 2: Configure appsettings.json
Add MCP client configuration:
```json
{
"Mcp": {
"Client": {
"Name": "MyAppMcpClient",
"Version": "1.0.0",
"Description": "MCP client for MyApp"
},
"Servers": [
{
"Name": "codex-server",
"Transport": {
"Type": "Http",
"BaseUrl": "http://localhost:5050"
},
"Timeout": "00:00:30",
"Enabled": true
},
{
"Name": "remote-mcp-server",
"Transport": {
"Type": "Http",
"BaseUrl": "https://api.example.com/mcp"
},
"Timeout": "00:00:60",
"Enabled": true
}
],
"Connection": {
"MaxRetries": 3,
"RetryDelayMs": 1000,
"EnableConnectionPooling": true
}
}
}
```
#### Step 3: Update Program.cs
```csharp
using OpenHarbor.MCP.Client.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
// Add MCP client
builder.Services.AddMcpClient(builder.Configuration.GetSection("Mcp"));
var app = builder.Build();
app.Run();
```
#### Step 4: Use the Client to Call Tools
```csharp
using OpenHarbor.MCP.Client.Core.Abstractions;
public class MyService
{
private readonly IMcpClient _mcpClient;
public MyService(IMcpClient mcpClient)
{
_mcpClient = mcpClient;
}
public async Task<string> SearchCodexAsync(string query)
{
// List available tools from the codex-server
var tools = await _mcpClient.ListToolsAsync("codex-server");
// Call the search_codex tool
var result = await _mcpClient.CallToolAsync(
serverName: "codex-server",
toolName: "search_codex",
arguments: new Dictionary<string, object>
{
["query"] = query,
["maxResults"] = 10
}
);
return result.Content;
}
}
```
#### Step 5: Run and Test
```bash
# Ensure MCP servers are running
# Terminal 1: Start CODEX MCP Server
dotnet run --project /path/to/CodexMcpServer
# Server listens on http://localhost:5050
# Terminal 2: Run your client application
dotnet run
# The client will automatically connect to configured MCP servers via HTTP
# and be ready to call their tools
```
**Legacy Stdio Transport** (for local process-based tools):
```json
{
"Servers": [
{
"Name": "local-tool",
"Transport": {
"Type": "Stdio",
"Command": "dotnet",
"Args": ["run", "--project", "/path/to/tool", "--", "--stdio"]
},
"Enabled": true
}
]
}
```
Note: HTTP transport is recommended for production with remote servers, load balancing, and monitoring.
---
## Architecture
OpenHarbor.MCP.Client follows **Clean Architecture** principles:
```
┌─────────────────────────────────────────────────┐
│ OpenHarbor.MCP.Client.Cli (Executable) │
│ ┌───────────────────────────────────────────┐ │
│ │ OpenHarbor.MCP.Client.AspNetCore (DI) │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ OpenHarbor.MCP.Client.Infrastructure│ │ │
│ │ │ ┌───────────────────────────────┐ │ │ │
│ │ │ │ OpenHarbor.MCP.Client.Core │ │ │ │
│ │ │ │ - IMcpClient │ │ │ │
│ │ │ │ - IMcpServerConnection │ │ │ │
│ │ │ │ - IConnectionPool │ │ │ │
│ │ │ │ - Models (no dependencies) │ │ │ │
│ │ │ └───────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
```
### Projects
| Project | Purpose | Dependencies |
|---------|---------|--------------|
| **OpenHarbor.MCP.Client.Core** | Abstractions, interfaces, models | None |
| **OpenHarbor.MCP.Client.Infrastructure** | MCP client implementation, transports, connection management | Core, System.Text.Json |
| **OpenHarbor.MCP.Client.AspNetCore** | ASP.NET Core integration, DI extensions | Core, Infrastructure, ASP.NET Core |
| **OpenHarbor.MCP.Client.Cli** | Standalone CLI executable | All above |
See [Architecture Documentation](docs/architecture.md) for detailed design.
---
## Examples
### 1. CodexMcpClient (Knowledge Search)
Sample client application that connects to CODEX MCP Server:
```
samples/CodexMcpClient/
├── Services/
│ ├── CodexSearchService.cs # Search documents
│ ├── DocumentService.cs # Retrieve documents
│ └── TagService.cs # List and filter tags
├── Program.cs
└── appsettings.json
```
**Running the sample**:
```bash
# Terminal 1: Start CODEX MCP Server
cd /path/to/OpenHarbor.MCP.Server/samples/CodexMcpServer
dotnet run
# Server listens on http://localhost:5050
# Terminal 2: Run client commands
cd /path/to/OpenHarbor.MCP.Client/samples/CodexMcpClient
dotnet run -- search "architecture patterns"
dotnet run -- get-document <id>
dotnet run -- list-tags
# Client connects to server via HTTP (configured in appsettings.json)
```
### 2. Multi-Server Client
Connect to multiple MCP servers simultaneously:
```csharp
public class MultiServerService
{
private readonly IMcpClient _mcpClient;
public async Task<CombinedResults> SearchAllServersAsync(string query)
{
// Get list of connected servers
var servers = await _mcpClient.GetConnectedServersAsync();
var results = new CombinedResults();
foreach (var server in servers)
{
// List tools available on this server
var tools = await _mcpClient.ListToolsAsync(server.Name);
// Find search tool (if exists)
var searchTool = tools.FirstOrDefault(t => t.Name.Contains("search"));
if (searchTool != null)
{
var result = await _mcpClient.CallToolAsync(
server.Name,
searchTool.Name,
new Dictionary<string, object> { ["query"] = query }
);
results.Add(server.Name, result);
}
}
return results;
}
}
```
### 3. Error Handling and Retry
```csharp
public class ResilientMcpService
{
private readonly IMcpClient _mcpClient;
private readonly ILogger<ResilientMcpService> _logger;
public async Task<McpToolResult> CallWithRetryAsync(
string serverName,
string toolName,
Dictionary<string, object> arguments,
int maxRetries = 3)
{
for (int attempt = 0; attempt < maxRetries; attempt++)
{
try
{
return await _mcpClient.CallToolAsync(serverName, toolName, arguments);
}
catch (McpConnectionException ex) when (attempt < maxRetries - 1)
{
_logger.LogWarning(
"MCP call failed (attempt {Attempt}/{MaxRetries}): {Error}",
attempt + 1, maxRetries, ex.Message
);
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
}
}
throw new Exception($"Failed after {maxRetries} attempts");
}
}
```
---
## Connection Management
### Connection Pooling
OpenHarbor.MCP.Client includes connection pooling for efficient resource usage:
```json
{
"Mcp": {
"Connection": {
"EnableConnectionPooling": true,
"MaxConnectionsPerServer": 5,
"ConnectionIdleTimeout": "00:05:00",
"PoolEvictionInterval": "00:01:00"
}
}
}
```
### Timeout Configuration
Configure timeouts per server:
```json
{
"Servers": [
{
"Name": "fast-server",
"Timeout": "00:00:10"
},
{
"Name": "slow-batch-server",
"Timeout": "00:05:00"
}
]
}
```
### Health Checks
Monitor server connections:
```csharp
public class ServerHealthService
{
private readonly IMcpClient _mcpClient;
public async Task<Dictionary<string, bool>> CheckServerHealthAsync()
{
var servers = await _mcpClient.GetConnectedServersAsync();
var health = new Dictionary<string, bool>();
foreach (var server in servers)
{
try
{
await _mcpClient.PingAsync(server.Name);
health[server.Name] = true;
}
catch
{
health[server.Name] = false;
}
}
return health;
}
}
```
---
## Testing
### Integration Tests
```bash
# Run all tests
dotnet test
# Run specific test project
dotnet test tests/OpenHarbor.MCP.Client.Tests/
# Run with coverage
dotnet test /p:CollectCoverage=true
```
### Mock MCP Server
The library includes a mock server for testing:
```csharp
[Fact]
public async Task Client_CanCallMockServerTool()
{
// Arrange
var mockServer = new MockMcpServer()
.WithTool("test_tool", async (args) =>
McpToolResult.Success($"Received: {args["input"]}"));
var client = new McpClient();
await client.ConnectToServerAsync(mockServer);
// Act
var result = await client.CallToolAsync(
"mock-server",
"test_tool",
new Dictionary<string, object> { ["input"] = "test" }
);
// Assert
Assert.True(result.IsSuccess);
Assert.Equal("Received: test", result.Content);
}
```
### Test Coverage
OpenHarbor.MCP.Client maintains **88.52% line coverage** and **75.58% branch coverage** with **60 tests** passing (100%).
**Coverage Breakdown:**
- **Lines**: 88.52% (excellent)
- **Branches**: 75.58% (excellent)
- **Test Projects**: 1
- OpenHarbor.MCP.Client.Core.Tests: 60 tests
- HTTP client connection tests: 20 tests
- Configuration validation tests
- Error handling and retry logic
**Analysis:**
- **Excellent coverage** - exceeds 85% industry threshold
- All critical paths tested
- Error handling well-covered
- Configuration scenarios comprehensive
**Coverage Reports:**
```bash
# Generate coverage report
dotnet test --collect:"XPlat Code Coverage" --results-directory ./TestResults
# View detailed coverage
# See: /home/svrnty/codex/COVERAGE-SUMMARY.md for complete analysis
```
**Status**: ✅ Excellent - Production-ready coverage meets all industry standards
---
## Documentation
| Document | Description |
|----------|-------------|
| [**API Reference**](docs/api/) | **Complete API documentation (IMcpClient, Models, Configuration)** |
| [Module Design](docs/module-design.md) | Architecture and design decisions |
| [Implementation Plan](docs/implementation-plan.md) | Development roadmap |
| [AGENT-PRIMER.md](AGENT-PRIMER.md) | AI-assisted setup guide |
| [HTTPS Setup Guide](docs/deployment/https-setup.md) | Production TLS/HTTPS configuration |
---
## Related Modules
OpenHarbor.MCP is a family of three complementary modules:
- **[OpenHarbor.MCP.Server](../OpenHarbor.MCP.Server/)** - Server library (expose tools TO AI agents)
- **[OpenHarbor.MCP.Client](../OpenHarbor.MCP.Client/)** - Client library (call tools FROM servers) ← You are here
- **[OpenHarbor.MCP.Gateway](../OpenHarbor.MCP.Gateway/)** - Gateway/proxy (route between clients and servers)
All three modules share:
- Same Clean Architecture pattern
- Same documentation structure
- Same security principles
- Compatible .NET 8 SDKs
---
## Contributing
We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for:
- Development setup
- Code standards
- Testing requirements
- Pull request process
---
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
---
## Support
- **Issues**: [GitHub Issues](https://github.com/svrnty/openharbor-mcp/issues)
- **Email**: info@svrnty.io
- **Documentation**: [docs/](docs/)
---
**Built with love by Svrnty**
Creating sovereign tools to democratize technology for humanity.