Files
kompas3d-mcp/src/Kompas.Mcp.Host/Tools/SystemTools.cs
T
mikhail 69a075c890 Журнал операций: история вызовов инструментов в JSONL
Каждый вызов пишется строкой JSON из фильтра в Program.cs: инструмент,
аргументы, длительность, ok, полный текст ошибки либо начало ответа.
Снимок модели в журнал не идёт — только размер картинки.

Включается только явным путём: KOMPAS_MCP_OPLOG_PATH на старте или
set_operation_log(enabled, path?) в сессии; KOMPAS_MCP_OPLOG=0 глушит,
не стирая путь. Сбой записи операцию не роняет, причина видна в
kompas_status.

tools/dev/oplog-report.ps1 разбирает накопленное: частота и медианное
время по инструментам, доля отказов, топ ошибок, ни разу не вызванные
инструменты — материал для решений, что из каталога убрать и что
переделать.

Заодно поправлены устаревшие счётчики в README: 60 инструментов
(было указано 57 при 59 фактических), 567 тестов вместо 427.
2026-07-31 21:36:28 +03:00

94 lines
6.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.ComponentModel;
using Kompas.Mcp.Core;
using Kompas.Mcp.Core.Diagnostics;
using Kompas.Mcp.Core.Interop;
using Kompas.Mcp.Core.Validation;
using ModelContextProtocol.Server;
namespace Kompas.Mcp.Host.Tools;
/// <summary>Системные инструменты: подключение, статус, видимость окна, журнал операций.</summary>
[McpServerToolType]
public sealed class SystemTools(KompasSession session, AutoValidation autoValidation, OperationLog operationLog)
{
[McpServerTool(Name = "kompas_connect")]
[Description("Подключиться к КОМПАС-3D: присоединиться к запущенному экземпляру или запустить новый, показать окно. Возвращает версию и редакцию.")]
public async Task<string> Connect()
{
var info = await session.ConnectAsync();
return $"Подключено к КОМПАС {info.Version} (build {info.BuildNumber}, {info.Edition}), ProgID {info.ProgId}.";
}
[McpServerTool(Name = "kompas_status")]
[Description("Текущее состояние подключения к КОМПАС.")]
public string Status()
{
// Проверка интеропа идёт до любого обращения к сессии: без сборок КОМПАС первое же
// касание её свойств бросит FileLoadException, а MCP SDK покажет агенту только
// «An error occurred invoking …» без причины. Здесь причина попадает прямо в ответ —
// на этот инструмент опирается /kompas:doctor.
try
{
KompasInteropLoader.ResolveDirectory();
}
catch (KompasInteropException ex)
{
return "Сервер не может обратиться к КОМПАС. " + ex.Message;
}
var validation = autoValidation.Enabled
? "Авто-валидация включена: операции сами дописывают итог проверки построения."
: "Авто-валидация выключена: проверяйте построение вызовом validate_part.";
return (session.IsConnected && session.LastInfo is { } i
? $"Подключено: КОМПАС {i.Version} ({i.Edition})."
: "Не подключено. Вызовите kompas_connect.") + " " + validation + " " + operationLog.Describe();
}
[McpServerTool(Name = "set_operation_log")]
[Description("Включить или выключить журнал операций: запись каждого вызова инструмента в файл JSONL " +
"(имя инструмента, аргументы, длительность, успех или текст ошибки, начало ответа). " +
"Журнал нужен для накопления истории работы — по ней видно, какие инструменты реально " +
"используются и на чём спотыкаются. Вызывайте по прямой просьбе пользователя; путь задаётся " +
"параметром path или переменной окружения KOMPAS_MCP_OPLOG_PATH (без пути журнал выключен). " +
"Снимки модели в журнал не пишутся — только их размер.")]
public string SetOperationLog(
[Description("true — включить запись, false — выключить")] bool enabled,
[Description("Файл журнала (.jsonl) или каталог для него. Пусто — прошлый путь либо KOMPAS_MCP_OPLOG_PATH")]
string? path = null)
{
if (!enabled)
{
operationLog.Disable();
return operationLog.Describe();
}
var file = operationLog.Enable(path);
return $"Журнал операций включён: {file}. Пишется по строке JSON на вызов инструмента " +
$"(записей за сессию: {operationLog.WrittenCount}).";
}
[McpServerTool(Name = "set_auto_validate")]
[Description("Включить или выключить авто-валидацию: дописывать ли к ответу каждой мутирующей операции " +
"(выдавливание, вращение, скругление, отверстие, массив, прямое редактирование…) итог проверки " +
"построения. Включена по умолчанию — отдельный validate_part тогда не нужен. Выключайте только " +
"если проверка после каждого шага заметно замедляет работу на тяжёлой модели; тогда зовите " +
"validate_part вручную перед выдачей результата и экспортом.")]
public string SetAutoValidate([Description("true — включить, false — выключить")] bool enabled)
{
autoValidation.Enabled = enabled;
return enabled
? "Авто-валидация включена: итог проверки построения дописывается к ответу каждой операции."
: "Авто-валидация выключена: проверяйте построение вызовом validate_part вручную.";
}
[McpServerTool(Name = "kompas_set_visible")]
[Description("Показать или скрыть главное окно КОМПАС.")]
public async Task<string> SetVisible([Description("true — показать, false — скрыть")] bool visible)
{
await session.ConnectAsync();
await session.SetVisibleAsync(visible);
return visible ? "Окно КОМПАС показано." : "Окно КОМПАС скрыто.";
}
}