svrnty-mcp-server/samples/CodexMcpServer/Tools/SearchCodexTool.cs
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

126 lines
3.6 KiB
C#

using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Svrnty.MCP.Core;
namespace CodexMcpServer.Tools;
/// <summary>
/// MCP tool for searching CODEX documents.
/// Calls CODEX API /api/documents/search endpoint.
/// </summary>
public class SearchCodexTool : IMcpTool
{
private readonly HttpClient _httpClient;
private static readonly JsonDocument _schema = JsonDocument.Parse("""
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query to find relevant documents in CODEX"
}
},
"required": ["query"]
}
""");
public SearchCodexTool(HttpClient httpClient)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
// Set base address if not already set
if (_httpClient.BaseAddress == null)
{
_httpClient.BaseAddress = new Uri("http://localhost:5050");
}
}
/// <inheritdoc/>
public string Name => "search_codex";
/// <inheritdoc/>
public string Description => "Search CODEX documents by query text. Returns matching documents with relevance scores.";
/// <inheritdoc/>
public JsonDocument Schema => _schema;
/// <inheritdoc/>
public async Task<JsonDocument> ExecuteAsync(JsonDocument? arguments)
{
try
{
// Validate arguments
if (arguments == null)
{
return CreateErrorResponse("Arguments cannot be null. Expected {\"query\": \"search text\"}");
}
var root = arguments.RootElement;
if (!root.TryGetProperty("query", out var queryElement))
{
return CreateErrorResponse("Missing required parameter 'query'");
}
var query = queryElement.GetString();
if (string.IsNullOrWhiteSpace(query))
{
return CreateErrorResponse("Query cannot be empty");
}
// Prepare request to CODEX API
var requestBody = new
{
query = query
};
var content = new StringContent(
JsonSerializer.Serialize(requestBody),
Encoding.UTF8,
"application/json"
);
// Call CODEX API
var response = await _httpClient.PostAsync("/api/documents/search", content);
if (!response.IsSuccessStatusCode)
{
var errorContent = await response.Content.ReadAsStringAsync();
return CreateErrorResponse(
$"CODEX API returned error: {response.StatusCode}. {errorContent}"
);
}
// Parse and return response
var responseContent = await response.Content.ReadAsStringAsync();
try
{
return JsonDocument.Parse(responseContent);
}
catch (JsonException ex)
{
return CreateErrorResponse($"Failed to parse CODEX API response: {ex.Message}");
}
}
catch (HttpRequestException ex)
{
return CreateErrorResponse($"HTTP request failed: {ex.Message}");
}
catch (Exception ex)
{
return CreateErrorResponse($"Unexpected error: {ex.Message}");
}
}
private static JsonDocument CreateErrorResponse(string message)
{
var error = new
{
error = message
};
return JsonDocument.Parse(JsonSerializer.Serialize(error));
}
}