Echolot
リファレンス

ワークスペースのファイル

ワークスペースの形式を、ファイルごと、キーごとに。差分を読む、ファイルを手で書く、ファイルを生成するときのために。

ワークスペースは、.echolotで終わるフォルダで、中にプレーンなTOMLファイルが入っています。リクエスト、環境、MCPサーバ、モック、フローごとに1ファイルです。 Finderでは1つのドキュメントとして表示されますが、ターミナル、Git、エディタからは通常のフォルダです。 Echolotは、すべてのファイルを毎回同じ方法で書き出す(キーの順序は固定で、デフォルト値のものは書かない)ため、アプリでの変更は差分では小さな変更になります。Gitとチームを参照してください。

Alpenglow.echolot/
  workspace.toml                     the workspace: ID, name, variables, auth, agents, proxy, certificates
  environments/
    staging.toml                     one environment
  requests/
    _folder.toml                     the order of the top level
    _folder.pre.js                   the workspace's pre-request script (and _folder.test.js)
    auth/
      _folder.toml                   a folder: name, order, docs, variables, auth
      sign-in.req.toml               an HTTP request
      sign-in.body.json              its body
      sign-in.pre.js                 its pre-request script
      sign-in.test.js                its test script
    catalog/
      search-products.gql.toml       a GraphQL request
      search-products.graphql        its query
  mcp-servers/
    alpenglow-mcp.toml               an MCP server
  specs/
    alpenglow.yaml                   an OpenAPI document
    shop.graphql                     a GraphQL schema
    inventory.proto                  a protobuf file
  mocks/
    shop.toml                        a mock server: settings and routes
    shop.js                          its routes in JavaScript
  flows/
    place-test-order.flow.toml       a flow
  assistant/
    checking-orders.md               a shared Assistant conversation, to read
    checking-orders.json             the same, to open in the app

すべてのファイルに共通のルール

  • ファイルはTOML 1.0、UTF-8です。
  • 各ファイルは、形式のバージョンを示すecholot = 1で始まります。これより大きな番号のファイルは、新しいEcholotで保存されたものです。Echolotは、そのファイルを開かずに、その旨を知らせます。
  • ファイル名はスラッグです。小文字、数字、ハイフンで、最大80文字、項目の名前から作られます(Sign inはsign-in)。名前そのものはnameキーに入ります。
  • 項目間のパスは、requests/からの相対で、スラッグを/でつないだものです:auth/sign-in、orders。
  • テキストのフィールドには、{{variables}}と動的な値を含められます。
  • 項目のリストは、TOMLのテーブルの配列([[headers]])です。enabled = falseの項目は保持されますがオフになり、キーがなければオンです。

ファイルに入らないもの

  • シークレットの値。シークレットの変数は、名前とsecret = trueだけで書かれ、値はありません。値はMacのキーチェーンに保管されます。シークレットが必要なフィールド(パスワード、プロキシのパスワード、クライアントシークレット)には、シークレットである{{variable}}を入れてください。 Echolotは、入力したパスワードをキーチェーンに移すことを提案し、読み込みでは自動的にそうします。シークレットを参照してください。
  • OAuthトークンとMCPのサインイン:キーチェーン内。
  • pm.environment.setなどでスクリプトが設定した値:ウインドウまたはコマンドの間だけ保持されます。
  • 履歴とレスポンス:MacのApplication Support内に、ワークスペースごとに1つの履歴として保存されます。履歴を参照してください。
  • あなた自身のレイアウト:ペインのレイアウトとサイズ、開いているタブ、選択した環境。

そのため、ワークスペースは安全にコミットして共有できます。チームメイトは、自分のシークレットの値を設定します。

workspace.toml

# Echolot workspace. Requests live in requests/, one file each.
echolot = 1
id = "0b7d4c1e-2f6a-4e38-9c51-7a1e3d9b5f20"
name = "Alpenglow"

