Editor/McpServerExtension.cs
#nullable enable
using System;
using System.Linq;
using Sandbox;
using Editor.Mcp;
namespace Editor.Mcp
{
/// <summary>
/// S&box MCP Assistant - Advanced AI integration tools for s&box.
/// </summary>
[McpToolset( "pocketknife_editor", "Verified s&box editor complement tools for session state, package/cloud provenance, document adapters, navigation, and workflow diagnostics; use official s&box MCP for generic scene, asset, play, compile, and log operations." )]
public static partial class SboxMcpAssistant
{
// Tool categories are split into partial class files in the Tools/ directory.
[McpTool("pocketknife_find_capability")]
public static string FindCapability(string query, int limit = 5, int offset = 0)
{
var normalized = (query ?? "").Trim();
if (string.IsNullOrWhiteSpace(normalized))
return McpJson.Write(ToolOutcome<object>.Failure(null, ToolStatus.Failed, "capability.query_required", "A non-empty task query is required."));
if (normalized.Length > 200)
return McpJson.Write(ToolOutcome<object>.Failure(new { QueryLength = normalized.Length, MaximumQueryLength = 200 }, ToolStatus.Failed, "capability.query_too_long", "Capability query must be 200 characters or fewer."));
var boundedLimit = Math.Clamp(limit, 1, 20);
var boundedOffset = Math.Max(offset, 0);
var results = SboxCapabilityCatalog.Search(normalized, boundedLimit, boundedOffset, out var total)
.Select(capability => capability.ToPayload()).ToArray();
var nextOffset = boundedOffset + results.Length < total ? boundedOffset + results.Length : (int?)null;
return McpJson.Write(ToolOutcome<object>.Ready(new
{
Query = normalized,
Offset = boundedOffset,
Limit = boundedLimit,
Total = total,
Results = results,
Next = nextOffset ?? -1
}));
}
}
}