ワークフロー/エージェントを MCP サーバーとして公開する(lait serve --mcp)
agents:/workflows: の各エントリを MCP ツールとして他のクライアントに公開する方法。
lait serve --mcp は、lait.config.yml の agents:/workflows: に登録した各エントリを、
1つずつ呼び出し可能な MCP ツールとして公開する MCP サーバーです。既定では標準入出力(stdio)で
通信し、--http を指定すると Streamable HTTP で待ち受けます。
Claude Code や Claude Desktop のような MCP クライアントの設定に lait serve --mcp を子プロセス
として登録すれば、それらのエージェント/ワークフローを他のツールの部品として使わせられます。
# lait.config.yml
base_url: "http://localhost:1234/v1"
default:
model: local
agents:
reviewer: agents/reviewer.md
workflows:
release_notes: workflows/release_notes.yml
lait serve --mcp
MCP クライアント側の設定例(Claude Desktop の claude_desktop_config.json 相当):
{
"mcpServers": {
"lait": {
"command": "lait",
"args": ["serve", "--mcp"],
"cwd": "/path/to/your/project"
}
}
}
HTTP で公開する(--http)
--http <ADDR> を指定すると、標準入出力の代わりに MCP の Streamable HTTP トランスポートで
ADDR を待ち受けます。起動すると、接続先 URL が標準エラー出力に表示されます(ポートに 0 を
指定すると空いているポートが自動で選ばれます)。
lait serve --mcp --http 127.0.0.1:8765
# note: lait serve --mcp: ready at http://127.0.0.1:8765/mcp with 2 tool(s): ...
MCP クライアントには http://127.0.0.1:8765/mcp を登録します(パスは問いませんが、/mcp を
推奨します)。複数のクライアントが同時に接続でき、それぞれが独立したセッションになります。
認証はありません。 既定のループバックアドレス(127.0.0.1 など)で待ち受け、外部に公開する
場合は認証を行うリバースプロキシなどを前段に置いてください。DNS リバインディング対策として、
Host ヘッダーが localhost/127.0.0.1/::1 以外のリクエストは拒否します。別のホスト名で
アクセスさせる場合は --allowed-host <HOST>(example.com または example.com:8765、複数指定可)
で許可してください。
実行時オプション
| オプション | 説明 |
|---|---|
--http <ADDR> |
標準入出力の代わりに Streamable HTTP で ADDR を待ち受けます(上記参照)。 |
--allowed-host <HOST> |
--http で受け付ける Host ヘッダーの値を追加します。複数指定できます。 |
--cache/--no-cache(グローバル) |
各ツール呼び出しのモデルリクエストでレスポンスのディスクキャッシュを使う/使わない。省略時は default.cache に従います。 |
--record <DIR> |
ツール呼び出しのモデルリクエスト/レスポンスを DIR にカセットとして記録します(lait run --record と同じ。決定的テスト参照)。 |
--replay <DIR> |
モデルリクエストを DIR のカセットから再生し、ネットワークには接続しません(lait run --replay と同じ)。 |
--trace-file <PATH> |
各ツール呼び出しのモデル呼び出し・ツール呼び出しを JSONL のトレースとして書き出します(実行トレース参照)。サーバーは起動し続けるため、ツール呼び出しが終わるたびにそれまでの全イベントでファイルを書き直します。各イベントの attributes には、どの MCP ツールの呼び出しによるものかを示す lait.serve.tool が付きます。 |
公開されるツール
| 登録元 | ツール名 | 引数スキーマ |
|---|---|---|
agents: の各エントリ |
agent__<名前>(例: agent__reviewer) |
そのエージェントファイル自身の input_schema:(エージェント Markdown ファイルを参照)がそのまま使われます。input_schema: を持たないエージェントは、サブエージェントと同じ汎用スキーマ({"input": "..."}、文字列または JSON)になります。 |
workflows: の各エントリ |
workflow__<名前>(例: workflow__release_notes) |
{"input": "...", "inputs": {...}} です。input は lait run <名前> <PROMPT> の PROMPT に対応する文字列で(ワークフローの input_schema: に従って解釈されます)、ワークフローが inputs: を宣言していなければ必須です。inputs は宣言された inputs: の値のオブジェクトで、各入力のスキーマがそのままプロパティのスキーマになり、default を持たない入力は必須になります。 |
- ツールの
descriptionは、エージェントファイルのdescription:/ワークフローファイルの トップレベルdescription:から取られます(未設定ならRun the '<名前>' agent/workflow.という既定文)。 - ツール呼び出しの実行結果(最終出力テキスト)がそのままツール結果として返ります。実行の途中
経過(
report::noteなどの進捗表示)は出しません — 後述のとおり標準出力/標準エラー出力は プロトコル用途のためです。
agents:/workflows: に登録されていても、名前が OpenAI/MCP のツール名制約(64文字以内、
英数字/_/-のみ)に収まらない場合や、ファイルの読み込み・パースに失敗する場合は、そのエント
リだけを飛ばして起動を続けます(lait workflow list/lait skill list と同じ寛容さです)。
どのエントリが飛ばされたかは標準エラー出力の note: 行に出ます。
制約・スコープ外
lait serveは起動時に一度だけlait.config.ymlを読み込みます。 サーバー起動後にagents:/workflows:を追記しても、再起動するまでは反映されません(他のすべてのlaitコ マンドと同じ「1回の起動につき1回の設定読み込み」という前提です)。ask:ステップを含むワークフローは公開されません。lait serve --mcpでは標準入出力が MCP の JSON-RPC 通信そのものに使われているため、ask:ステップ([ワークフロー](./workflow.md #ask–人間に尋ねる))が対話端末からの回答を待とうとすると、MCP の通信と衝突しかねません。ask:ステップは非対話的な標準入力(実際の MCP クライアントがlait serveを子プロセスとして 起動する場合は常にこちら)に対してはもともとdefault:へフォールバックする安全策を持って いますが、lait serve --mcpを対話端末から直接手動で試す場合はその安全策が効かず、標準入力 の奪い合いになり得ます。このため、公開対象を組み立てる際にask:ステップを1つでも含む (制御ステップの内側に入れ子になったものも含む)ワークフローは無条件に除外し、note:行で その理由を表示します(このチェックはそのワークフローファイル自身のステップだけを見ます —workflow:ステップで呼び出す別ファイル側のask:ステップまでは検出しません)。--approve-tools(対話的なツール承認)は使えません。 同じ理由(標準入力が MCP 通信専用。--httpの場合も、承認に応答する人間がいない)により、served なエージェント/ワークフロー自身の tool loop は常に非対話的に実行されます。tool_policy(allow/deny)は通常どおり効きます。lait history・--show-usageには記録されません。 served な呼び出しは、通常のlait run/lait agent runが経由する出力・履歴記録の経路(report::emit_run_outputなど) を通らず、結果テキストを MCP クライアントへ直接返すだけです。- ワークフローの
WorkflowFile/WorkflowScopeはツール呼び出し間でキャッシュされません。workflow__<名前>ツールが呼ばれるたびに、そのワークフロー YAML を毎回読み直します(モデル 呼び出し自体のレイテンシに比べれば YAML の再パースは無視できるコストと判断しています)。agents:側は既存のAgentRegistryのキャッシュをそのまま再利用します。