[[variables]]
name = "baseURL"
value = "https://demo.echolot.dev/v1"

[[variables]]
name = "token"
secret = true
キー意味
idワークスペースのID。キーチェーン内のシークレットはこれに属するため、同じIDのコピーはシークレットを共有します。書き出したコピーには新しいIDが付きます。
nameワークスペースの名前。
[[variables]]ワークスペースの変数。変数を参照してください。
[auth]継承するすべてのリクエストの認証。認証を参照してください。デフォルト:なし。
[agents]AIエージェントのルール。エージェントを参照してください。
[proxy]アプリのものではなく、ワークスペース独自のプロキシ。
[[certificates]]ホストごとの、信頼するCA証明書と送信するクライアント証明書。

プロキシ

キー意味
modemanual(デフォルト)、system、environment(HTTPS_PROXY系)、またはnone。
urlプロキシ:http://host:port、https://…、またはsocks5://host:port。
username、passwordプロキシの資格情報。パスワードは、シークレットの{{variable}}として書きます。
bypass直接接続するホスト(配列)。

証明書

各[[certificates]]テーブルは、1つのホストに対するルールです。

キー意味
hostルールの対象のホスト。
trust信頼するCA証明書のPEMファイル(配列)。
certificateクライアント証明書:PEMファイル、または.p12/.pfxファイル。
key証明書ファイルにキーがない場合の、クライアント証明書のPEMキー。
passphraseキーまたはPKCS#12ファイルのパスフレーズ。シークレットの{{variable}}として書きます。

エージェント

[agents]は、EcholotのMCPサーバとアシスタントを通じて、AIエージェントがこのワークスペースで何をしてよいかを設定します。エージェントを参照してください。

[agents]
allowed-hosts = ["demo.echolot.dev"]
max-requests = 200
max-requests-per-minute = 30

[agents.rules]
unsafe-send = "ask"
destructive = "refuse"
キー意味
enabledfalseにすると、このワークスペースのエージェントがオフになり、何も得られなくなります。デフォルトはtrue。
allowed-hostsワークスペースのリクエストが使うホストに加えて、ワークスペース自身のものとみなすホスト。
max-requests1つのエージェントセッションが合計で送信できるリクエスト数。
max-requests-per-minute1つのエージェントセッションが1分間に送信できるリクエスト数。
[agents.rules]操作の種類ごとのルール:allow、ask、refuse。

操作の種類は、read、safe-send、unsafe-send、protected-send、new-host、workspace-write、destructiveです。 より厳しいルールは常に有効です。緩いルールは、あなたが信頼したあとにだけ有効になります(アプリが確認し、コマンドラインでは--trust-workspace-policyが必要です)。 protected-sendとnew-hostは、allowにはできません。

environments/

環境ごとに1ファイル。ファイル名がそのスラッグで、--envで使われます。

echolot = 1
name = "Production"
protected = true

[[variables]]
name = "baseURL"
value = "https://api.alpenglow.example/v1"

[[variables]]
name = "password"
secret = true
キー意味
name環境の名前。
protectedtrueにすると保護された環境になり、送信のたびに確認が表示されます。
[[variables]]その環境の変数。

変数

workspace.toml、環境、フォルダ、リクエストで共通です。

キー意味
name変数の名前。{{name}}として使います。
valueその値。シークレットでは省略されます。
secretシークレットならtrue。値はキーチェーンにあります。
enabledfalseでオフにします。

requests/

requestsフォルダには、サイドバーに表示されるツリーが入っています。その中の各フォルダがツリーのフォルダ、各リクエストファイルがリクエストです。リクエストの種類は、ファイルのサフィックスで決まります。

サフィックス種類
.req.tomlHTTP(Server-Sent Eventsを含む)
.gql.tomlGraphQL
.grpc.tomlgRPC
.ws.tomlWebSocket
.sio.tomlSocket.IO
.mqtt.tomlMQTT
.mcp.tomlMCPサーバの呼び出し

