构建

把服务端立起来 — 并且不往 stdout 写任何东西

作者: makemind · 2026年1月6日

课程从这里开始。六篇里养大一个服务端。每一篇加一样东西,而每一级 本身就是能跑的成品

第一篇做的是一个什么都不干的服务端。没有工具,没有资源。可是没有这一级,后面全都会塌。

全部就这些

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 里就是我们写的名字。第一篇要确认的全部就是这个。 服务端活着,并按契约自我介绍。

此内容需要开发者或更高等级

登录并升级您的方案即可继续阅读。

查看方案
Twitter