Model Context Protocol(MCP)により、AIエージェントやMCP対応クライアントはToolを発見して呼び出せます。このプロジェクトでは、2つの異なるものがMCPを話します。このページではその両方を扱います。

ローカルLauncher: browserflow mcp

1人の開発者自身のRegistry向けに動く、認証なしのstdio子プロセスです。このページの大半はこちらを扱います。

ホスト型: Jinba TrailのPOST /mcp

あなたの組織の公開済みオートメーションを任意のMCPクライアント(Claude Desktop、Cursor、mcp-remoteブリッジなど)に公開する、マルチテナントでBearer認証付きのStreamable HTTPサーバーです。
どちらの場合も、エージェントはToolを呼び出す判断をできますが、呼び出されたFlowはRiderの下で決定論的なFlowSpecとして実行されます。実行経路のどこにもモデルは入りません。これにより、エンジンは再現性を手放さずにエージェントのエコシステムへ接続できます。
これらは同じMCPサーバーではありません。 browserflow mcp は、ローカルRegistryに対して自分で実行する、認証なし・単一ユーザーのstdioプロセスです。「org」やBearerキーという概念はありません。Jinba TrailのPOST /mcpは、jbt_* APIキーで保護されたホスト型・マルチテナントのHTTPエンドポイントで、公開するToolはあなたの組織の公開済みオートメーションだけです。「自分のFlowがローカルでMCP公開されている」ことと、「自分のオートメーションがJinba Trailのホスト型MCPから到達可能である」ことを混同しないでください。両者は独立して制御されます(下のMCP公開はRESTとは別のゲートを参照)。

考え方: エージェントが判断し、Flowが実行する

多くの「AIワークフロー」は、各実行のクリティカルパス上にモデルを置くため、同じタスクを2回実行しても分岐し得ます。browser-flowは明確な線を引きます。モデルはRunの外側にあります。エージェントの仕事は、どのFlowをどの入力で呼び出すかを選ぶことだけです。呼び出された後、Flowはbrowserflow runの下で実行される場合とまったく同じように実行されます。同じFlowSpec digest、同じ固定済みPack、同じ記録済みeffect、同じ結果です。 モデルは判断経路にあり、実行経路には決して入りません。この分離こそが、このプロジェクト全体の主張です。その背後にある原則はコンセプト概要を参照してください。

MCPサーバーを開始する

browserflow mcpにRegistryを指定すると、その中のすべてのFlowがMCPツールとして公開されます。
browserflow mcp --registry ./registry        # stdio transport(デフォルト)
browserflow mcp daily-price-watch.yaml       # 単一のFlowを公開
このサーバーは(@modelcontextprotocol/sdk経由で)stdio transportを使います。これは、MCPサーバーを子プロセスとして起動するエージェントクライアントの標準です。browserflow runbrowserflow serveを支える同じRegistryがMCPサーバーも支えるため、追加で公開するものはありません。MCPで公開されたFlowは、あなたがすでにラップトップ上またはRESTの背後で実行しているものと同じartifactです。
browserflow mcpは、複数あるLauncherの1つです。Launcherは、ある環境向けにcapabilityを配線してRiderを呼び出す薄いホストです。FlowとそのFlowSpecはすべてのLauncherで一定で、変わるのはフロントだけです。Launcherとポータビリティを参照してください。

入力は自動的にTool schemaになる

MCP schemaを手書きする必要はありません。Flowの型付きinputsが、そのままMCPツールの入力schemaになります。SDKまたはYAMLで作成した同じ型付き契約がエージェントに公開されるため、エージェントは何を渡せばよいかを正確に把握できます。 唯一の入力が検索queryであるdaily-price-watchの場合、公開されたToolは接続してきたエージェントから次のように見えます。
// Flowが宣言した入力...
export default flow({
  name: "daily-price-watch",
  inputs: {
    query: t.string(),
  },
  // ...browser search-price@1.2.0 → transform → conditional http.post
});
# ...またはYAMLで同じ内容
name: daily-price-watch
inputs:
  query: string