リクエストの横に、同じスラッグで置かれるファイル:

ファイル内容
<slug>.body.<ext>リクエストのボディを、その形式で:.json、.xml、.txt、.html、.graphql、.form.txt。
<slug>.graphqlGraphQLリクエストのクエリ。
<slug>.pre.jsリクエスト前スクリプト。
<slug>.test.jsテストスクリプト。

_folder.toml

すべてのフォルダにあり、トップレベル用にrequests/自体にもあります。

echolot = 1
name = "Auth"
order = ["sign-in", "who-am-i", "client-credentials"]
docs = "Send \"Sign in\" first: it captures the access token into {{token}}."
キー意味
nameフォルダの名前。requests/_folder.tomlにはありません。
orderフォルダ内の項目のスラッグ。サイドバーと実行で使われる順序です。リストにないものはその後に、スラッグ順で続きます。
docsフォルダのドキュメント(Markdown)。
specフォルダが従う仕様。specs/alpenglow.yamlなど。
spec-urlその仕様がURLから来た場合の、取得元。
agent-toolstrueにすると、フォルダのリクエストをツールとしてエージェントに提供します。
[[variables]]フォルダ内のすべてに適用される、フォルダの変数。
[auth]継承するフォルダ内のすべてに適用される、フォルダの認証。デフォルト:継承。

その横の_folder.pre.jsと_folder.test.jsは、フォルダのスクリプトです。requests/にあるものは、ワークスペースのスクリプトです。 これらは、内側のすべてのリクエストに対して、ワークスペースのものから順に、リクエスト自身のものまで実行されます。 仕様に従うフォルダには、_spec-lock.jsonもあり、仕様から最後に取り込んだ内容が入っています。Echolotに管理させてください。

すべてのリクエストのキー

echolot = 1
name = "Sign in"
method = "POST"
url = "{{baseURL}}/auth/token"

[body]
syntax = "json"
file = "sign-in.body.json"

[[headers]]
name = "Content-Type"
value = "application/json"

[[assertions]]
target = "status"
check = "equals"
expected = "200"

[[captures]]
variable = "token"
from = "json"
path = "$.access_token"
scope = "workspace"
secret = true
キー意味
nameリクエストの名前。
urlクエリ文字列を含むURL。MCPの呼び出しを除くすべての種類にあります。
docsリクエストのドキュメント(Markdown)。
spec-operation元になった仕様のオペレーション。POST /auth/tokenなど。
[[headers]]name、value、そしてオフにしたものにはenabled = false。
[[disabled-params]]オフにしたクエリパラメータ:name、value。オンのものはURLに入っています。
[[disabled-form-fields]]オフにしたフォームフィールド:name、value。
[[variables]]リクエスト自身の変数。
[[assertions]]そのチェック。
[[captures]]レスポンスのたびに変数へ保存する値。
[auth]その認証。デフォルト:フォルダから継承。
[settings]アプリのものと異なる設定。

HTTPリクエスト(.req.toml)

キー意味
methodメソッド:GET、POST、または任意のトークン。デフォルトはGET。
[body]ボディ。省略するとなし。

[body]テーブルは、次の3つの形式のいずれかを取ります。

形式キー
テキストsyntax:json、xml、text、html、graphql、form(URLエンコードされたフォームフィールド)。file:リクエストの横にあるボディのファイル。
ディスクからストリーミングするファイルstream-from:ファイルのパス。
マルチパートsyntax = "multipart"と、パートごとの[[body.parts]]テーブル:name、そしてvalue(テキスト)またはfile(パス)、content-type、enabled。

GraphQLリクエスト(.gql.toml)

