-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
48 lines (41 loc) · 2.27 KB
/
Copy pathProgram.cs
File metadata and controls
48 lines (41 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System.Text.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol;
using TableCloth.Mcp;
using TableCloth.Mcp.Catalog;
using TableCloth.Mcp.Tools;
// TableCloth MCP server (stdio).
//
// 설계 원칙: 이 서버는 TableCloth/Spork 데스크톱 앱 및 그 소스에 의존하지 않는다.
// 카탈로그와 샌드박스 실행 자산을 "공개 URL"에서만 받아 소비하는 별도 lane 이다.
// (PARAMETERIZED_WSB_SPEC.md 의 consumer ② "독립형 MCP 서버" 역할)
//
// 가치 범위: "지금 필요한 한국 공공/금융 서비스를 찾아주고, 보안프로그램 설치 없이
// 깨끗한 일회용 샌드박스로 그 사이트를 열어준다"까지. 로그인/인증/실제 업무 자동화(RPA)는
// 의도적으로 하지 않는다 — 그건 사용자의 몫.
var builder = Host.CreateApplicationBuilder(args);
// stdio 전송은 stdout 을 프로토콜 채널로 쓴다. 모든 로그는 stderr 로 보낸다(안 그러면 프로토콜 깨짐).
builder.Logging.AddConsole(o => o.LogToStandardErrorThreshold = LogLevel.Trace);
builder.Services.AddSingleton(_ => new HttpClient
{
Timeout = TimeSpan.FromSeconds(30),
DefaultRequestHeaders = { { "User-Agent", "tablecloth-mcp/0.1" } },
});
builder.Services.AddSingleton<CatalogClient>();
// NativeAOT 대비: 리플렉션 스캔(WithToolsFromAssembly)은 [RequiresUnreferencedCode] 라 쓰지 않는다.
// 제네릭 WithTools<T> + 소스젠 컨텍스트(AppJsonContext)를 SDK 기본 옵션 앞쪽에 얹어 도구 입출력을 직렬화한다.
var toolJsonOptions = new JsonSerializerOptions(McpJsonUtilities.DefaultOptions);
toolJsonOptions.TypeInfoResolverChain.Insert(0, AppJsonContext.Default);
builder.Services
.AddMcpServer(options =>
{
// 서버 수준 지침: 클라이언트(예: Claude Desktop)가 모델에 힌트로 노출한다.
// 문구는 shared/strings.json 이 정본(구현 간 동일). SharedResources 가 임베드 리소스에서 로드.
options.ServerInstructions = SharedResources.ServerInstructions;
})
.WithStdioServerTransport()
.WithTools<CatalogTools>(toolJsonOptions)
.WithTools<SandboxTools>(toolJsonOptions);
await builder.Build().RunAsync();