# steps: search-price@1.2.0 → transform → http.post (conditional)
MCP tool (as advertised to the agent)
{
  "name": "daily-price-watch",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": { "type": "string" }
    },
    "required": ["query"]
  }
}
エージェントが{ "query": "wireless headphones" }でToolを呼び出すと、browserflow mcpはその入力をschemaに照らして検証し、Flowを実行します。browser tool search-price@1.2.0が価格を検索し、transformが形を整え、条件付きhttp.postが価格低下時にシークレットwebhookへ通知します。エージェントには、構造化されたRun resultが返ります。
シークレットがMCP経由で公開されることはありません。daily-price-watch内のwebhook URLは、起動環境自身のSecrets providerから実行時に供給されます。Tool schema、入力、エージェントが見る結果のいずれにも含まれません。シークレットを参照してください。

エージェントにできること、できないこと

エージェントにできることエージェントにできないこと
Flow(およびTool)をMCPツールとして発見するFlowSpecや固定済みPack digestを変更する
どのFlowを呼び出すかを選ぶRunにモデルを注入する
schemaに一致する型付きinputsを渡すシークレットを読む、または渡す
構造化されたRun resultを受け取るRunを非決定論的にする
エージェントは呼び出し元であり、作成者ではありません。エージェントが何をしても、呼び出されるFlowは、あなたがコンパイルして固定したcontent-addressed artifactです。どこでも同一に再現される、同じartifactです。

これが再現性を保つ理由

1

1つのartifact、多数のフロント

MCPで公開されるFlowは、browserflow runで実行する、またはbrowserflow serveでserveするFlowSpecとバイト単位で同一です。エージェント経由で呼び出しても、どのartifactが実行されるかは変わりません。
2

決定論的な実行

Riderは、capabilityから供給されるeffectを使ってDAGを実行し、それをJournalに記録します。言語モデルは参加しないため、どのフロントから呼び出されたかに関係なく、同じ入力は同じ結果を生みます。
3

監査可能なRun

そのRunは通常のRider runであるため、Journalを生成します。トリガーがエージェントだった場合でも、browserflow replay --verifyでタイムトラベルしてリプレイできます。結果はエージェントの推論に依存しません。テストとリプレイを参照してください。
現在、browserflow mcpFlowをMCPツールとして公開します(Registry内のFlowごとに1つのTool)。個別のToolを別々に公開する機能はまだ実装されていません。公開したいToolの周りに、単一手順のFlowをラップしてください。
browserflow mcpstdio transportを使います。これは、MCPサーバーを子プロセスとして起動するエージェントクライアントの標準です(@modelcontextprotocol/sdk経由)。--registryのすべてのFlowは、この単一のtransportを通じて公開されます。
違うのはフロントだけです。browserflow serveは一般の呼び出し元向けにFlowをHTTPエンドポイントとして公開し、browserflow mcpはエージェントエコシステム向けにMCPツールとして公開します。同じRegistry、同じFlowSpec、同じRider、同じ結果です。REST APIをデプロイするを参照してください。

Hosted MCP: Jinba TrailのPOST /mcp