echolot = 1
name = "Search products"
url = "{{baseURL}}/graphql"
operation = "SearchProducts"
schema = "specs/shop.graphql"
query-file = "search-products.graphql"
graphql-variables = """
{
  "text": "ultralight"
}"""
キー意味
query-fileリクエストの横にある、クエリのファイル<slug>.graphql。
operationクエリに複数ある場合に、実行するオペレーション。
graphql-variablesGraphQLの変数をJSONテキストで。古いファイルではvariablesと呼ばれていました。
schemaチェックと補完に使うスキーマ:specs/内のファイル。
transportpost(デフォルト)、get、またはサブスクリプション用のwebsocket。
persisted-queriestrueにすると、最初はクエリのSHA-256だけを送信し、サーバがそれを知らない場合にクエリを送信します(自動永続化クエリ)。
batchtrueにすると、複数のオペレーションを持つドキュメントを、オペレーションごとに1エントリの配列として送信します。
[[uploads]]ファイルのアップロード:variable(ファイルを渡す変数)とpath。

gRPCリクエスト(.grpc.toml)

キー意味
protoサービスを記述する.protoファイル。specs/inventory.protoなど。
reflectiontrueにすると、代わりにサーバのリフレクションを使います。
serviceサービス。alpenglow.inventory.v1.Inventoryなど。
rpcメソッド。Reserveなど。
messageJSONテキストのメッセージ。クライアントストリーミングのメソッドでは、メッセージの配列。
deadline-msミリ秒単位のデッドライン。
compression送信するメッセージのgzipまたはdeflate。

WebSocketリクエスト(.ws.toml)

キー意味
subprotocols提示するサブプロトコル(配列)。
[[messages]]保存したメッセージ:name、text、enabled。

Socket.IOリクエスト(.sio.toml)

キー意味
versionサーバのSocket.IOバージョン:4(デフォルト)、3、2。
pathサーバが待ち受けるパス。デフォルトは/socket.io/。
namespace参加する名前空間。/supportなど。
socket-auth認証ペイロードをJSONテキストで。
[[emits]]保存したイベント:name、event、arguments(JSONテキスト)、確認応答を求めるack = true、enabled。

MQTTリクエスト(.mqtt.toml)

キー意味
version5(デフォルト)または3.1.1。
client-idクライアントID。空の場合はランダムなID。
clean-startfalseにすると、ブローカーにセッションを保持するよう求めます。デフォルトはtrue。
keep-alivePingの間隔(秒)。デフォルトは60。
[will]遺言メッセージ:topic、payload、qos、retain。
[[subscriptions]]filter、qos(デフォルトは0)、no-local、enabled。
[[messages]]パブリッシュ用に保存したメッセージ:name、topic、payload、qos、retain、content-type、enabled。

ユーザー名とパスワードは、リクエストのBasic認証です。

MCPの呼び出し(.mcp.toml)

echolot = 1
name = "search_catalog"
server = "alpenglow-mcp"
tool = "search_catalog"
arguments = """
{
  "query": "ultralight tent",
  "limit": 3
}"""
キー意味
servermcp-servers/内のサーバのスラッグ。
tool、resource、prompt、またはmethod呼び出す対象:名前でツール、URIでリソース、名前でプロンプト、または生のJSON-RPCメソッド。どれか1つ。
arguments引数をJSONテキストで。

チェック

キー意味
targetチェックの対象:status、header、json、body、time(ミリ秒)、size(バイト)、schema(JSON Schema)、graphql-errors、mcp-error、mcp-output-schema、openapi、grpc-status。
nameheaderの場合:ヘッダーの名前。
pathjsonの場合:JSONPath。$.items.lengthなど。
checkequals、not-equals、contains、not-contains、less-than、at-most、greater-than、at-least、exists、not-exists、matches(正規表現)、is-type、is-one-of、matches-schema。
expected比較する値。値が不要なチェックでは書かれません。
enabledfalseでオフにします。

各対象で使えるチェックは、スクリプトとテストを参照してください。

キャプチャ

