講座を始める。六編にわたってサーバーをひとつ育てる。各編がひとつずつ足し、どの段階も それ自体で動く完成品 だ。
一編目で作るのは何もしないサーバーだ。道具も無くリソースも無い。それでもこの段階が無いと後が全部崩れる。
これで全部
import 'dart:async';
import 'dart:io';
import 'package:mcp_server/mcp_server.dart';
void main(List<String> args) async {
const config = McpServerConfig(
name: 'Course',
version: '1.0.0',
capabilities: ServerCapabilities(),
);
final server = McpServer.createServer(config);
final transport = McpServer.createStdioTransport().get();
server.connect(transport);
stderr.writeln('course step1: up, nothing registered');
await Completer<void>().future;
}
ServerCapabilities() が空だ。まだ差し出すものが無いと言っている。次の編からここが埋まる。
最後の Completer<void>().future は永遠に完了しない。main が終わればプロセスが死ぬので、死なないように掴んでおく。
繋いで問う
クライアント無しで手で突ける。stdio で回るサーバーなので、行を押し込めばいい。
{ printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}\n'
sleep 2; } | dart run bin/step1.dart
返ってきたもの。
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18","serverInfo":{"name":"Course","version":"1.0.0"},"capabilities":{}}}
serverInfo に我々が書いた名前がそのままある。一編目で確かめるのはこれで全部だ。 サーバーが生きていて、規約どおり自己紹介する。