Jinba Trailを使っている場合、ホスト型プロダクトは同じ考え方を、stdio子プロセスではなく、認証付きのマルチテナントHTTPエンドポイントとしてラップします。このセクションでは、そのホスト型の表面を説明します。エンジンを直接セルフホストしている場合は、上のstdioの手順が該当します。
これは上のbrowserflow mcpとは別のMCPサーバーです。transport(stdioではなくStreamable HTTP)、認証モデル(「プロセスを起動できる人」ではなくBearer jbt_*キー)、Toolのソース(ローカルRegistry pathではなく、あなたの組織の公開済みオートメーション)が異なります。一方を有効にしたからといって、もう一方で何かが公開されるとは考えないでください。
  • Endpoint: POST /mcpPOST /v1/run/:flowと同じ方法で認証されます。Bearer Authorization: Bearer jbt_live_…(またはjbt_test_…)ヘッダーがあなたの組織を識別します。キーの発行についてはPlaygroundとAPIキーを参照してください。
  • Transport: Streamable HTTP、statelessです。リクエストごとに新しいMCP sessionが構築されます(呼び出しをまたいでサーバー側で保持されるsessionはありません)。レスポンスモードはAcceptヘッダーでネゴシエートされます。application/jsonより前にtext/event-streamを列挙すると、転送されたRun progressを含むstreaming responseを受け取れます。デフォルトは単一のbuffered JSON responseです。
  • 公開されるTool: (a) 公開済み(draftではない)で、(b) MCP toggleが有効(下記参照)で、(c) 呼び出し元キーのスコープ内にある場合はその範囲内の、オートメーションごとに1つのMCPツールが公開されます。各Toolの入力schemaは、RESTエンドポイントのrequest bodyとまったく同じく、オートメーションの公開(非シークレット)入力から生成されます。シークレット由来の入力は、あなたの組織に保存されたシークレットからサーバー側で解決され、エージェントが供給したり読み返したりできるTool parameterとして現れることはありません。
  • Execution: Toolを呼び出すと、POST /v1/run/:flowの場合とまったく同じようにオートメーションが実行されます。同じ決定論的なFlowSpec、同じ記録済みRun、同じ結果です。test-modeキーは、RESTのルールと同じく、シークレットを使うオートメーションを呼び出せません。
curl -X POST https://<host>/mcp \
  -H "Authorization: Bearer jbt_live_••••3f9a" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get-order-status",
      "arguments": { "orderId": "NW-100423" }
    }
  }'
{
  "run_id": "run_8fZ...",
  "status": "succeeded",
  "flow_digest": "sha256:9c2e...",
  "output": { "orderId": "NW-100423", "state": "shipped" }
}
Claude DesktopやCursorのようなクライアントをこのエンドポイントに接続するには、MCPで接続するを参照してください。ホスト型UIの流れ(toggleの有効化、キーの発行、クライアント設定の配線)を順に説明しています。

MCP公開はRESTとは別のゲート

オートメーションを公開すると、REST(POST /v1/run/:flow)経由で呼び出せるようになります。しかし、それだけでMCP経由に公開されるわけではありません。公開済みオートメーションがPOST /mcp上のToolとして登録されるかどうかは、オートメーションごとの2つ目のMCP toggleで制御されます。ownerは、REST呼び出し元向けにオートメーションを公開しつつ、すべてのMCPクライアントのTool一覧からは除外できます。逆はできません(オートメーションはMCP有効化の前に公開されている必要があります)。MCPをoffにすると、すべてのキーに対して即座にToolが削除されます。RESTの公開状態には一切触れません。

キーごとのスコープが表示されるToolを絞り込む

APIキーがオートメーションのサブセットにスコープ設定されている場合、ホスト型MCPサーバーはスコープ外のtools/callを拒否するだけではありません。そもそもそのキーのtools/listに、そのToolを表示しません。スコープなしのキー(作成時にスコープが設定されていない限りデフォルト)は、組織内の公開済みでMCP有効なすべてのオートメーションを見ます。つまり、同じ組織内の2つのキーが同じ/mcpエンドポイントに接続しても、まったく異なるTool一覧を見る可能性があります。
queued-run dispatch modeでは、リクエストを開いたままにしたくないクライアント向けに、あなたのオートメーションに加えてget-run-status polling toolが追加されます。これは呼び出しのdispatch方法に関する運用上の詳細であり、オートメーションごとに設定するものではありません。

関連

MCPで接続する

ホスト型UIの流れです。MCP toggleを有効化し、キーを発行し、クライアントをJinba TrailのPOST /mcpに接続します。

PlaygroundとAPIキー

RESTとホスト型MCPの両方の呼び出しを認証するBearer jbt_*キーを発行します。

Launcherとポータビリティ

CLI、REST、MCP、cronのどのフロントでも、同じFlowSpecが変更なしで実行される仕組みです。

コンセプト概要

原則です。モデルが判断し、決定論的エンジンが実行します。

REST APIをデプロイする

同じFlowをbrowserflow serveでHTTPエンドポイントとして公開します。