キー意味
variable値を保存する変数。
fromjson、form、msgpack、xml、header、cookie、status、body。
path値の場所:JSONPath、XPath、ヘッダーまたはCookieの名前。statusとbodyにはありません。
scopeenvironment(デフォルト:有効な環境)またはworkspace。
secrettrueにすると、値をシークレットとしてキーチェーンに保存します。
enabledfalseでオフにします。

400以上のレスポンスや、存在しない値の場合、変数はそのまま変わりません。キャプチャを参照してください。

設定

キー意味
timeoutやり取り全体の秒数。
rawtrueにすると、自動のヘッダーを送信しません。
verify-tlsfalseにすると、証明書の検証をスキップします。
follow-redirectsfalseにすると、リダイレクトで止まります。
max-redirectsたどるリダイレクトの回数。
decompressfalseにすると、ボディをサーバがエンコードしたままにします。
cookiesfalseにすると、Cookieを送信も保存もしません。
http-versionautomatic、http1、http2、http3。
stream-limitイベントストリームやセッションを待ち受ける秒数。

リクエストの設定を参照してください。

認証

[auth]にはtypeと、その種類のキーがあります。[auth]のないリクエストやフォルダは継承します。ワークスペースのデフォルトは認証なしです。

typeキー
inheritなし:フォルダのものを使う。
noneなし:フォルダに認証があっても、認証なし。
basic、digestusername、password
bearertoken。Bearerでない場合はprefix
api-keyname、value、in(headerまたはquery)
oauth2grant(authorization-code、client-credentials、device-code)、authorization-url、token-url、device-authorization-url、client-id、client-secret、scope、audience、redirect-uri。PKCEをオフにするpkce = false。クライアントの資格情報をBasicではなくボディで送信するclient-authentication = "body"。Bearerでない場合はheader-prefix
aws-signatureaccess-key-id、secret-access-key、session-token、region、service
jwtalgorithm(HS256、HS384、HS512、RS256、RS384、RS512、PS256、PS384、PS512、ES256、ES384)、secret、secret-base64、payload、header、iatを省くissued-at = false、expires-in(秒、デフォルトは300)、in(headerまたはquery)、prefix、query-name(デフォルトはtoken)
hawkid、key、algorithm(sha256またはsha1)、ext、payload-hash
edgegridclient-token、client-secret、access-token、max-body(デフォルトは131072)、headers-to-sign
ntlmusername、password、domain、workstation

パスワード、トークン、キーは、すべてシークレットの{{variable}}として書いてください。認証を参照してください。

mcp-servers/

MCPサーバごとに1ファイル。ファイル名は、MCPの呼び出しが指定するスラッグです。

echolot = 1
name = "Alpenglow MCP"
transport = "http"
url = "https://demo.echolot.dev/mcp"
キー意味
nameサーバの名前。
transporthttp(Streamable HTTP)またはstdio(Echolotが起動するプログラム)。
urlhttpの場合:エンドポイント。
[[headers]]httpの場合:name、value、enabled。
commandstdioの場合:起動するプログラム。
argumentsstdioの場合:その引数(配列)。
working-directorystdioの場合:起動するフォルダ。
[[environment]]stdioの場合:環境変数、name、value、enabled。
[oauth]OAuthでサインインするサーバのクライアント設定:client-id、client-secret、scope、redirect-uri。

サーバを追加するを参照してください。

specs/

仕様ファイルはそのままの形で置かれます。OpenAPIドキュメント(.yaml、.yml、.json)、GraphQLスキーマ(.graphqlのSDL、またはJSONのイントロスペクション結果)、protobufファイル(.proto)です。 Echolotはそれらをその場で編集し、書式を保ちます。リクエストとモックは、specs/alpenglow.yamlのように、パスでそれらを指定します。仕様を参照してください。

mocks/

モックサーバごとに1ファイルと、その横にJavaScriptのルート。

echolot = 1
name = "Shop"
spec = "specs/alpenglow.yaml"
port = 4010
delay = 200

