Fitter MCP
Fitter — AIエージェント向けWebデータ
Fitterは、あらゆるWebサイトやAPIを宣言的に構造化JSONに変換します。 1つのJSON/YAML設定で、データの場所(HTTPリクエスト、ヘッドレスブラウザ、ファイル、静的値)と抽出内容(JSONパス、CSSセレクタ、XPath)を記述します。コードも、壊れやすいスクレイピングスクリプトも不要です。
🚀 ブラウザで試す — WebAssemblyにコンパイルされた本物のエンジン: ライブ例、ビジュアル設定ビルダー、インストール不要。
設定はプレーンなデータであるため、LLMがそれらを作成できます。組み込みのMCPサーバーを使用すると、Claude Code、Claude Desktop、または任意のMCPクライアントが、オンデマンドでマシン上でスクレイピングパイプラインを作成・実行できます。
「タイトルとスコア付きのHackerNewsトップ5ストーリーを取得して」 → モデルがfitter設定を作成し、検証し、ローカルで実行して、クリーンなJSONを取得します。
1つのエンジン、5つの使い方:
🤖 Fitter MCP | MCPサーバーがfitterをClaude Code、Claude Desktop、および任意のMCPクライアントに公開します |
🧠 Fitter Agent | AI搭載CLI: 自然言語 → 設定 → 実行結果 |
🖥 Fitter CLI | テスト/デバッグ/ホーム用途で設定をローカル実行 |
📦 Fitter Lib | 独自のGoプログラムにエンジンを組み込む |
⚙️ Fitter | スケジューリングと通知を備えた長時間実行サービスモード |
なぜAIエージェントにfitterなのか?
宣言的で監査可能 — エージェントは、読み取り・保存・再実行が可能な設定を生成し、使い捨てコードではありません
ローカルファースト — すべての取得はマシン上で行われます。サードパーティのスクレイピングAPI、キー、リクエストごとの課金はありません
バッテリー同梱 — HTTPクライアント、ヘッドレスブラウザ(Playwright/Chromium/Docker)、JSON/HTML/XML/XPath/PDF解析、ページネーション、キャッシュ参照、ホストレート制限 — 単一の静的バイナリに
再利用可能 — 今日エージェントが作成したものは、明日のcronジョブやサービス設定になります
Fitter_MCPの使い方
Fitter MCPは、Model Context Protocolサーバー(stdioトランスポート)であり、任意のMCPクライアント(Claude Code、Claude Desktop、IDEアシスタント、カスタムエージェント)がFitter設定を実行し、構造化JSONを取得できるようにします。
クイックスタート(Claude Desktop — ワンクリック)
リリースページからfitter-mcp-<os>-<arch>.mcpbをダウンロードして開くだけで、Claude Desktopがサーバーを自動的にインストールします。
クイックスタート(Claude Code)
# 1. get the binary: download fitter_mcp_<version>-<os>-<arch> from the release page
# https://github.com/PxyUp/fitter/releases — or build it from source:
go build -o fitter_mcp ./cmd/mcp
# 2. register it once, available in every project
claude mcp add fitter -s user -- "$(pwd)/fitter_mcp"あとは次のように尋ねるだけです:
fitterを使って、タイトルとスコア付きのHackerNewsトップ5ストーリーを取得して
モデルはfitter_config_referenceを呼び出し、設定を作成し、必要に応じてfitter_validate_configでチェックし、fitter_runで実行します — すべてのデータ取得はマシン上でローカルに行われます。既製のパイプラインとして、examples/config_morning_briefing.jsonを試してください:
fitterでexamples/config_morning_briefing.jsonを実行して、ブリーフィングを教えて
Claude Desktopに登録
{
"mcpServers": {
"fitter": {
"command": "/path/to/fitter_mcp"
}
}
}ブラウザサポート(Playwright)
.mcpbバンドルとネイティブバイナリにはブラウザは含まれていません。HTTP、静的、ファイルコネクタはすぐに動作しますが、ブラウザ設定(playwrightコネクタ)にはPlaywrightのブラウザが必要です。入手方法はいくつかあります:
初回使用時(ネイティブバイナリ /
.mcpb):playwrightコネクタで"install": trueを設定します — fitterは初回使用時に、組み込みのplaywright-goバージョンに一致するドライバーとブラウザをダウンロードします(一度きり、キャッシュされます)。そのため、別途インストール手順は不要です。事前に(ネイティブ、オプション): 初回ダウンロードを避けるために、fitterがビルドされているのと同じ
playwright-goバージョンでブラウザを事前にインストールします(go.modを確認、現在はv0.6100.0):go run github.com/mxschmitt/playwright-go/cmd/playwright@v0.6100.0 install # Linux: append --with-deps to also install the required OS librariesバージョンは
go.modと正確に一致する必要があります —playwright-goは不一致のドライバーでは実行を拒否します。その後、"install": trueなしで設定を実行します。Docker: Chromium、Firefox、WebKitがプリインストールされた
ghcr.io/pxyup/fitter-mcp:playwrightイメージを使用します("install": trueは不要)。
ツール
Tool | Description |
| インラインで渡されたFitter設定(JSONまたはYAML文字列)を実行し、抽出したデータをJSONとして返します。オプションの |
|
|
|
|
| URLを取得し、コンパクトな構造の概要と候補セレクタ/パス(JSONの場合はgjsonパス、HTMLの場合は繰り返し要素/リスト行セレクタ)を返します。これにより、モデルはセレクタを推測してnullを取得する代わりに、最初の試行で設定を作成できます。クライアントレンダリングされたSPAを検出し、ヘッドレスブラウザで |
| 設定を実行せずに検証します(構造、 |
| 設定形式全体(コネクタ、パーサー、モデル/フィールドスキーマ、プレースホルダー、通知、参照、制限)の簡潔なリファレンスを作業例付きで返します。モデルは外部ドキュメントなしで設定を作成できます。 |
このリファレンスは、リソースをサポートするクライアント向けにMCPリソースfitter://config-referenceとしても公開されています。
設定形式はFitter_CLIとまったく同じです。トップレベルのオブジェクトにはitem(必須)、limits、referencesがあります。通知も機能します(結果はさらにhttp/telegram/redis/file/consoleにプッシュされます)。trigger_configとhttp_serverはサービスモード専用で、MCP呼び出しでは無視されます。
リモート/ホストモード(ストリーミングHTTP)
デフォルトではfitter_mcpはstdioで通信します。代わりにストリーミングHTTPトランスポートを提供するには--httpを渡します — 共有チームサーバー、コンテナ、または任意のリモートデプロイメント向けです:
# serve MCP at http://<host>:8080/mcp (health probe at /healthz)
FITTER_MCP_AUTH_TOKEN=my-secret fitter_mcp --http :8080
# register the remote endpoint in Claude Code
claude mcp add --transport http fitter http://localhost:8080/mcp --header "Authorization: Bearer my-secret"--http <addr>(環境変数FITTER_MCP_HTTP_ADDR)— リッスンアドレス。空の場合はstdioモードFITTER_MCP_AUTH_TOKEN— 設定すると、すべての/mcpリクエストはAuthorization: Bearer <token>を送信する必要があります。設定しない場合、エンドポイントは認証なしになるため、localhostにバインドするか、プロキシの背後に置いてください--stateless(環境変数FITTER_MCP_STATELESS=true)— セッションごとの状態がないため、レプリカをスティッキーセッションなしでロードバランサーの背後に配置できます
サーバーはSIGINT/SIGTERMでグレースフルシャットダウンします。
Docker
スリムなマルチアーキテクチャイメージ(linux/amd64 + linux/arm64)が各リリースに同梱されています:
# hosted HTTP mode
docker run --rm -p 8080:8080 \
-e FITTER_MCP_HTTP_ADDR=:8080 \
-e FITTER_MCP_AUTH_TOKEN=my-secret \
ghcr.io/pxyup/fitter-mcp:latest
# or stdio mode, spawned by the MCP client
claude mcp add fitter -s user -- docker run --rm -i ghcr.io/pxyup/fitter-mcp:latestスリムイメージにはfitterバイナリとCA証明書のみが含まれています。サーバー/静的/ファイルコネクタは動作しますが、ブラウザコネクタ(chromium/docker/playwright)は動作しません。
ブラウザベースの設定にはplaywrightバリアントを使用します。これはPlaywrightとChromium、Firefox、WebKitをバンドルしています(fitterがビルドされているplaywright-goバージョンに一致するため、設定で"install": trueは不要です):
docker run --rm -i ghcr.io/pxyup/fitter-mcp:playwright # stdio mode
# per-release tag: ghcr.io/pxyup/fitter-mcp:vX.Y.Z-playwrightこれはDockerfile.mcp-playwrightからビルドされています。--build-arg PLAYWRIGHT_BROWSERS=chromiumでビルドすると、より小さなChromiumのみのイメージになります。
DockerでのOAuth2アカウント
両方のイメージにはfitter_cliが同梱されているため、一度きりのOAuth2ログインをコンテナ内で実行できます。トークンを/tokensにマウントされたボリューム(イメージ内で事前に作成された書き込み可能なディレクトリ)に保存し、MCPサーバーと共有します:
# one-time login, device flow: no ports needed — open the printed url on any device
docker run --rm -it -v fitter-tokens:/tokens --entrypoint fitter_cli \
ghcr.io/pxyup/fitter-mcp:latest \
auth --provider github --client-id <ID> --client-secret <SECRET> --token-file /tokens/github.json
# or browser flow (device flow not enabled for the app): publish the callback port and
# bind on 0.0.0.0 so the published port reaches the listener; the browser still visits 127.0.0.1
docker run --rm -it -p 8988:8988 -e FITTER_AUTH_LISTEN=0.0.0.0 \
-v fitter-tokens:/tokens --entrypoint fitter_cli ghcr.io/pxyup/fitter-mcp:latest \
auth --provider github --client-id <ID> --client-secret <SECRET> --token-file /tokens/github.json
# then run the MCP server with the same volume; configs reference "token_file": "/tokens/github.json"
# stdio mode (spawned by the MCP client, no port):
docker run --rm -i -v fitter-tokens:/tokens ghcr.io/pxyup/fitter-mcp:latest
# hosted HTTP mode (MCP endpoint on 8080, like the run examples above):
docker run --rm -p 8080:8080 -v fitter-tokens:/tokens \
-e FITTER_MCP_HTTP_ADDR=:8080 \
-e FITTER_MCP_AUTH_TOKEN=my-secret \
ghcr.io/pxyup/fitter-mcp:latest注: 8988は一度きりのブラウザフローログイン専用です。MCPサーバー自体はstdioモードではポートを必要とせず、ホストHTTPモードでは8080のみ必要です。
Dockerでのログイン済みブラウザセッション
ブラウザセッションにはplaywrightイメージが必要です(スリム版にはブラウザがありません)。一度きりのヘッド付きログインにはディスプレイが必要なため、ホスト上で実行し、セッションディレクトリをコンテナにバインドマウントします(イメージは書き込み可能な/sessionsを事前に作成します):
# on the host: log in once, save the session
fitter_cli browser-login --url https://example.com/login --storage-state ~/.fitter/sessions/example.json
# run the MCP server with the sessions dir mounted; configs reference "storage_state_file": "/sessions/example.json"
docker run --rm -i -v ~/.fitter/sessions:/sessions ghcr.io/pxyup/fitter-mcp:playwrightバインドマウント(名前付きボリュームではなく)を使用してください。コンテナは毎回の実行後に更新されたクッキーを書き戻すため、ホスト側のコピーは最新の状態を保ち、いつでもbrowser-loginで再拡張できます。
ボリュームはサーバーが書き込み可能な状態を維持する必要があります。ローテーションされたリフレッシュトークンは、リフレッシュのたびに書き戻されます。
環境変数
FITTER_PLUGINS - string[""] - プラグインフォルダのパス、Fitter/Fitter_CLIの
--pluginsフラグと同じFITTER_MCP_HTTP_ADDR - string[""] - リモートモードのリッスンアドレス、
--httpと同じFITTER_MCP_AUTH_TOKEN - string[""] - HTTPエンドポイントを保護するベアラートークン
FITTER_MCP_STATELESS - bool[false] - ステートレスHTTPトランスポート、
--statelessと同じ
レシピ
Complete, tested configs showing the main patterns. All of them run unchanged via Fitter_MCP (fitter_run_file), Fitter_CLI or the library — more in examples/.
APIのないページをスクレイピングし、APIのあるページから情報を補完する
GitHub trendingには公式APIがありません。HTMLからリポジトリのスラッグをスクレイピングし(html_attributeがhrefを読み取ります)、その後{PL}を使って各リポジトリをGitHub REST APIに展開します:
examples/config_github_trending.json
{
"item": {
"connector_config": {
"response_type": "HTML",
"url": "https://github.com/trending",
"server_config": { "method": "GET", "headers": { "User-Agent": "Mozilla/5.0 (fitter demo)" } }
},
"model": {
"array_config": {
"root_path": "article.Box-row h2 a",
"length_limit": 5,
"item_config": {
"field": {
"type": "string",
"html_attribute": "href",
"generated": { "model": {
"type": "object",
"connector_config": {
"response_type": "json",
"url": "https://api.github.com/repos{PL}",
"server_config": { "method": "GET", "headers": { "User-Agent": "fitter-demo" } },
"null_on_error": true
},
"model": { "object_config": { "fields": {
"repo": { "base_field": { "type": "string", "path": "full_name" } },
"stars": { "base_field": { "type": "int", "path": "stargazers_count" } },
"language": { "base_field": { "type": "string", "path": "language" } }
} } }
} }
}
}
}
}
},
"limits": { "host_request_limiter": { "api.github.com": 2 } }
}[{"repo": "block/buzz", "stars": 6214, "language": "Rust"}, {"repo": "koala73/worldmonitor", "stars": 71179, "language": "TypeScript"}]式を使ってJSONフィールドで結合する
配列の項目がオブジェクトの場合、結合キーはその中にあります。{{{FromExp=...}}}(現在の項目fResに対するexpr-lang)で取り出します。書籍検索→著者詳細、検索クエリはinputで指定します:
examples/config_book_authors.json
"url": "https://openlibrary.org/authors/{{{FromExp=fromJSON(fRes).author_key[0]}}}.json"./fitter_cli --path=examples/config_book_authors.json --input=dune[{"title": "Dune", "year": 1965, "author": {"name": "Frank Herbert", "born": "8 October 1920", "died": "11 February 1986"}}]結果をローカルファイルに書き込む
file_storage生成フィールドは、フィールドを書き込みに変換します。上位5つの暗号通貨をCSVに追加し、各項目を1行にします。裸の{{{json.path}}}プレースホルダーは現在の項目を読み取ります。{HUMAN_INDEX}は1から始まるランクを刻印します(項目は並列で処理されるため、追加は完了順に配置されます。ランク列で並べ替えてください):
examples/config_crypto_csv.json
"file_storage": {
"content": "{HUMAN_INDEX},{{{name}}},{{{current_price}}},{{{price_change_percentage_24h}}}\n",
"file_name": "coins.csv",
"path": "/tmp/fitter-report",
"append": true
}$ sort -n /tmp/fitter-report/coins.csv
1,Bitcoin,64778,-2.3
2,Ethereum,1881.01,-3.4
3,Tether,0.999265,0PDFからテキストを抽出する
response_type: "pdf"は、取得したPDFをJSONドキュメントに変換します。{"text": "...", "pages": ["..."], "total_pages": N} — これにより、通常のJSONパス(text、pages.0)や式が機能します。Bitcoinホワイトペーパー、ページ数、トリミングされたイントロ:
{
"item": {
"connector_config": {
"response_type": "pdf",
"url": "https://bitcoin.org/bitcoin.pdf",
"server_config": { "method": "GET" }
},
"model": {
"object_config": {
"fields": {
"total_pages": { "base_field": { "type": "int", "path": "total_pages" } },
"intro": {
"base_field": {
"type": "string",
"path": "pages.0",
"generated": {
"calculated": {
"type": "string",
"expression": "trim(fRes[:100]) + \"...\""
}
}
}
}
}
}
}
}
}{"intro": "Bitcoin: A Peer-to-Peer Electronic Cash SystemSatoshi Nakamotosatoshin@gmx.comwww.bitcoin.orgAbstrac...", "total_pages": 9}情報収集の方法
Server - 一部のAPIまたはHTTPリクエストからの応答を解析する(http.Clientの使用)
Browser - chromium + docker + playwright/cypressを使用して実際のブラウザをエミュレートし、DOM情報を取得する
Static - 静的文字列をデータとして解析する
解析可能な形式
JSON - JSONを解析して特定の情報を取得する
XML - XMLツリーを解析して特定の情報を取得する
HTML - DOMツリーを解析して特定の情報を取得する
XPath - DOMツリーを解析して特定の情報を取得するが、XPathによる
PDF - PDFドキュメントからテキストを抽出する。コンテンツはJSON
{"text": "...", "pages": ["..."], "total_pages": N}として公開されるため、textやpages.0のような通常のJSONパスが機能する
ライブラリとして使用する
go get github.com/PxyUp/fitterpackage main
import (
"fmt"
"github.com/PxyUp/fitter/lib"
"github.com/PxyUp/fitter/pkg/config"
"log"
"net/http"
)
func main() {
res, err := lib.Parse(&config.Item{
ConnectorConfig: &config.ConnectorConfig{
ResponseType: config.Json,
Url: "https://random-data-api.com/api/appliance/random_appliance",
ServerConfig: &config.ServerConnectorConfig{
Method: http.MethodGet,
},
},
Model: &config.Model{
ObjectConfig: &config.ObjectConfig{
Fields: map[string]*config.Field{
"my_id": {
BaseField: &config.BaseField{
Type: config.Int,
Path: "id",
},
},
"generated_id": {
BaseField: &config.BaseField{
Generated: &config.GeneratedFieldConfig{
UUID: &config.UUIDGeneratedFieldConfig{},
},
},
},
"generated_array": {
ArrayConfig: &config.ArrayConfig{
RootPath: "@this|@keys",
ItemConfig: &config.ObjectConfig{
Field: &config.BaseField{
Type: config.String,
},
},
},
},
},
},
},
}, nil, nil, nil, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(res.ToJson())
}
出力:
{
"generated_array": ["id","uid","brand","equipment"],
"my_id": 6000,
"generated_id": "26b08b73-2f2e-444d-bcf2-dac77ac3130e"
}lib.ParseCtx(ctx, ...)を使用してcontext.Contextを渡します。キャンセルすると進行中のフェッチ(HTTPリクエスト、ヘッドレスブラウザ、Dockerコンテナ)が中止され、デッドラインがエンドツーエンドで適用されます。lib.Parseはlib.ParseCtx(context.Background(), ...)と同等です。
Fitterの使い方
またはローカルで:
go run cmd/fitter/main.go --path=./examples/config_api.json引数
--path - string[""] - Fitterの設定ファイルのパス
--url - string[""] - Fitterの設定のURL
--verbose - bool[false] - ログを有効にする
--plugins - string[""] - Fitter用プラグインのパス
--log-level - enum["info", "error", "debug", "fatal"] - ログレベルを設定する(verboseがtrueの場合のみ)
Fitter_CLIの使い方
またはローカルで:
go run cmd/cli/main.go --path=./examples/cli/config_cli.json引数
--path - string[""] - Fitter_CLIの設定ファイルのパス
--url - string[""] - Fitter_CLIの設定のURL
--copy - bool[false] - 情報をクリップボードにコピーする
--pretty - bool[true] - 読みやすい結果にする(コピーにも影響)
--verbose - bool[false] - ログを有効にする
--omit-error-pretty - bool[false] - prettyが無効な場合に純粋な値を提供する
--plugins - string[""] - Fitter用プラグインのパス
--log-level - enum["info", "error", "debug", "fatal"] - ログレベルを設定する(verboseがtrueの場合のみ)
--input - string[""] - フォーマットのための入力値を指定する。例:
--input=\""124"\"--input=124--input='{"test": 5}'
./fitter_cli_${VERSION} --path=./examples/cli/config_cli.json --copy=truefitter_cli auth — OAuth2アカウントを接続する
一度だけの対話型ログインで、oauth2コネクタ設定用の(リフレッシュ)トークンを保存します:
# device flow (default when the provider supports it): no callback, works headless
./fitter_cli_${VERSION} auth --provider github --client-id <ID> --client-secret <SECRET> --token-file ~/.fitter/tokens/github.json
# custom provider without preset
./fitter_cli_${VERSION} auth --auth-url https://.../authorize --token-url https://.../token --client-id <ID> --token-file ./token.json引数:
--provider - 既知のエンドポイントを持つプリセット:
github|google|microsoft|gitlab|spotify--client-id / --client-secret - OAuth2アプリの認証情報(一部のデバイスフローはシークレットなしで動作します)
--token-file - 受け取ったトークンを保存する場所(0600パーミッション)。
oauth2.token_fileで同じパスを参照します--flow -
auto(利用可能ならデバイス、それ以外はブラウザ)、device(URLにアクセスしてコードを入力)、またはbrowser(PKCEを使用したlocalhostコールバック、デフォルトポート8988 — アプリのコールバックURLとしてhttp://127.0.0.1:8988/callbackを登録)--scopes - カンマ区切りのスコープ
--auth-url/--token-url/--device-auth-url/--auth-style - プリセットのないプロバイダー向けのエンドポイント上書き
--port - int[8988] - ブラウザフローのコールバックポート(環境変数
FITTER_AUTH_PORT)。デフォルトでは、プロバイダーに登録するコールバックURLはhttp://127.0.0.1:8988/callbackです--listen - ブラウザフローのバインドアドレス、デフォルトは
127.0.0.1。コンテナ内では0.0.0.0に設定して、公開ポートがリスナーに到達するようにします(環境変数FITTER_AUTH_LISTEN)--redirect-url - リスンアドレスと異なる場合にプロバイダーに登録するコールバックURL。例:Dockerポートマッピング(環境変数
FITTER_AUTH_REDIRECT_URL)--no-browser - 認証URLのみを表示する
Docker内で実行する場合:Docker内のOAuth2アカウントを参照してください。
ログイン後、コマンドはすぐに使用できるoauth2設定ブロックを出力します。コネクタはアクセストークンを自動的に更新し、ローテーションされたリフレッシュトークンをトークンファイルに書き戻すため、ログインは一度だけ必要です。
fitter_cli browser-login — 実際のログインセッションを再利用する
API/OAuthのないサイト向け:実際の(ヘッド付き)ブラウザウィンドウで手動で一度ログインします。パスワード、2FA、SSO、キャプチャを含むあらゆる認証方式が機能します。そして、storage_state_fileを介してヘッドレススクレイピング用にセッションを保存します:
./fitter_cli_${VERSION} browser-login --url https://example.com/login --storage-state ~/.fitter/sessions/example.json
# a browser window opens; log in, then press Enter in the terminal to save the session引数:
--url - 開くログインページ(必須)
--storage-state - セッションを保存する場所(cookies + localStorage、0600パーミッション)。
playwright.storage_state_fileで同じパスを参照します(必須)--browser - enum["Chromium", "FireFox", "WebKit"] デフォルトは"Chromium"。スクレイピング設定と同じ値を使用します。サイトがセッションをブラウザのフィンガープリントにバインドする場合があります
--install - bool[false] - 最初にPlaywrightブラウザをインストールする
--indexeddb - bool[false] - スナップショットにIndexedDBを含める(Firebase Authなど)
コマンドを再実行すると、既存の状態が最初に読み込まれるため、最初からログインしなくてもセッションを拡張/更新できます。スクレイピングコネクタも毎回実行後に更新されたクッキーを書き戻すため、定期的に使用されている限りセッションは維持されます。ディスプレイが必要です。Docker内では、このコマンドをホストで実行し、ファイルをマウントしてください。Docker内のブラウザセッションを参照してください。
例:
Server版 HackerNews + Quotes + Guardian News - API + HTML + XPath解析を使用
Chromium版 Guardian News + Quotes - HTML解析 + ブラウザエミュレーションを使用
Docker版 Docker版: Guardian News + Quotes - HTML解析 + Dockerイメージからのブラウザを使用
Playwright版 Playwright版: Guardian News + Quotes - HTML解析 + Playwrightフレームワークからのブラウザを使用
Playwright版 Playwright版: England Cities + Weather - HTML + XPath解析 + Playwrightフレームワークからのブラウザを使用
JSON版 ページネーションを生成 - 静的コネクタを使用してページネーション配列を生成
Server版 現在時刻を取得 - URLから時刻を取得してフォーマットする
Fitter_Agentの使い方
Fitter Agentは、Claudeを使用して自然言語のリクエストをFitter設定に変換し、自動的に実行するAI搭載のCLIです。
またはローカルで:
export ANTHROPIC_API_KEY=<your-anthropic-api-key>
go run cmd/agent/main.go引数
--api-key - string[""] - Anthropic APIキー。キーがシェル履歴に残らないように、
ANTHROPIC_API_KEY環境変数を推奨します--model - string["claude-opus-4-8"] - 使用するClaudeモデル
--effort - enum["low", "medium", "high", "xhigh", "max"] - 推論の努力量、デフォルトは"high"。より速く/安価な設定には下げ、より難しい抽出には上げます
--verbose - bool[false] - ログを有効にする
--log-level - enum["info", "error", "debug", "fatal"] - ログレベルを設定する
--plugins - string[""] - Fitter用プラグインのパス
--chromium-limit - uint[0] - 同時Chromiumインスタンス数を制限する
--docker-limit - uint[0] - 同時Dockerコンテナ数を制限する
--playwright-limit - uint[0] - 同時Playwrightインスタンス数を制限する
仕組み
┌─────────────────────────────────────────────────────────────────┐
│ 1. User enters natural language request │
│ "Get top 5 HackerNews stories with titles and scores" │
│ ↓ │
│ 2. Claude returns a config in a schema-constrained response │
│ ↓ │
│ 3. Agent validates it; on failure the error is handed back │
│ to Claude to repair (up to 3 attempts) │
│ ↓ │
│ 4. Agent displays config and asks for confirmation │
│ ↓ │
│ 5. On confirmation, executes via lib.Parse() │
│ ↓ │
│ 6. Returns structured JSON result │
└─────────────────────────────────────────────────────────────────┘設定の調整
エージェントは会話を保持するため、設定が生成された後は、リクエスト全体を言い直す代わりに、変更したいことを言うだけで済みます:
> Get top 3 HackerNews stories with titles and scores
refine> Only return 5 items and also include the article URLnewを使用すると、現在の設定を忘れて新しいセッションを開始します。
対話型REPLコマンド
help - ヘルプメッセージを表示
new/reset - 現在の設定を忘れて新しく開始
clear - 画面をクリア
exit/quit/q - エージェントを終了
セッション例
$ export ANTHROPIC_API_KEY=sk-ant-...
$ ./fitter_agent
╔══════════════════════════════════════════════════════════════╗
║ Fitter Agent - AI-Powered Data Extraction ║
╚══════════════════════════════════════════════════════════════╝
Describe what you want to extract. Follow-up messages refine the
previous config. Type 'help' for commands.
> Get top 3 HackerNews stories with titles and scores
┌─ Generated Fitter Config ───────────────────────────────────────
{
"item": {
"connector_config": {
"response_type": "json",
"url": "https://hacker-news.firebaseio.com/v0/topstories.json",
"server_config": { "method": "GET" }
},
"model": {
"array_config": {
"root_path": "@this",
"length_limit": 3,
"item_config": {
"fields": {
"id": { "base_field": { "type": "int" } },
"story": {
"base_field": {
"type": "int",
"generated": {
"model": {
"type": "object",
"connector_config": {
"response_type": "json",
"url": "https://hacker-news.firebaseio.com/v0/item/{PL}.json",
"server_config": { "method": "GET" }
},
"model": {
"object_config": {
"fields": {
"title": { "base_field": { "type": "string", "path": "title" } },
"score": { "base_field": { "type": "int", "path": "score" } }
}
}
}
}
}
}
}
}
}
}
}
}
}
└──────────────────────────────────────────────────────────────────
Execute this config? [y/n]: y
┌─ Result ────────────────────────────────────────────────────────
[
{
"id": 46740029,
"story": { "title": "Show HN: Open-source project", "score": 161 }
},
{
"id": 46737630,
"story": { "title": "Interesting article", "score": 237 }
},
{
"id": 46735644,
"story": { "title": "New technology release", "score": 192 }
}
]
└──────────────────────────────────────────────────────────────────
> exit
Goodbye!リクエスト例
Request | What it does |
| 現在のBTC価格を取得 |
| CSSセレクタを使用したHTMLスクレイピング |
| ネストされたAPI呼び出し |
| シンプルなAPI抽出 |
| Webスクレイピング |
サポートされている機能
エージェントは以下の設定を生成できます:
JSON APIs - GET/POSTメソッドを使用したREST API
HTML Scraping - CSSセレクタベースの抽出
XPath Scraping - XPathベースの抽出
Nested API Calls - リスト内の各項目の詳細を取得
Browser Emulation - JSレンダリングページ用のPlaywright
Formatted Fields - プレースホルダー付きのURLテンプレート
Array Limiting - 結果をN項目に制限
設定
コネクタ
データを取得する方法です
type ConnectorConfig struct {
ResponseType ParserType `json:"response_type" yaml:"response_type"`
Url string `json:"url" yaml:"url"`
Attempts uint32 `json:"attempts" yaml:"attempts"`
NullOnError bool `yaml:"null_on_error" json:"null_on_error"`
StaticConfig *StaticConnectorConfig `json:"static_config" yaml:"static_config"`
IntSequenceConfig *IntSequenceConnectorConfig `json:"int_sequence_config" yaml:"int_sequence_config"`
ServerConfig *ServerConnectorConfig `json:"server_config" yaml:"server_config"`
BrowserConfig *BrowserConnectorConfig `yaml:"browser_config" json:"browser_config"`
PluginConnectorConfig *PluginConnectorConfig `json:"plugin_connector_config" yaml:"plugin_connector_config"`
ReferenceConfig *ReferenceConnectorConfig `yaml:"reference_config" json:"reference_config"`
FileConfig *FileConnectorConfig `json:"file_config" yaml:"file_config"`
}NullOnError[false] - true に設定すると、すべてのエラーが無視されます
ResponseType - enum["HTML", "json", "xpath", "XML", "pdf"] - コネクタからデータがどの形式で取得されるか
Attempts - コネクタによるデータ取得を試行する回数
Url - リクエストするアドレスを指定します。重要: 親の値を文字列として注入 することができます
https://api.open-meteo.com/v1/forecast?latitude={{{latitude}}}&longitude={{{longitude}}}&hourly=temperature_2m&forecast_days=1
設定は次のいずれかになります:
例:
{
"response_type": "xpath",
"attempts": 3,
"url": "https://openweathermap.org/find?q={PL}",
"browser_config": {
"playwright": {
"timeout": 30,
"wait": 30,
"install": false,
"browser": "Chromium"
}
}
}PluginConnectorConfig
コネクタはプラグインシステムを介して定義できます。これを使用するには、Fitter/Cli(プラグインの場所)に次のフラグを適用する必要があります:
... --plugins=./examples/plugin--plugins - 指定されたフォルダ内の ".so" 拡張子を持つすべてのファイルを検索します(サブディレクトリは除外)
type PluginConnectorConfig struct {
Name string `json:"name" yaml:"name"`
Config json.RawMessage `json:"config" yaml:"config"`
}{
"name": "connector",
"config": {
"name": "Elon"
}
}Name - プラグインの名前
Config - プラグインの json 設定
プラグインのビルド方法
プラグインをビルドします
go build -buildmode=plugin -gcflags="all=-N -l" -o examples/plugin/connector.so examples/plugin/connector/connector.gopl.ConnectorPlugin インターフェースを実装する Plugin 変数をエクスポートしてください
CLI の例:
https://github.com/PxyUp/fitter/blob/master/examples/cli/config_plugin.json#L5
プラグインの例:
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/PxyUp/fitter/pkg/config"
"github.com/PxyUp/fitter/pkg/logger"
"github.com/PxyUp/fitter/pkg/builder"
pl "github.com/PxyUp/fitter/pkg/plugins/plugin"
)
var (
_ pl.ConnectorPlugin = &plugin{}
Plugin plugin
)
type plugin struct {
log logger.Logger
Name string `json:"name" yaml:"name"`
}
func (pl *plugin) Get(ctx context.Context, parsedValue builder.Interfacable, index *uint32, input builder.Interfacable) ([]byte, error) {
return []byte(fmt.Sprintf(`{"name": "%s"}`, pl.Name)), nil
}
func (pl *plugin) SetConfig(cfg *config.PluginConnectorConfig, logger logger.Logger) {
pl.log = logger
if cfg.Config != nil {
err := json.Unmarshal(cfg.Config, pl)
if err != nil {
pl.log.Errorw("cant unmarshal plugin configuration", "error", err.Error())
return
}
}
}ReferenceConnectorConfig
references からプリフェッチされたデータを取得できるコネクタ
type ReferenceConnectorConfig struct {
Name string `yaml:"name" json:"name"`
}例
https://github.com/PxyUp/fitter/blob/master/examples/cli/config_ref.json#L66
Name - references マップからの参照名
IntSequenceConnectorConfig
結果として整数シーケンスを生成する静的コネクタの改良版
type IntSequenceConnectorConfig struct {
Start int `json:"start" yaml:"start"`
End int `json:"end" yaml:"end"`
Step int `json:"step" yaml:"step"`
}Start[0] - 生成の開始点(含む)
End[0] - 生成の終了点(任意の言語の range と同様に最終結果から除外)
Step[1] - シーケンスの間隔
例
{
"start": 0,
"end": 2
// Generate [0, 1]
}FileConnectorConfig
指定されたファイルからデータを取得するコネクタタイプ
type FileConnectorConfig struct {
Path string `yaml:"path" json:"path"`
UseFormatting bool `yaml:"use_formatting" json:"use_formatting"`
}StaticConnectorConfig
指定された文字列からデータを取得するコネクタタイプ
type StaticConnectorConfig struct {
Value string `json:"value" yaml:"value"`
Raw json.RawMessage `json:"raw" yaml:"raw"`
}例:
https://github.com/PxyUp/fitter/blob/master/examples/cli/config_static_connector.json#L5
{
"value": "[1,2,3,4,5]"
}ServerConnectorConfig
golang の http.Client(curl のようなサーバーサイドリクエスト)を使用してデータを取得するコネクタタイプ
type ServerConnectorConfig struct {
Method string `json:"method" yaml:"method"`
Headers map[string]string `yaml:"headers" json:"headers"`
Timeout uint32 `yaml:"timeout" json:"timeout"`
JsonRawBody json.RawMessage `json:"json_raw_body" yaml:"json_raw_body"`
Body string `yaml:"body" json:"body"`
ErrorOnStatus bool `json:"error_on_status" yaml:"error_on_status"`
Proxy *ProxyConfig `yaml:"proxy" json:"proxy"`
OAuth2 *OAuth2Config `yaml:"oauth2" json:"oauth2"`
}Method - すべての HTTP メソッドをサポート: GET、POST、PUT、DELETE、PATCH、OPTIONS、HEAD
Headers - リクエスト中に使用する事前定義ヘッダー。キー/値に注入可能
Timeout[sec] - デフォルトは 60 秒のタイムアウト、または指定された値を使用
Body - リクエストのボディ。解析された値は注入可能
JsonRawBody - json 形式のリクエストボディ。値は注入可能
ErrorOnStatus - オプション、デフォルトは
false。trueの場合、HTTP レスポンスステータス>= 400はエラーボディの解析ではなくフェッチエラー(attempts/null_on_errorを通過)として扱われるため、フェッチの失敗と本当に空の結果を区別できます。falseのままにすると、返ってきたボディを解析する元の動作が維持されます。Proxy - リクエストのプロキシを設定 設定
OAuth2 - アクセストークンを自動的に取得/更新し、
Authorizationヘッダーとして送信します 設定
リクエストはデフォルトで識別可能な
User-Agent(fitter (+https://github.com/PxyUp/fitter))を送信します。上書きするにはHeadersで独自のUser-Agentを設定してください。
例:
{
"method": "GET",
"proxy": {
"server": "http://localhost:8080",
"username": "pyx"
}
}OAuth2 設定
リクエストの前にアクセストークンを自動的に取得し、Authorization ヘッダーとして注入します(headers で設定されたものを上書き)。トークンはメモリにキャッシュされ、有効期限前に更新されます。401 レスポンスが返された場合、キャッシュされたトークンは破棄され、新しいトークンでリクエストが 1 回再試行されます。
type OAuth2Config struct {
TokenUrl string `json:"token_url" yaml:"token_url"`
GrantType OAuth2GrantType `json:"grant_type" yaml:"grant_type"`
ClientId string `json:"client_id" yaml:"client_id"`
ClientSecret string `json:"client_secret" yaml:"client_secret"`
Scopes []string `json:"scopes" yaml:"scopes"`
RefreshToken string `json:"refresh_token" yaml:"refresh_token"`
EndpointParams map[string]string `json:"endpoint_params" yaml:"endpoint_params"`
AuthStyle string `json:"auth_style" yaml:"auth_style"`
TokenFile string `json:"token_file" yaml:"token_file"`
}TokenUrl - トークンエンドポイントの URL。フォーマット もサポート
GrantType - enum["client_credentials", "refresh_token"]、デフォルトは "client_credentials"。ユーザーが一度同意した API(Google、Microsoft など)で長期有効なリフレッシュトークンを保持している場合は "refresh_token" を使用します
ClientId/ClientSecret - クライアント認証情報。フォーマット もサポート。例:
{{{FromEnv=CLIENT_SECRET}}}Scopes - 要求するスコープ
RefreshToken - "refresh_token" グラントに必要。フォーマット もサポート
EndpointParams - 追加のトークンエンドポイントパラメータ(例: Auth0 の
audience)。"client_credentials" グラントのみAuthStyle - enum["", "header", "params"] - クライアント認証情報をトークンエンドポイントに渡す方法: basic auth ヘッダーまたはリクエストボディ。空の場合は自動検出
TokenFile - 実行間でトークンを永続化するためのオプションのパス(
~/をサポート)。保存されたトークンは RefreshToken より優先され、ローテーションされたリフレッシュトークンが書き戻されます。単回使用のリフレッシュトークンを提供するプロバイダー(GitHub Apps など)に必要です。fitter_cli auth で作成します
例:
{
"method": "GET",
"oauth2": {
"token_url": "https://oauth2.googleapis.com/token",
"grant_type": "refresh_token",
"client_id": "{{{FromEnv=GOOGLE_CLIENT_ID}}}",
"client_secret": "{{{FromEnv=GOOGLE_CLIENT_SECRET}}}",
"refresh_token": "{{{FromEnv=GOOGLE_REFRESH_TOKEN}}}"
}
}プロキシ設定
type ProxyConfig struct {
// Proxy to be used for all requests. HTTP and SOCKS proxies are supported, for example
// `http://myproxy.com:3128` or `socks5://myproxy.com:3128`. Short form `myproxy.com:3128`
// is considered an HTTP proxy.
Server string `json:"server" yaml:"server"`
// Optional username to use if HTTP proxy requires authentication.
Username string `json:"username" yaml:"username"`
// Optional password to use if HTTP proxy requires authentication.
Password string `json:"password" yaml:"password"`
}Server - プロキシサーバーのスキーマ付きアドレス。フォーマット もサポート
Username - プロキシのユーザー名(空にできます)。フォーマット もサポート
Password - プロキシのパスワード(空にできます)。フォーマット もサポート
{
"server": "http://localhost:8080",
"username": "pyx"
}環境変数
FITTER_HTTP_WORKER - int[1000] - デフォルトの同時 HTTP ワーカー数
BrowserConnectorConfig
ブラウザを介したデータ取得をエミュレートするコネクタタイプ
type BrowserConnectorConfig struct {
Chromium *ChromiumConfig `json:"chromium" yaml:"chromium"`
Docker *DockerConfig `json:"docker" yaml:"docker"`
Playwright *PlaywrightConfig `json:"playwright" yaml:"playwright"`
}設定は次のいずれかになります:
Chromium - ローカルにインストールされた Chromium を使用してデータを取得
Docker - データ取得用のコンテナを起動するサービスとして docker を使用
Playwright - データ取得に playwright フレームワークを使用
例:
{
"docker": {
"wait": 10000,
"image": "docker.io/zenika/alpine-chrome:with-node",
"entry_point": "chromium-browser",
"purge": true
}
}Chromium
ローカルにインストールされた Chromium を使用してデータを取得します
type ChromiumConfig struct {
Path string `yaml:"path" json:"path"`
Timeout uint32 `yaml:"timeout" json:"timeout"`
Wait uint32 `yaml:"wait" json:"wait"`
Flags []string `yaml:"flags" json:"flags"`
}Path - Chromium バイナリへのパス
Timeout[sec] - chromium の実行タイムアウト
Wait[msec] - ページ読み込みのタイムアウト
Flags - Chromium のフラグ。デフォルト: "--headless", "--proxy-auto-detect", "--temp-profile", "--incognito", "--disable-logging", "--disable-extensions", "--no-sandbox"
例:
{
"path": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"wait": 10000
}Docker
データ取得用のコンテナを起動するために Docker を使用します
type DockerConfig struct {
Image string `yaml:"image" json:"image"`
EntryPoint string `json:"entry_point" yaml:"entry_point"`
Timeout uint32 `yaml:"timeout" json:"timeout"`
Wait uint32 `yaml:"wait" json:"wait"`
Flags []string `yaml:"flags" json:"flags"`
Purge bool `json:"purge" yaml:"purge"`
NoPull bool `yaml:"no_pull" json:"no_pull"`
PullTimeout uint32 `yaml:"pull_timeout" json:"pull_timeout"`
}Docker デフォルトイメージ: docker.io/zenika/alpine-chrome
Image - docker レジストリのイメージ(レジストリホスト付きで指定)
EntryPoint - コンテナ内で実行されるコマンド
Timeout[sec] - コンテナ実行のタイムアウト(イメージのプルは含まない)
Wait[msec] - ページ読み込みのタイムアウト(Chromium ベースのコンテナのみで機能)
Flags - コンテナ実行のコマンド引数。Chromium ベースのデフォルト: "--no-sandbox","--headless", "--proxy-auto-detect", "--temp-profile", "--incognito", "--disable-logging", "--disable-gpu"
Purge - 作業完了後にコンテナを削除するかどうか(docker rm と同様)
NoPull - イメージのプルを防止
PullTimeout - コンテナのプルのタイムアウトを定義
環境変数
DOCKER_HOST - string - (EnvOverrideHost) docker サーバーの URL を設定します。
DOCKER_API_VERSION - string - (EnvOverrideAPIVersion) 使用する API のバージョンを設定します。最新の場合は空のままにします。
DOCKER_CERT_PATH - string - (EnvOverrideCertPath) TLS 証明書(ca.pem、cert.pem、key.pem)を読み込むディレクトリを指定します。
DOCKER_TLS_VERIFY - bool - (EnvTLSVerify) TLS 検証を有効または無効にします(デフォルトはオフ)
例:
{
"wait": 10000,
"image": "docker.io/zenika/alpine-chrome:with-node",
"entry_point": "chromium-browser",
"purge": true
}Playwright
playwright フレームワークを介してブラウザを実行します
type PlaywrightConfig struct {
Browser PlaywrightBrowser `json:"browser" yaml:"browser"`
Install bool `yaml:"install" json:"install"`
Timeout uint32 `yaml:"timeout" json:"timeout"`
Wait uint32 `yaml:"wait" json:"wait"`
TypeOfWait *playwright.WaitUntilState `json:"type_of_wait" yaml:"type_of_wait"`
PreRunScript string `json:"pre_run_script" yaml:"pre_run_script"`
PostRunScript string `json:"post_run_script" yaml:"post_run_script"`
Stealth bool `json:"stealth" yaml:"stealth"`
StorageStateFile string `json:"storage_state_file" yaml:"storage_state_file"`
IndexedDB bool `json:"indexed_db" yaml:"indexed_db"`
Proxy *ProxyConfig `yaml:"proxy" json:"proxy"`
}Browser - enum["Chromium", "FireFox", "WebKit"] - 使用するブラウザ
Install - ブラウザをインストールするかどうか(初回使用時に組み込みの
playwright-goバージョンに一致するドライバーとブラウザをダウンロードします。これらがプリインストールされているghcr.io/pxyup/fitter-mcp:playwrightイメージでは不要)Timeout[sec] - playwright を実行するタイムアウト
Wait[sec] - ページ読み込みのタイムアウト
TypeOfWait - enum["load", "domcontentloaded", "networkidle", "commit"] 待機するページの状態。デフォルトは "load"
PreRunScript[""] - AddInitScript を介して注入され、ページスクリプトが実行される前に実行されるスクリプト(ドキュメント作成時、ナビゲーション完了前)。環境のパッチ適用(navigator のオーバーライド、API スタブ)に役立ちます。読み込まれた DOM にはアクセスできません。プレースホルダー {PL} もサポート
PostRunScript[""] - ページ読み込み後、ページコンテンツの読み取り前に実行されるスクリプト。DOM 操作(クリック、スクロール)に役立ちます。プレースホルダー {PL} もサポート
Stealth[false] - ボット防御を通過するためのスクリプトを追加
StorageStateFile[""] - playwright のストレージ状態 json(cookie + localStorage)へのパス(
~/をサポート)。ナビゲーション前にブラウザコンテキストに読み込まれ、毎回の実行後に書き戻されるため、更新されたセッションが維持されます。ヘッドレス実行で実際のログインを再利用できます。fitter_cli browser-login でファイルを一度作成します。ログインとスクレイピングには同じbrowserを使用してください。サイトがセッションをブラウザのフィンガープリントにバインドする場合があります。フォーマット もサポートIndexedDB[false] - 永続化されたストレージ状態に IndexedDB を含めます(一部の SPA、例: Firebase Auth はトークンをそこに保持します)
Proxy - リクエストのプロキシを設定 設定
例
{
"timeout": 30,
"wait": 30,
"install": false,
"browser": "Chromium"
}Related MCP server: MCP Server Fetch Python
Model
モデルを使用してスクレイピングの結果を定義します
type Model struct {
ObjectConfig *ObjectConfig `yaml:"object_config" json:"object_config"`
ArrayConfig *ArrayConfig `json:"array_config" yaml:"array_config"`
BaseField *BaseField `json:"base_field" yaml:"base_field"`
IsArray bool `json:"is_array" yaml:"is_array"`
}設定は次のいずれかになります:
ObjectConfig - オブジェクト形式の設定
ArrayConfig - 配列形式の設定
BaseField - 単一/生成フィールドの設定
IsArray - bool[false] - フィールドが配列であることを強制指定します(model field と base field の組み合わせで使用可能)
例:
{
"object_config": {}
}ObjectConfig
オブジェクトとフィールドの設定
type ObjectConfig struct {
Fields map[string]*Field `json:"fields" yaml:"fields"`
Field *BaseField `json:"field" yaml:"field"`
ArrayConfig *ArrayConfig `json:"array_config" yaml:"array_config"`
Condition string `json:"condition" yaml:"condition"`
}Condition - オプションの条件式。解決前にソースノードに対して評価されます。false の場合、オブジェクト全体が親から省略されます(フィールドは一切解決されません)
設定は次のいずれかになります:
Fields - 各フィールド定義のマップ。キー - フィールド名、値 - 設定
Field - 配列の要素に使用。 "string"、"int" などの基本型としてデシリアライズされるフィールド(基本型の配列の場合に使用)
ArrayConfig - 配列の要素に使用。配列の配列のデシリアライズ
例:
{
"fields": {
"title": {
"base_field": {
"type": "string",
"path": "type"
}
}
}
}ArrayConfig
配列とフィールドの設定
type ArrayConfig struct {
RootPath string `json:"root_path" yaml:"root_path"`
Reverse bool `yaml:"reverse" json:"reverse"`
ItemConfig *ObjectConfig `json:"item_config" yaml:"item_config"`
LengthLimit uint32 `json:"length_limit" yaml:"length_limit"`
Condition string `json:"condition" yaml:"condition"`
ItemCondition string `json:"item_condition" yaml:"item_condition"`
StaticConfig *StaticArrayConfig `json:"static_array" yaml:"static_array"`
}RootPath - html 解析の場合に配列のルート要素または繰り返し要素を見つけるためのセレクター。配列のサイズはルートの下の子要素の数になります
Reverse - bool[false] - 逆順の反復(n から 1)を使用する必要があることを示します
LengthLimit - 配列の固定サイズ(生成された配列のみ。静的には使用不可)。注: ソースの要素が制限より少ない場合、宣言されたサイズを維持するために配列は末尾に
nullでパディングされます(これは意図的です)— 代わりにソースの正確な長さを得るにはlength_limitを省略してくださいCondition - オプションの条件式。解決前にソースノードに対して評価されます。false の場合、配列全体が親から省略されます
ItemCondition - オプションの条件式。すべての構築済みアイテムに対して評価されます(fRes - アイテム値、fSrc - ソース要素、fIndex - アイテムインデックス)。false に解決されるアイテムは配列から削除されます - 宣言的フィルタリング。static_array には適用されません
設定は次のいずれかになります:
ItemConfig - 配列の各要素の設定
StaticConfig - 静的配列の設定
例:
{
"root_path": "#content dt.quote > a",
"item_config": {
"field": {
"type": "string"
}
}
}Field
フィールドの共通部分
type Field struct {
BaseField *BaseField `json:"base_field" yaml:"base_field"`
ObjectConfig *ObjectConfig `json:"object_config" yaml:"object_config"`
ArrayConfig *ArrayConfig `json:"array_config" yaml:"array_config"`
FirstOf []*Field `json:"first_of" yaml:"first_of"`
}設定は以下のいずれかになります:
BaseField - "string"、"int" などの基本型のようにデシリアライズされるフィールド
ObjectConfig - フィールドがネストされたオブジェクト内にある場合
ArrayConfig - フィールドが配列内にある場合
FirstOf - 最初に空でない解決済みフィールドが選択されます
例:
{
"base_field": {
"type": "string",
"path": "div.current-temp span.heading"
}
}BaseField
静的な情報を取得したり、新しい情報を生成したい場合
type BaseField struct {
Type FieldType `yaml:"type" json:"type"`
Path string `yaml:"path" json:"path"`
HTMLAttribute string `json:"html_attribute" yaml:"html_attribute"`
Condition string `json:"condition" yaml:"condition"`
Generated *GeneratedFieldConfig `yaml:"generated" json:"generated"`
FirstOf []*BaseField `json:"first_of" yaml:"first_of"`
}FieldType - enum["null", "boolean", "string", "int", "int64", "float", "float64", "array", "object", "html", "raw_string"] - パース用の静的フィールド。重要: html 型は HTML を返すコネクタでのみ動作します(この場合 HTMLAttribute は効果がありません)。例
Path - パース用のセレクタ(配列の子の場合は相対指定)
HTMLAttribute - goquery による HTML パースでのみ効果がある追加値。ここでパースする属性を指定できます。
Condition - 任意の condition 式。抽出された値(fRes/fResJson/fResRaw、fIndex; fSrc - フィールドが解決されたノード(兄弟要素を含む))に対して評価されます。false の場合、フィールドは null を生成する代わりに親オブジェクト/配列から省略されます。Generated の前に評価されるため、条件が false の場合、生成処理(サブリクエスト、ファイルダウンロード)もスキップされます。
重要: デフォルトでは "string" 型はトリムされ、すべての特殊文字が置換されます。プレーンな文字列が必要な場合は "raw_string" を使用してください。
設定は以下のいずれか、または空にできます:
例
{
"generated": {
"uuid": {}
}
}{
"type": "string",
"path": "text()"
}条件付きフィールド
すべてのフィールドは condition を持つことができます - expr-lang 式(定義済み値)。true 以外の値に評価された場合、フィールドは出力から省略されます(キー/アイテムが消えます)。null には設定されません。無効な式もフィールドを省略し、エラーをログに記録します。
条件が評価される場所:
BaseField.
condition- 抽出後:fResは抽出された値、fSrcはフィールドが解決されたノード(その兄弟要素を含む)です。つまりfSrc.on_sale == trueで、抽出していないデータに基づいてフィールドを制御できます。条件が false の場合、generated 処理は完全にスキップされます(サブリクエストなし、ファイルダウンロードなし)ObjectConfig.
condition/ ArrayConfig.condition- 解決前:fRes/fSrcはソースノードです(json の場合はパースされた値、html の場合はテキストコンテンツ)ArrayConfig.
item_condition- 構築された各アイテムに対して:fResはアイテム、fSrcはそれが構築されたソース要素、fIndexはそのインデックスです。false のアイテムは削除されます - 宣言的な配列フィルタリングです。fSrcを使用して、出力に追加せずにソース属性でフィルタリングできます。
配列アイテムのフィルタリング - fSrc.in_stock はソース要素を読み取り(出力には抽出されません)、fRes.price は構築されたアイテムを読み取ります:
{
"array_config": {
"root_path": "products",
"item_condition": "fSrc.in_stock && fRes.price > 0",
"item_config": {
"fields": {
"title": { "base_field": { "type": "string", "path": "title" } },
"price": { "base_field": { "type": "float", "path": "price" } }
}
}
}
}値がチェックに合格しない限りキーを省略:
{
"discount": {
"base_field": {
"type": "float",
"path": "discount_pct",
"condition": "fRes > 0"
}
}
}特殊なケース:
静的配列内では、省略されたアイテムは
nullのままです(位置は定義上固定されており、インデックスは決してシフトしません)ルートモデル設定が省略された場合、パース結果は
nullになります
実行可能な例: examples/config_conditions.json
GeneratedFieldConfig
フィールドをその場で生成する機能を提供します
type GeneratedFieldConfig struct {
UUID *UUIDGeneratedFieldConfig `yaml:"uuid" json:"uuid"`
Static *StaticGeneratedFieldConfig `yaml:"static" json:"static"`
Formatted *FormattedFieldConfig `json:"formatted" yaml:"formatted"`
Plugin *PluginFieldConfig `yaml:"plugin" json:"plugin"`
Calculated *CalculatedConfig `yaml:"calculated" json:"calculated"`
File *FileFieldConfig `yaml:"file" json:"file"`
Model *ModelField `yaml:"model" json:"model"`
FileStorageField *FileStorageField `json:"file_storage" yaml:"file_storage"`
}設定は以下のいずれかになります:
UUID - ランダムな UUID V4 を生成
Static - 静的フィールドを生成
Formatted - フィールドをフォーマット
Model - 他のコネクタとモデルから生成されたモデル
Plugin - プラグインフィールド
Calculated - 計算フィールド
File - ファイルフィールド(サーバーからファイルをダウンロードするため)
FileStorage - ローカルファイルに保存できるファイルフィールド
例:
{
"uuid": {}
}https://github.com/PxyUp/fitter/blob/master/examples/cli/config_cli.json#L58
{
"model": {
"type": "array",
"model": {
"array_config": {
"root_path": "#content dt.quote > a",
"item_config": {
"field": {
"type": "string"
}
}
}
},
"connector_config": {
"response_type": "HTML",
"url": "http://www.quotationspage.com/random.php",
"attempts": 3,
"browser_config": {
"chromium": {
"path": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"wait": 10000
}
}
}
}
}UUID
その場でランダムな UUID V4 を生成します。一意の ID を生成するために使用できます。
type UUIDGeneratedFieldConfig struct {
Regexp string `yaml:"regexp" json:"regexp"`
}Regexp - 生成された UUID の一部を取得するために使用できるマッチャーを提供します
Static
静的フィールドを生成します
type StaticGeneratedFieldConfig struct {
Type FieldType `yaml:"type" json:"type"`
Value string `json:"value" yaml:"value"`
Raw json.RawMessage `json:"raw" yaml:"raw"`
}Type - enum["null", "boolean", "string", "int","int64","float","float64", "array", "object"] - フィールドの型
Value - フィールドの文字列値
Raw - フィールドの純粋な json 値
例
{
"type": "int",
"value": "65"
}{
"type": "array",
"value": "[65,45]"
}{
"type": "array",
"raw": [65,45]
}Formatted Field Config
親の base field から値を渡すフォーマット済みフィールドを生成します
type FormattedFieldConfig struct {
Template string `yaml:"template" json:"template"`
}例: https://github.com/PxyUp/fitter/blob/master/examples/cli/config_cli.json#L98
{
"template": "https://news.ycombinator.com/item?id={PL}"
}File Storage Field
フィールドの結果をローカルファイルとして保存するために使用できるフィールド
type FileStorageField struct {
Content string `json:"content" yaml:"content"`
Raw json.RawMessage `yaml:"raw" yaml:"raw"`
FileName string `json:"file_name" yaml:"file_name"`
Path string `json:"path" yaml:"path"`
Append bool `json:"append" yaml:"append"`
}Content - コンテンツ用のテンプレート文字列。重要: 親の値を文字列として注入できます
Raw - フィールドの生の json コンテンツ。重要: 親の値を文字列として注入できます
FileName - ファイルを保存するためのローカルファイル名。デフォルトでは、ヘッダーから FileName を取得しようとし、その後 URL から取得します。重要: 親の値を文字列として注入できます。
Path - ファイルを保存するためのローカルファイルの親ディレクトリ。デフォルトのパスはプロセスディレクトリです。重要: 親の値を文字列として注入できます
Append[false] - ファイルに追記するかどうか
{
"content": "{{{id}}}, {{{message}}}\n",
"append": true,
"file_name": "{{{id}}}.csv",
"path": "/Users/pxyup/fitter/examples/cli/test/csv"
}File Field
サーバーからファイルをローカルにダウンロードするために使用できるフィールド
type FileFieldConfig struct {
Config *ServerConnectorConfig `yaml:"config" json:"config"`
Url string `yaml:"url" json:"url"`
FileName string `json:"file_name" yaml:"file_name"`
Path string `json:"path" yaml:"path"`
}Config - ServerConfig はデフォルトの fitter http.Client を使用してリクエストを送信します
Url - 画像の URL。重要: コネクタ内の URL は 親の値を文字列として注入できます
FileName - ファイルを保存するためのローカルファイル名。デフォルトでは、ヘッダーから FileName を取得しようとし、その後 URL から取得します。重要: 親の値を文字列として注入できます。
Path - ファイルを保存するためのローカルファイルの親ディレクトリ。デフォルトのパスはプロセスディレクトリです。重要: 親の値を文字列として注入できます
フィールドの結果は、ローカルファイルパスが文字列として返されます
{
"url": "https://images.shcdn.de/resized/w680/p/dekostoff-gobelinstoff-panel-oriental-cat-46-x-46_P19-KP_2.jpg",
"path": "/Users/pxyup/fitter/bin",
"config": {
"method": "GET"
}
}伝播された URL を使用(親の値を文字列として注入)
{
"url": "https://picsum.photos{PL}",
"path": "/Users/pxyup/fitter/bin",
"config": {
"method": "GET"
}
}設定例:
https://github.com/PxyUp/fitter/blob/master/examples/cli/config_image.json
https://github.com/PxyUp/fitter/blob/master/examples/cli/config_image_multiple.json
Calculated field
式に応じて異なる型を生成できるフィールド
type CalculatedConfig struct {
Type FieldType `yaml:"type" json:"type"`
Expression string `yaml:"expression" json:"expression"`
}Type - 式の結果の型
Expression - 計算用の式(計算式には このライブラリ を使用します)
定義済み値
FNull - builder.Nullvalue のエイリアス
FNil - nil のエイリアス
isNull(value T) - 値が FNull かどうかをチェックする関数
fRes - base field のパース結果の生の(適切な型の)値
fIndex - 親配列内のインデックス(親が配列フィールドの場合のみ)
fResJson - 生の結果の JSON 文字列表現
fResRaw - バイト形式の結果
fSrc - condition/item_condition 式でのみ使用可能: 値が解決されたソースノード(json の場合はパースされた値(兄弟要素を含む)、html の場合はテキストコンテンツ)。calculated/formatted/notifier 式では使用できません
FNewLine - 改行区切り文字
{
"type": "bool",
"expression": "fRes > 500"
}Plugin field
fitter 用の外部プラグインにできるフィールド
type PluginFieldConfig struct {
Name string `json:"name" yaml:"name"`
Config json.RawMessage `json:"config" yaml:"config"`
}Name - プラグインの名前(拡張子なしの名前のみ)
Config - プラグインの json 設定
Model Field
新しい model と connector によってその場で生成できるフィールド型
type ModelField struct {
// Type of parsing
ConnectorConfig *ConnectorConfig `yaml:"connector_config" json:"connector_config"`
// Model of the response
Model *Model `yaml:"model" json:"model"`
Type FieldType `yaml:"type" json:"type"`
Path string `yaml:"path" json:"path"`
Expression string `yaml:"expression" json:"expression"`
}ConnectorConfig - 使用するコネクタ。重要: コネクタ内の URL は 親の値を文字列として注入できます
Model - 内部モデルの設定
Type - enum["null", "boolean", "string", "int", "int64", "float", "float64", "array", "object"] - 生成されたフィールドの型
Path - 生成されたフィールドから情報を抽出できない場合に、json セレクタを使用して抽出できます
Expression - Model の後処理に使用できる文字列(path フィールドは無視されます)
例:
https://github.com/PxyUp/fitter/blob/master/examples/cli/config_cli.json#L60
{
"type": "array",
"model": {
"array_config": {
"root_path": "#content dt.quote > a",
"item_config": {
"field": {
"type": "string"
}
}
}
}
}https://github.com/PxyUp/fitter/blob/master/examples/cli/config_weather.json#L37
{
"type": "string",
"path": "temp.temp",
"model": {
"object_config": {
"fields": {
"temp": {
"base_field": {
"type": "string",
"path": "//div[@id='forecast_list_ul']//td/b/a/@href",
"generated": {
"model": {
"type": "string",
"model": {
"object_config": {
"fields": {
"temp": {
"base_field": {
"type": "string",
"path": "div.current-temp span.heading"
}
}
}
}
},
"connector_config": {
"response_type": "HTML",
"attempts": 4,
"url": "https://openweathermap.org{PL}",
"browser_config": {
"playwright": {
"timeout": 30,
"wait": 30,
"install": false,
"browser": "FireFox",
"type_of_wait": "networkidle"
}
}
}
}
}
}
}
}
}
},
"connector_config": {
"response_type": "xpath",
"attempts": 3,
"url": "https://openweathermap.org/find?q={PL}",
"browser_config": {
"playwright": {
"timeout": 30,
"wait": 30,
"install": false,
"browser": "Chromium"
}
}
}
}Static Array Config
静的(固定長)配列の生成を提供します
type StaticArrayConfig struct {
Items map[uint32]*Field `yaml:"items" json:"items"`
Length uint32 `yaml:"length" json:"length"`
}例:
{
"0": {
"base_field": {
"type": "string",
"path": "div.current-temp span.heading"
}
}
}{
"length": 4,
"0": {
"base_field": {
"type": "string",
"path": "div.current-temp span.heading"
}
}
}{
"length": 4,
"2": {
"base_field": {
"type": "string",
"path": "div.current-temp span.heading"
}
}
}プレースホルダーリスト
{PL} - 値の注入用
{INDEX} - 親配列内のインデックスの注入用
{HUMAN_INDEX} - 親配列内のインデックスを人間向けの方法で注入するため
{{{json_path}}} - 伝播された "object"/"array" フィールドから情報を取得します
{{{RefName=SomeName json.path}}} - 名前で reference 値を取得し、json パスで値を抽出します。例
{{{FromEnv=ENV_KEY}}} - 環境変数から値を取得します
{{{FromInput=.}}} または {{{FromInput=json.path}}} - トリガーまたはライブラリの入力から値を取得します
{{{FromFile=./test_file.log}}} - パスでファイルから値を取得します。ファイルのコンテンツにもプレースホルダーを含めることができます
{{{FromURL=http://localhost:8081}}} - URL からレスポンスを取得します
例:
{{{FromExp="{{{FromEnv=TEST_VAL}}}" + "hello"}}}Current time is: {PL} with token from TokenRef={{{RefName=TokenRef}}} and TokenObjectRef={{{RefName=TokenObjectRef token}}}Current time is: {PL} with token from TokenRef={{{RefName=TokenRef}}} and TokenObjectRef={{{RefName=TokenObjectRef token}}}TokenRef={{{RefName=TokenRef}}} and TokenObjectRef={{{RefName=TokenObjectRef token}}} Object={{{value}}} {PL} Env={{{FromEnv=TEST_VAL}}} {INDEX} {HUMAN_INDEX}References
事前取得される(処理前に)特別なマップで、connector または placeholder に使用できます。
以下の用途に使用できます:
jwt トークンをキャッシュしてヘッダーで使用
値のキャッシュ
など
Reference
type Reference struct {
*ModelField
Expire *uint32 `yaml:"expire" json:"expire"`
}ModelField - 埋め込み構造体です。同じフィールドを使用できます
Expire[sec] - 取得後に参照が期限切れになる期間。未設定 => 永久にキャッシュ。0 に設定 => 毎回再取得。n > 0 に設定 => n 秒間キャッシュ
Fitter の場合
type RefMap map[string]*Reference
type Config struct {
// Other Config Fields
Limits *Limits `yaml:"limits" json:"limits"`
References RefMap `json:"references" yaml:"references"`
}Fitter Cli の場合
type RefMap map[string]*Reference
type CliItem struct {
// Other Config Fields
Limits *Limits `yaml:"limits" json:"limits"`
References RefMap `json:"references" yaml:"references"`
}References - map[string]*Reference - キーが ReferenceName であるオブジェクト(connector または placeholder に使用できます)、値は Reference
例
https://github.com/PxyUp/fitter/blob/master/examples/cli/config_ref.json#L2
{
"references": {
"TokenRef": {
"expire": 10,
"connector_config": {
"response_type": "json",
"static_config": {
"value": "\"plain token\""
}
},
"model": {
"base_field": {
"type": "string"
}
}
},
"TokenObjectRef": {
"connector_config": {
"response_type": "json",
"static_config": {
"value": "{\"token\":\"token from object\"}"
}
},
"model": {
"object_config": {
"fields": {
"token": {
"base_field": {
"type": "string",
"path": "token"
}
}
}
}
}
}
}
}Notifiers
任意のアイテムごとの設定 item.notifier_config。処理後にパース結果をどこかにプッシュします。結果は通常どおり返されます(CLI/MCP 出力、サービスログ)。notifier は追加で配信します。Fitter(サービスモード)、Fitter_CLI、Fitter_MCP で動作します。
type NotifierConfig struct {
Expression string `yaml:"expression" json:"expression"`
Force bool `json:"force" yaml:"force"`
SendArrayByItem bool `yaml:"send_array_by_item" json:"send_array_by_item"`
Template string `yaml:"template" json:"template"`
// exactly ONE destination:
Console *ConsoleConfig `yaml:"console" json:"console"`
TelegramBot *TelegramBotConfig `yaml:"telegram_bot" json:"telegram_bot"`
Http *HttpConfig `yaml:"http" json:"http"`
Redis *RedisNotifierConfig `json:"redis" yaml:"redis"`
File *FileStorageField `json:"file" yaml:"file"`
}Expression - オプションの expr-lang 条件: それが true と評価された場合のみ通知します。解析結果は
fRes(解析値)、fResRaw(生バイト)、fResJson(JSON文字列) として利用できます。例:len(fResRaw) > 0Force - 解析がエラーで終了した場合でも通知します
SendArrayByItem - 結果が配列の場合、各要素を個別の通知として送信します
Template - 送信前に結果に適用されるオプションのテンプレート。placeholders を使用できます
Destination -
console,telegram_bot,http,redis,fileのいずれか1つ
宛先設定:
type HttpConfig struct {
Url string `yaml:"url" json:"url"`
Method string `json:"method" yaml:"method"`
Headers map[string]string `yaml:"headers" json:"headers"`
Timeout uint32 `yaml:"timeout" json:"timeout"`
}
type TelegramBotConfig struct {
Token string `json:"token" yaml:"token"`
UsersId []int64 `json:"users_id" yaml:"users_id"`
Pretty bool `json:"pretty" yaml:"pretty"`
OnlyMsg bool `json:"only_msg" yaml:"only_msg"`
}
type RedisNotifierConfig struct {
Addr string `json:"addr" yaml:"addr"`
Password string `json:"password" yaml:"password"`
DB int `json:"db" yaml:"db"`
Channel string `json:"channel" yaml:"channel"`
}
type ConsoleConfig struct {
OnlyResult bool `json:"only_result" yaml:"only_result"`
}file 宛先は、ファイルフィールドタイプと同じ FileStorageField を使用します。
例 (examples/config_telegram.json):
{
"item": {
"connector_config": { "...": "..." },
"model": { "...": "..." },
"notifier_config": {
"expression": "len(fResRaw) > 0",
"telegram_bot": {
"token": "{{{FromEnv=TG_TOKEN}}}",
"users_id": [123456],
"pretty": true
}
}
}
}制限
DDOS攻撃やメモリの大量使用を防ぐための制限を提供します。
type Limits struct {
HostRequestLimiter HostRequestLimiter `yaml:"host_request_limiter" json:"host_request_limiter"`
ChromiumInstance uint32 `yaml:"chromium_instance" json:"chromium_instance"`
DockerContainers uint32 `yaml:"docker_containers" json:"docker_containers"`
PlaywrightInstance uint32 `yaml:"playwright_instance" json:"playwright_instance"`
}HostRequestLimiter - map[string]int64 - ホスト名ごとの制限。キーはホスト、値は並列リクエスト数(server connector で使用)
ChromiumInstance - 並列 chromium インスタンスの数
DockerContainers - 並列 docker インスタンスの数
PlaywrightInstance - 並列 playwright インスタンスの数
https://github.com/PxyUp/fitter/blob/master/examples/cli/config_cli.json#L2
{
"limits": {
"host_request_limiter": {
"hacker-news.firebaseio.com": 5
},
"chromium_instance": 3,
"docker_containers": 3,
"playwright_instance": 3
}
}Available Tools
6 toolsfitter_config_referenceA
Return a condensed reference of the Fitter config format (connectors, parsers, model/field schema, placeholders, notifiers, references, limits) with working examples. Use it before authoring a config for fitter_run.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries burden. Describes output but does not explicitly state that tool is read-only or has no side effects, though context implies safe operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose, no fluff. Every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters or output schema, description sufficiently covers purpose and usage. Could mention response format but not critical for a reference tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters, schema coverage is 100% trivially. Baseline 4 applies, and description adds value by listing what the reference includes.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns a condensed reference of the Fitter config format with working examples, and distinguishes itself from sibling run tools by advising use before authoring a config for fitter_run.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly recommends using before authoring a config for fitter_run, providing clear context. However, it does not mention exclusions or alternatives, but siblings are run tools making differentiation obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitter_inspect_urlA
Fetch a URL and return a compact structure outline plus candidate selectors/paths, so you can author a fitter config that matches on the first try instead of guessing selectors and getting nulls. For JSON it lists gjson paths with types and sample values; for HTML it lists repeated elements (candidate array_config root_path / list rows) and link/heading selectors. For client-rendered SPAs (content built by JavaScript), a plain fetch sees only an empty shell — the output warns when it detects one; pass render:true to render it in a headless browser first (mirrors what a browser_config scrape would see). Read-only helper that does NOT extract data — use it before fitter_run, then fitter_run to actually extract.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | HTTP(S) URL to fetch and inspect for its structure and candidate selectors. | |
| render | No | Render the page in a headless browser (Playwright/Chromium) before inspecting — needed for client-rendered SPAs whose content is built by JavaScript and is absent from the raw HTML. Requires browser support (the fitter-mcp:playwright image or a local Playwright install). | |
| response_type | No | Optional hint for how to read the response: json, HTML, xpath or XML. Empty auto-detects from the Content-Type/body. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It clearly states the tool is read-only and does not extract data, and explains behavior for different content types (JSON, HTML, SPAs) and the render option.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but each sentence adds unique value, covering purpose, output, parameter usage, and distinctions from execution tools. It is front-loaded with the primary purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description describes the output as a 'compact structure outline plus candidate selectors/paths' and gives specifics for JSON and HTML. It also covers the render behavior for SPAs, making the tool's behavior well understood.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description expands on each parameter beyond the schema: url as the target, render for SPAs, and response_type as an optional hint with auto-detection. It explains why the parameters matter and how they affect the output.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Fetch a URL and return a compact structure outline') and differentiates from sibling tools by positioning it as an inspection step before fitter_run. Clearly identifies the tool's role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use it ('before fitter_run') and what it does not do ('does NOT extract data'), plus provides guidance on when to set render:true for SPAs. Also mentions the response_type hint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitter_runA
Run a Fitter scraping/parsing config passed inline (JSON or YAML) and return the extracted data as JSON. Fitter fetches data via a connector (HTTP request, headless browser, static value, file, ...) and extracts structured data using json/HTML/XML/xpath selectors described by a declarative model. Call fitter_config_reference first if you are unsure about the config format.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No | Optional input value (plain string or JSON), available in the config via {{{FromInput=.}}} or {{{FromInput=json.path}}} placeholders. | |
| config | Yes | Fitter CliItem config as a JSON or YAML string. Top-level keys: item (required), limits, references. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose behaviors. It mentions fetching data via connectors and extracting data, implying network access. However, it omits potential side effects like rate limits, authentication needs, or error scenarios, which would strengthen transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief, with a clear structure: first sentence states the tool's purpose, second explains the underlying Fitter mechanism, third gives a usage tip. Every sentence contributes directly to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with two parameters, no output schema, and no annotations, the description provides sufficient context: config format, supported selectors, and a reference to the config spec tool. It could be more complete by noting potential timeouts or result size limitations, but overall it covers the essential information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (both parameters described). The description adds context beyond the schema by explaining that config is JSON/YAML, highlighting top-level keys (item, limits, references), and stating that output is JSON. This adds meaningful value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action ('Run a Fitter scraping/parsing config passed inline') and the resource (inline config). It distinguishes from siblings by specifying 'inline', contrasting with file- and URL-based tools. The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description advises calling fitter_config_reference first if unsure about the config format, providing clear guidance. However, it does not explicitly compare this tool to fitter_run_file or fitter_run_url, leaving the selection of the appropriate sibling somewhat implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitter_run_fileA
Run a Fitter scraping/parsing config from a local JSON or YAML file and return the extracted data as JSON. Same as fitter_run but reads the config from disk.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to a Fitter config file (.json, .yaml or .yml) with top-level keys: item (required), limits, references. | |
| input | No | Optional input value (plain string or JSON), available in the config via {{{FromInput=.}}} or {{{FromInput=json.path}}} placeholders. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description must fully disclose behavioral traits. It states the tool returns extracted data as JSON but does not mention whether modifications occur, required permissions, or error handling (e.g., file not found). The description is minimal and lacks transparency beyond the basic operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with two sentences, front-loading the primary purpose. Every sentence adds value: first defines the tool, second clarifies the difference from a sibling. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 2 parameters and no output schema, the description covers the basic purpose but omits important context like what happens if the file is invalid, permissions needed, or error scenarios. It is adequate for simple use but has gaps compared to a fully transparent description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds minimal additional meaning beyond the schema; it only reiterates that 'input' is optional and used with placeholders, which the schema already covers. No further value is added for the 'path' parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the verb (Run), the resource (Fitter config file), and distinguishes it from fitter_run by specifying 'reads the config from disk.' It also indicates the output format (JSON). This differentiates it from sibling tools like fitter_config_reference, fitter_run, and fitter_run_url.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly notes 'Same as fitter_run but reads the config from disk,' which helps users decide between this tool and fitter_run. However, it does not provide explicit when-not-to-use scenarios or mention other alternatives besides the direct sibling comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitter_run_urlA
Run a Fitter scraping/parsing config downloaded from an HTTP(S) URL (JSON or YAML) and return the extracted data as JSON. Same as fitter_run but fetches the config from a remote location, e.g. a raw GitHub link.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | HTTP(S) URL of a Fitter config (JSON or YAML) with top-level keys: item (required), limits, references. | |
| input | No | Optional input value (plain string or JSON), available in the config via {{{FromInput=.}}} or {{{FromInput=json.path}}} placeholders. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavior. It states the tool downloads config from a URL and returns JSON, but omits important details such as network error handling, timeout limits, authentication, size restrictions, or what happens with invalid configs. This lack of transparency could lead to unexpected failures.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with no unnecessary words. It front-loads the action and result, then adds the key distinction from 'fitter_run'. Every sentence provides useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool involves remote fetching and parsing, but the description does not detail the return format beyond 'extracted data as JSON', nor does it explain error conditions or required permissions. With no output schema, more detail would be beneficial for an agent to anticipate the response structure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers both parameters with descriptions (100% coverage). The description adds value by specifying the required top-level keys of the config ('item', 'limits', 'references'), which aids in understanding the expected structure beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs a Fitter config from an HTTP(S) URL and returns JSON data. It explicitly distinguishes itself from 'fitter_run' by noting the remote fetching behavior, making the purpose specific and differentiated from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description indicates when to use this tool over 'fitter_run' (remote vs local config) and gives an example (raw GitHub link). However, it does not explicitly mention when not to use it or alternatives like 'fitter_run_file', though the context from the name and sibling list provides some guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitter_validate_configA
Validate a Fitter config (JSON or YAML) without executing it. Checks the structural rules: item/connector_config/model presence, valid response_type, that the connector has a data source, and compiles every condition/item_condition expression in the model. Returns "valid" or the validation error. Cheap and safe — use it while iterating on a config before calling fitter_run.
| Name | Required | Description | Default |
|---|---|---|---|
| config | Yes | Fitter CliItem config as a JSON or YAML string to validate without executing it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the burden, detailing what it checks (structural rules, condition compilation), that it is cheap and safe, and that it returns 'valid' or error. This comprehensively discloses behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: purpose, checks, and usage advice. Front-loaded and succinct with no redundancies.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the single parameter and no output schema, the description fully covers purpose, behavior, usage context, and return type. It is complete for effective tool selection.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description reinforces the config parameter but adds no new parameter-level details beyond the schema description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Validate a Fitter config (JSON or YAML) without executing it,' clearly specifying the verb and resource. It distinguishes from sibling tools like fitter_run by advising use before calling fitter_run.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly advises using this tool while iterating on a config before calling fitter_run, providing clear when-to-use context. However, it does not explicitly state when not to use it or mention alternatives for different scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
1 tool update
v1.8.2- Added
fitter_inspect_url
1 tool update
v1.7.0- Added
fitter_validate_config
4 tool updates
v0.1.0- First observed
fitter_config_reference - First observed
fitter_run - First observed
fitter_run_file - First observed
fitter_run_url
TDQS
Each tool serves a distinct purpose: reference, inspection, execution (with three source variants), and validation. No overlap or ambiguity between them.
All tools follow the 'fitter_' prefix with snake_case, and the action part is consistently descriptive (inspect, run, validate). The naming pattern is uniform and predictable.
Six tools is ideal for a config-driven scraping/parsing workflow: reference, inspect, run (three variants), and validate. Not bloated or sparse.
The toolset covers the full lifecycle: learning the format (reference), inspecting target structure (inspect), validating configs (validate), and executing from inline, file, or URL sources. No missing functionality apparent.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for Riveter's enrichment, scraping, and monitoring API
MCP server for web extraction and rendering via AceDataCloud WebExtrator
One MCP server for 180+ live web-data APIs returning clean JSON from sites that block scrapers.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for interacting with Prometheus metrics and data.17MIT
- AlicenseAqualityCmaintenanceAn MCP server for fetching and transforming web content into various formats.48MIT
- FlicenseBqualityDmaintenanceAn MCP Server for Web scraping and Crawling, built using Crawl4AI224-
- AlicenseAqualityCmaintenanceMCP server for web scraping — extract clean markdown, links, and metadata from any URL. Free Firecrawl alternative.51575MIT
Appeared in Searches
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/PxyUp/fitter'
If you have feedback or need assistance with the MCP directory API, please join our Discord server