feat(mcp): Dabit.Mcp 초기 공개 (리네임 + colors 수정 + scroll 검증)

- refactor: DabitChe.Mcp → Dabit.Mcp (namespace, csproj, exe 모두)
- fix: display_message colors를 쉼표 구분 문자열로 변경 (ModelContextProtocol 1.3.0 배열 바인딩 버그 우회)
- docs: scroll 4방향(left/right/up/down) 실기 검증 완료 (DIBD600T V3.6.1)

20 도구 (읽기 4 + 콘텐츠 2 + 설정 14), stdio 전송, Windows exe.
실기 검증: scroll/fill_screen 8색/display_message 글자별색 모두 정상.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
insulee
2026-06-02 11:20:49 +09:00
parent 94dd74bd5c
commit 640c9a3380
109 changed files with 7146 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
using System.ComponentModel;
using Dabit.Mcp.Services;
using DibdProtocol.Protocol;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
namespace Dabit.Mcp.Tools;
/// <summary>페이지 메시지 개수·초기화·섹션 효과 도구. ⚠️ 쓰기.</summary>
[McpServerToolType]
public sealed class PageTools
{
private readonly LedControlService _led;
private readonly ILogger<PageTools> _log;
public PageTools(LedControlService led, ILogger<PageTools> log)
{
_led = led;
_log = log;
}
[McpServerTool]
[Description("페이지 메시지 개수를 설정한다. ⚠️ 쓰기·설정 저장. count 1~10.")]
public async Task<string> SetPageCount(
[Description("페이지 수 1~10")] int count,
CancellationToken ct = default)
{
if (count < 1 || count > 10)
return "페이지 수는 1~10이어야 합니다.";
var resp = await _led.SendAsciiAsync("60", count.ToString("D2"), ct, 5000);
return Format(resp, $"페이지 개수 {count}개 설정.");
}
[McpServerTool]
[Description("페이지 메시지를 초기화(삭제)한다. ⚠️ 쓰기. page: 0=전체 삭제, 1~10=개별 페이지.")]
public async Task<string> ResetPageMessage(
[Description("0=전체 삭제, 1~10=개별 페이지")] int page,
CancellationToken ct = default)
{
if (page < 0 || page > 10)
return "page는 0(전체)~10이어야 합니다.";
// 정본: 전체→"99", 개별 N(1~10)→(N-1) zero-pad 2자리
var data = page == 0 ? "99" : (page - 1).ToString("D2");
var resp = await _led.SendAsciiAsync("61", data, ct, 5000);
return Format(resp, page == 0 ? "전체 페이지 초기화." : $"{page}번 페이지 초기화.");
}
[McpServerTool]
[Description("섹션별 표출 효과 모드를 설정한다. ⚠️ 쓰기. mode: 0=동시표출, 1=개별표출.")]
public async Task<string> SetSectionEffect(
[Description("0=동시표출, 1=개별표출")] int mode,
CancellationToken ct = default)
{
// 정본: N=동시표출, Y=개별표출
var data = mode == 0 ? "N" : "Y";
var resp = await _led.SendAsciiAsync("62", data, ct, 5000);
return Format(resp, mode == 0 ? "섹션 동시표출 설정." : "섹션 개별표출 설정.");
}
private static string Format(DibdProtocol.Protocol.AsciiParsedResponse? r, string ok)
=> r is null ? "전송 실패 — 연결 또는 통신 오류." : (r.Result == "F" ? "전광판이 거부했습니다 (Result=F)." : ok);
}