[[scenarios]]
operation = "GET /products/{sku}"
status = "404"

[[routes]]
id = "e5f6a7b8"
method = "GET"
path = "/users/{id}"
summary = "One user"

[[routes.responses]]
name = "OK"
status = 200
content-type = "application/json"
headers = [{ name = "X-Request-Id", value = "{{$randomUUID}}" }]
body = """
{
  "id": "{{request.params.id}}",
  "name": "{{$randomFullName}}"
}"""

[[routes.responses]]
name = "Not found"
status = 404
content-type = "application/json"
rules = [{ source = "path", name = "id", value = "0" }]
body = """{ "error": "no user {{request.params.id}}" }"""
キー意味
nameモックの名前。
spec提供する仕様。なければ、モックのルートだけが応答します。
portポート。デフォルトは4010。
share-on-networktrueにすると、このMacだけでなく、すべてのネットワークインターフェースで応答します。
delay応答の前に待つミリ秒数。
failure-rate意図的な500で応答するリクエストの割合(%)、0〜100。
validate-requestsfalseにすると、仕様に違反するリクエストにも応答します。デフォルトはtrue。
[[scenarios]]仕様のオペレーションに選んだ応答:operation(GET /petsなど)、status、example(例の名前)。
[[routes]]手書きのルート:id(ルートを変更しても変わりません)、method(またはANY)、path(パラメータは{id})、summary、オフのルートにはenabled = false、response(デフォルトのレスポンスの名前。省略すると最初のもの)、request-content-typeとrequest-body(そこから作るリクエストが送信する内容)。
[[routes.responses]]上のルートの応答の1つ:name、status、content-type、headers(nameとvalue)、rules(sourceはpath、query、header、bodyのいずれか。name。valueは、*で任意、空でなし)、body。

mocks/<slug>.jsには、モックのJavaScriptのルートが入っており、手書きのルートと仕様より先に応答します。 仕様のオペレーションのレスポンスは、モックには保存されません。例は仕様に入ります。モック、ルートとダミーデータ、JavaScriptのルートを参照してください。

flows/

フローごとに1ファイル、<slug>.flow.toml。Echolotはブロック、接続、ノートを固定の順序で書き出すので、ブロックを移動しても変更は2行です。

echolot = 1
name = "Place a test order"
description = "Places an order, then asks a person whether to keep it."

[mcp]
tool = "place_test_order"
description = "Places a test order on the demo shop, asking a person before keeping it."

[[blocks]]
id = "signin"
kind = "request"
title = "Sign in"
position = [330, 250]

[blocks.settings]
request = "auth/sign-in"

[[wires]]
from = "start.run"
to = "signin.run"
キー意味
name、descriptionフローの名前と、その内容。
[mcp]フローをツールとしてエージェントに提供します:tool(その名前)とdescription。
[schedule]スケジュールで実行します:every-minutes、またはcron("0 6 * * *"など)。
[webhook]リクエストが届いたときに実行します:method(デフォルトはPOST)とpath。
[[inputs]]入力:name、type(any、text、number、bool、object、list、secret)、description、default、required。
[[blocks]]ブロック:id、kind、title、position(キャンバス上の[x, y])、paused、color、そして種類ごとの設定を持つ[blocks.settings]。
[[wires]]接続:fromとto。それぞれblock.port。
[[groups]]ブロックのグループ:title、blocks(そのID)、color。
[[notes]]キャンバス上のノート:text、frame([x, y, width, height])。

ブロックの種類とその設定は、ブロックにあります。

assistant/

ワークスペースで共有するアシスタントとの会話:どのエディタでも読める<slug>.mdと、Echolotが再び開くための<slug>.json。

その他のファイル

Echolotが知らないファイルはそのままにされるため、README、.gitignore、データファイルをワークスペースに置いても構いません。 エージェントやフローが保存するデータ(exports/products.csvなど)は、指定された場所、つまりワークスペース内に保存されます。

このページの内容