Skip to main content
Glama
fc0web

benchtop-mcp

by fc0web

benchtop-mcp

シリアル接続された計測装置・回路を、AI エージェント(Claude など)から直接操作・記録・解析するための MCP サーバーです。

実機がなくても動きます。 内蔵の仮想装置(port="mock")があるので、ハードを繋ぐ前に全機能を試せます。

Version: 0.14.0-alpha (2026-09-20) — ★ BREAKING: send_command を MCP tool 面から除去 (STEP 2159、 rei-aios chat-Claude 2026-09-20 arc 経由)。 任意 SCPI 文字列を機器に投げる汎用口が MCP に露出していると、 モデルが SafetyGate (v0.5) や physics-limits (v0.6) を経由せずに 任意コマンドを組み立てられる ため。 実装本体 (Bench.send_command class method) は保持、 新規 CLI subcommand python benchtop_mcp.py send_command <port> <command> [--baudrate N] で 引き続き 呼べる。 MCP tool 数: 34 → 33。 honest scope: 本変更は MCP-only client (Claude Desktop 等) にのみ効く。 shell を持つ agent (Claude Code 等) は CLI を直接叩けるので、 セキュリティ境界 ではなく 事故経路削減 の措置。 shell 持ち agent への 歯止めが要るなら 実行ユーザの権限 or 機器ファームウェア側の 上限 (別 layer)。 selftest phase [27] で 回帰試験 (「MCP tools/list に send_command が含まれないこと」 + 「戻すと 落ちること」) を verify。 CHANGELOG 参照。

★ 過去 Version: 0.13.0-alpha (2026-08-25) — relational_compression_bound (K(x|y) 条件付き上界、 4 modes、 entanglement で 負可)。 詳細下記。

Version: 0.11.0-alpha (2026-08-27) — ★ SmellNet replay adapter spike: rei-scout 別 tab 発見 (2026-08-27 report Finding A: MIT-MI/SmellNet ★72, MIT License, MOX gas sensor, 50 substances + 43 mixtures, 828K timesteps / 68 hours) を rei-aios STEP 1474 candidate arc から STEP 1477 で 実装。 新 module benchtop_olfact_smellnet_replay.py (load_smellnet_csv / load_embedded_fixture / get_replay_window / download_smellnet_stub) と benchtop_olfact.measure_eag()replay_source optional param 追加。 v0.7 mock path (deterministic hashlib.md5 seed) は backward compat 完全維持、 data_source field ('mock' | 'replay') で 機械的に 区別可能。 embedded synthetic fixture (3 substance × 3 channel × 100 timestep、 SmellNet 互換 CSV schema) で interface 動作 verify、 実 SmellNet DL は download_smellnet_stub() で 6 step documented (別 STEP directive 待ち = network / HF auth 依存回避 の spike scope)。 SNR は replay path で (max-min)/stdev proxy 計算、 verdict は STEP 1350 3-value subset (TRUE/NEITHER) 継続。 novelty ゼロ ([[feedback-world-uniqueness-claim-controllable]] 継承、 「SmellNet 使用」 は 論文レベル既存)。 selftest 拡張 42 (replay adapter 単体) + 20 (olfact 統合、 mock 15 baseline + replay 6 = 6 追加) = 累計 62/62 PASS。 STEP 1477。

★ 過去 Version: 0.10.0-alpha (2026-08-27) — 宣言的 alert rule engine check_alert_rules (declarative rule、 4 per-row op + 3 session-level op + 3 severity + 5 guard、 analyze_session 3σ 固定則 補完、 STEP 1471)。

★ v1.0 threshold は defer 継続 (2026-08-27 判断、 藤本さん directive 経由): SPIKE 4 段 (v0.7 olfact / v0.8 wireup / v0.9.0 chem / v0.9.1 uart-chem) が mock skeleton のまま = semver 「1.0 = stable API + verified」 慣習に対して overclaim risk。 [[feedback-no-rush-publication]] discipline + [[feedback-world-uniqueness-claim-controllable]] 継承。 v1.0 移行条件は今後の別 STEP で判断: (i) SPIKE 各段の hardware verified evidence 添付 (Phase C silicon narrative の水平展開)、 (ii) Product Transition Judgment Framework v0.1 で 5 checklist 中 3+ 該当、 (iii) 藤本さん explicit go。 いずれも 2026-08-27 現時点 未達 = v0.10.0-alpha として feature 追加のみ (license MIT 継続、 v0.x 分は 永久 MIT irrevocable、 v1.0+ 分のみ 将来 AGPL flip 検討余地)。

Version: 0.7.0-alpha (2026-08-23, SPIKE) — ★ olfact / biosensor mock layer: 生体嗅覚センサ (bio-hybrid / receptor-chip / bio-inspired 3 layer) の interface skeleton を benchtop に 追加。 新 tool 3 個: list_probes (内蔵 mock probe registry 3 probe) + measure_eag (deterministic mock EAG waveform、 probe_id + odor_name の hashlib.md5 seed で cross-process 再現可能、 D-FUMT₈ verdict subset for STEP 1350 mapping) + probe_health (3 layer 別 degradation model: linear-hydrogel / exponential-protein-denaturation / calibration-only-silicon)。 藤本さん directive (2026-08-23 対話 arc 「虫の触覚センサー / 動物 / 植物センサー」 + 「AI に役立つか」 経由) 実装。 ★ hardware 未取得 = 全 tool で hardware_available: False + is_mock: True marker、 実 EAG physics (ion channel kinetics 等) 模倣なし = interface skeleton のみ。 実 hardware 統合 (フロントエンドアンプ + 恒温恒湿 + オルファクトメータ) は 別 STEP candidate。 selftest phase [21a-21f] 追加、 module 単体 35 assertion + wire 6 phase 全 PASS。 [[feedback-super-naming-siren-family-pattern]] 適用 (mock 誤読予防)、 [[feedback-world-uniqueness-claim-controllable]] 継承 (「世界初」 主張ゼロ、 novelty は Rei stack 内 benchtop 新 domain 追加のみ)。

Version: 0.6.0-alpha (2026-08-20, SPIKE) — ★ physics-limits pre-flight layer (5 tool): bekenstein_bound_bits / landauer_min_energy_j / lloyd_computation_ceiling / operator_space_size / compression_upper_bound。 LLM が 単位付き算術 + 桁勘定 + 上界計算で 誤りやすい 領域を pure calc (stdlib のみ) の MCP tool に落とし、 実 hardware SCPI 送出の pre-flight check として 使う。 SafetyGate (v0.5) と 相補: 事前規模計算 → SafetyGate。 Kolmogorov K(x) uncomputable は siren-family pattern 回避で明示 disclaimer 付き。 selftest phase [20a-20f]。

Version: 0.5.0-alpha (2026-08-19, SPIKE) — ★ provenance layer + SafetyGate: import_external_session で 他社 MCP server (Keysight/rigol/lecroy/kya-os wrapped) の 計測記録を benchtop に 取り込み + SafetyGate で SCPI-argument level の hazard (Kikusui PLZ-5W CR mode Siemens/Ω 混同 = 短絡 hazard 等) を 静的検出。 4 agent verify (2026-08-19) 経由の 「機器層/記録層 分割」 戦略の 記録層 実装。 selftest phase [19a-19f]。

Version: 0.4.0 (2026-08-17) — ★ 実験ノート (experiment notebook) 統合: Session dataclass に subject (被測定物 ID) / environment (温湿度 dict) / instrument_config (装置設定 dict) / mystery_id (rei-aios link) 全 optional field 追加。 新 tool 2 個: find_similar_sessions (subject / mystery_id / environment key/value + tolerance で 過去 session 絞り込み) + regression_check (baseline vs current の mean_delta / stdev_ratio tolerance-based 劣化検出)。 chat-Claude 2026-08-17 arc 「実験ノート MCP」 提案 (benchtop = 手を動かす、 rei-aios = 考える、 その間の 空白) を benchtop 内 拡張として 実装 (新 MCP 追加せず 「深化」 discipline 準拠)。 backward compat: 旧 JSON (v0.3.0 以前) も 読める、 新 field default None。 selftest phase [17] (実験ノート + find_similar_sessions 5 case) + [18a-18c] (regression_check 3 case) 追加、 計 18 phase 全 PASS。

Version: 0.3.0 (2026-08-17) — ★ major: audit log hash chain 追加 (Rei-Automator STEP 1340 primitive port)。 全 tool 呼び出しが ~/.benchtop-mcp/audit/audit.jsonl に append-only JSONL + sha256 prev-hash chain で 記録され、 新 tool verify_audit_chain で 改竄検出可能。 chat-Claude 2026-08-17 arc 「証跡が価値になる領域」 (ISO/IEC 17025 校正 / GMP 医薬品製造記録 / 監査対応) 用途。 session store (~/.benchtop-mcp/session_*.json) と 別 store で 併存、 audit log は 削除禁止 (append-only)。 BENCHTOP_AUDIT=0 で 無効化可能、 BENCHTOP_AUDIT_DIR で 保存先変更可能。 selftest phase [16a-16d] で genesis chain / continuation / tamper detection / MCP tool level を 各 verify。

Version: 0.2.4 (2026-08-13) — v0.2.3 verify 中に発火した実 pain 対応 (initial external-verify-derived fix): search_sessionssince / untilYYYY-MM-DD (時刻部分なし) のとき local midnight として解釈 し UTC 換算後に比較。旧 v0.2.3 では UTC 文字列辞書順比較で 「JST 早朝に測った session を since='今日' で 検索すると 0 件」 の 静かな穴があった (session_id は JST 表示 / started_at は UTC で日付が 1 日ずれる)。完全 ISO (T + offset) は従来通り厳密。BENCHTOP_TZ env で tz override 可能。副 fix として各 tool の返り値に started_at_local を併記。詳細は下記「v0.2 で足したもの」節。

Compatibility note: v0.2.3 は interpretation field の値を "threshold_gate_on_welch_standard_error" (v0.2.2) → "welch_t_statistic_with_fixed_z_threshold" に rename しました。この文字列を pattern match していた caller は壊れます。現時点で外部 caller はいない想定なので実害ゼロですが、今後 return dict の field 値を触るときは breaking change 扱いとします (メジャー版 or 明示注記の伴う変更のみ)。

v0.2.4 は search_sessions(since='YYYY-MM-DD') の 解釈を UTC 文字列辞書順比較 → local midnight 換算比較 に変更しています。厳密には behavior change ですが、「UTC 基準の日付のみ指定」を意図して使っていた caller は現実には存在しない想定 (いたとすればそれが今回のバグ) なので breaking 扱いはしません。完全 ISO 指定 (T + 時刻 + offset) は従来動作を維持。

License: v0.x は MIT。 v1.0+ は AGPL-3.0 + commercial dual への切替 可能性 予告 (LICENSE file 参照)。 v0.x 分は 永久 MIT (irrevocable)。


これは何を解決するのか

計測の現場では、だいたい同じことが繰り返されています。

  1. 装置にコマンドを送って値を読む

  2. しばらく回してログを取る

  3. Excel に貼って平均と σ を出し、おかしい点を探す

  4. CSV にして誰かに渡す

一つ一つは簡単ですが、面倒で、毎回手でやっています。このサーバーを入れると、その全部を AI に日本語で頼めるようになります。

「mock に繋いで200回測って、電圧のばらつきを見て、外れ値があったら教えて。結果は CSV にして」

地味です。しかし前の会話で確認した「売れるものの条件」——誰もが必要とし、自作すると面倒で、壊れると静かに高くつく——に、正確に当てはまります。


Related MCP server: embedded-serial-mcp

公開しているツール(AI から呼べる機能)

ツール

役割

list_ports

利用可能な装置の一覧。実機が無くても mock が必ず出る

send_command

v0.14.0-alpha (2026-09-20) で MCP 面から除去。 CLI からのみ呼べる: python benchtop_mcp.py send_command <port> <command> [--baudrate N]。 任意 SCPI 文字列を機器に投げる汎用口を MCP に露出すると モデルが SafetyGate 未経由の任意コマンドを組み立てられる ため。 shell を持つ agent (Claude Code 等) には効かず、 MCP-only client (Claude Desktop 等) 向けの 事故経路削減。 詳細 CHANGELOG 参照

measure

N 回連続で測定し、セッションとして保存

list_sessions

保存済みセッションの一覧

analyze_session

平均・σ・最小/最大・ドリフト・3σ外れ値を算出

export_session_csv

CSV に書き出し

plot_session (v0.2)

ASCII スパークライン (▁▂▃▄▅▆▇█) でチャンネル別に視覚化

compare_sessions (v0.2)

2 セッションの mean/stdev/drift 差分と Welch 型 z スコアを返す (v0.2.1: z_threshold 明示パラメータ)

search_sessions (v0.2)

日付範囲・note キーワード・port・channel でセッションを絞り込む

verify_audit_chain (v0.3.0)

audit log の sha256 prev-hash chain 整合性を検証 (改竄検出)

find_similar_sessions (v0.4.0)

subject / mystery_id / environment key/value + tolerance で 過去 session を 絞り込み (「3ヶ月前の 同じ条件と 比べて」 用)

regression_check (v0.4.0)

baseline vs current の mean_delta / stdev_ratio を tolerance-based で 判定 (校正基準からの 劣化検出)

list_probes (v0.7.0-alpha)

生体嗅覚センサ mock probe registry の 一覧 (3 layer: bio-hybrid / receptor-chip / bio-inspired、 全 hardware_available: False)

measure_eag (v0.7.0-alpha)

mock EAG (Electroantennogram) 測定、 deterministic waveform (hashlib.md5 seed 由来)、 SNR + D-FUMT₈ verdict (STEP 1350 mapping subset)

probe_health (v0.7.0-alpha)

生体劣化 verdict (HEALTHY/DEGRADING/EXPIRED/UNCALIBRATED)、 3 layer 別 degradation model

check_alert_rules (v0.10.0-alpha)

既存 session に 宣言的 alert rule 群を 適用 (校正・保守閾値の 静的 gate)。 4 per-row op (gt/lt/abs_gt/sigma) + 3 session-level op (drift_abs/stdev_gt/mean_abs_gt) + 3 severity + 5 guard、 analyze_session の 3σ 固定則の 補完

measure_eag (v0.11.0-alpha 拡張)

v0.7 mock path 保持 + replay_source optional param 追加 = SmellNet 互換 replay session を 与えると real dataset waveform を 返す (embedded fixture or external CSV)、 data_source field で mock / replay 区別、 is_embedded_fixture で fixture / external CSV 区別

load_smellnet_csv / load_embedded_fixture / get_replay_window / download_smellnet_stub (v0.11.0-alpha)

Python API only (MCP tool 未 wire = v0.12+ candidate)。 SmellNet 互換 MOX time-series CSV load + window 抽出 (linear interp + wrap around)、 embedded 3 substance × 3 channel × 100 timestep synthetic fixture、 実 DL は stub (別 STEP directive 待ち)

存在しない session_id を渡した場合、plot_session / analyze_session / compare_sessions / export_session_csv は例外を投げずに {"error": "session_not_found", "session_id": "...", "hint": "..."} を返す (v0.2.1)。AI から見て tool 呼び出しが例外で落ちるより、error 情報を含む dict が返る方がリトライ or 別 tool に自然に繋がる。

対応する測定値の形式は3種類を自動判別します。

T=25.3,H=48.1     →  {"T": 25.3, "H": 48.1}
25.3,48.1         →  {"ch1": 25.3, "ch2": 48.1}
25.3              →  {"value": 25.3}

v0.2 で足したもの

「毎回手でやる面倒」 を 1 つずつ引き受ける ための 3 ツール。有料化予告済みの機能 (連続ロギング / 閾値アラート / 校正記録) とは非競合の、あくまで基本操作の拡張です。

  • plot_session — Excel を開かずに傾向・外れ値の位置がざっくり見える。matplotlib を入れない (依存を増やさない) ため、Unicode ブロック文字 8 段階で描画。サンプル数が多いときは平均でビン化して幅を合わせる。

  • compare_sessions — 「先週と比べて怪しくないか」 を AI が数値で判断できるように、2 セッションの mean/stdev/drift 差分と Welch 型 t 統計量 (mean_shift_z として返す) を計算する。使う式は 1 本だけ: z = (mean_A − mean_B) / sqrt(σ_A²/n_A + σ_B²/n_B)。これは Welch's t 検定の統計量そのもの (v0.2.3 訂正: v0.2.2 では 「Welch's t-test ではない」 と書いていたが、 statistic は同一で異なるのは判定則という書き分けが正確)。異なるのは:

    • Welch's t-test は t 分布 critical value (自由度依存) で判定 → p 値

    • この tool は 固定閾値 z_threshold (既定 3.0) で単純 gate

    welch_df (Welch-Satterthwaite 自由度) を per-channel に返すので、caller は 「今回の n で固定 3.0 が甘い/厳しい」 を自分で判定できる (v0.2.3 追加)。分母は per-sample の SD ではなく 平均の標準誤差 (SE) の Welch 合成 なので、n が大きいほど固定閾値は厳しくなる (n=100 なら 「平均が 0.3σ 分ずれれば z=3」)。判定は呼び出し側の責任: z_threshold パラメータ (既定 3.0) を明示指定でき、z_threshold_used / z_formula に採用値と式が反映されるので後から audit 可能。is_hypothesis_test: false / disclaimer / per-channel interpretation: "welch_t_statistic_with_fixed_z_threshold" を機械可読 field として置く。

    Guard (v0.2.3): n<2 (stdev 未定義) または σ_A²/n_A + σ_B²/n_B = 0 (定数装置) の場合、gate を評価せずに gate_evaluable: false + gate_skip_reason: "insufficient_samples" or "zero_variance" を返し、mean_shift_z / welch_df / standard_error / significant_shift はすべて None。旧実装 (v0.2.2 以前) では 0/0→NaN→significant_shift=False に落ちて 「差が無い」 と静かに誤報していた path を明示 guard で分離。None は 「差が無い」 ではなく 「gate 未評価」 と読むこと。

  • search_sessionslist_sessions は直近 30 件しか返さないので、~/.benchtop-mcp/ にセッションが溜まってきたらこちら。since/until (ISO 日時) + note キーワード (大文字小文字無視) + port + channel の AND 絞り込み。

v0.2.1 の追加改善 (v0.2.0 レビュー指摘対応):

  • measure 途中失敗の partial 保存 — 装置切断・Ctrl+C・SerialException 等が起きても、そこまでに取れた行はセッションに保存され、返り値の partial: trueabort_reason で通知される。100 回中 60 で止まっても「60 行取れた + 止まった理由」が残る。全部捨てるより実運用の失敗解析に使える。

  • 無効 session_id の structured error — 上の tool 表下の注記の通り、例外ではなく dict で返す。

v0.2.2 の追加改善 (v0.2.1 レビュー指摘対応):

  • compare_sessions の z 式明示 + 検定ではないことの機械可読契約 — 上の compare_sessions 説明参照。docstring は人間 (caller) には届くが LLM の出力語彙までは縛れないので、return dict の is_hypothesis_test: false + disclaimer + per-channel interpretation で field 名として置いている。

  • partial の下流波及Session.aborted_at が立った session は、analyze_session / plot_session の top-level に partial: true + abort_reason を mirror。compare_sessions は 2 入力の非対称 n が z を歪めうるので any_input_aborted: true + aborted_inputs: ["a" or "b"] を top-level に立てる。search_sessions / list_sessions の各行にも partial を出す。中断された session が下流のどの tool を通っても事実が消えない契約。

  • plot_session の legend contract — per-channel dict に label: str (= channel 名) を追加、top-level に channels_order: [str] で render 順を明示。§3.5-c で 「どの line が どの channel か」 を目視 verify する際の後方支援。単位 (unit) は v0.3 へ defer 継続。

v0.2.4 の追加改善 (v0.2.3 実 verify 発火の pain fix、 initial external-verify-derived 変更):

  • search_sessions の date-only 解釈を local midnight 化 — 藤本さん が v0.2.3 verify 中 §3.5-b/c 全 pass 直後 に発見した 実 pain。 session_id は local time (JST) 表示、 started_at は UTC 保存で 日付が 1 日ずれる → since='2026-08-13', note_contains='seed'0 件 (今日作った session を 「今日以降」 で検索すると 消える)。 v0.2.4 では YYYY-MM-DD 形式 (時刻部分なし) を検出し local midnight として解釈 し UTC 換算 (since = 当日 00:00 local、 until = 当日 23:59:59.999999 local)。 「今日以降と書いたら 手元の時計で今日 0 時以降が返る」 直感一致。 完全 ISO (T + 時刻 [+ offset]) は 従来通り 厳密比較。 tz は BENCHTOP_TZ env 優先、 無ければ system local。

  • filters に audit trail 併記 — 返り値の filterssince_resolved_utc / until_resolved_utc / since_date_only / until_date_only / tz_used を 追加。 「意図した通り 解釈されたか」 が 機械可読で 確認可能。

  • started_at_local 副 field を 各 tool に追加 (副役割、 主 fix と 独立)。 search_sessions / list_sessions 各 row + analyze_session / plot_session top-level + compare_sessions の a/b 各 input dict。 空振り時は 見えない (副役割の 明確化) が、 検索成功後に 日時を 読む時に 便利。

v0.2.4 で 明示 defer した もの (「隠す」 選択の 意味論設計先要): plot_session の 外れ値で スケール潰れ (3% 外れ値機構の 1 点が最大値になると 残り 29 点が最下段に潰れる) は sparkline の 数学的性質 (min/max 正規化) の限界。 percentile clip や 外れ値別記号は 「clip した」 事実の どう明示するかの 設計判断が 追加で必要 = v0.2.5+ or 別 tool (plot_session_clipped) 候補。 現状は analyze_sessionoutliers field で 外れ値 位置 + magnitude は 取れる (併用推奨)。


v0.2.3 の追加改善 (v0.2.2 レビュー指摘対応):

  • compare docstring の自己矛盾撤回 — v0.2.2 は 「これは Welch's t-test ではない」 と書いていたが、上の式が示す通り statistic は Welch t そのもの。訂正: 「statistic は Welch t と同一、異なるのは判定則 (df 依存 critical value vs 固定閾値)」 と書き分け。per-channel interpretation string も "threshold_gate_on_welch_standard_error""welch_t_statistic_with_fixed_z_threshold" に更新。

  • Welch-Satterthwaite welch_df 露出 — per-channel に welch_df field を追加。固定閾値 3.0 は n=5 で df≈8 なら本来 2.8〜4.6 が必要 (甘い側)、n=100 で df≈198 なら α≈0.003 相当 (厳しい側) と n 依存する。df を露出することで caller が 「今回の n でこの gate を信用していい範囲か」 を自分で判断できる。partial session は n が任意に小さくなり得るので、この露出は下流波及と繋がっている。

  • zero_variance / insufficient_samples guard — 実害寄りの gap: mock device が定数を返す構成 (σ=0) や n=1 の partial session を compare すると、旧実装は se=0 → z=0/0 (NaN) → abs(z) > 3.0 は常に False に落ちて 「差が無い」 と静かに報告していた。v0.2.3 で明示 guard を導入: n<2gate_skip_reason: "insufficient_samples"σ_A²/n_A + σ_B²/n_B = 0gate_skip_reason: "zero_variance"。どちらの場合も mean_shift_z / welch_df / significant_shift はすべて None (False にすると 「差が無い」 と 誤読されるので None = 「未評価」 signal に分離)。selftest phase [14] で _ConstDevice_FailingDevice(fail_after=1) の 2 case verify。

呼び出し例:

「今日 mock で 5 回、それぞれ 30 秒ずつ測って、最後に一日分をまとめて見せて」
→ measure × 5 → search_sessions(since='2026-08-12') → 各 session plot_session
「先週の校正データと今の値を比べて、有意に動いていないか教えて」
→ search_sessions(note_contains='calib') で基準を特定
→ measure で今の値
→ compare_sessions(session_id_a=今, session_id_b=基準)

導入手順

1. 依存関係を入れる

pip install "mcp>=2.0.0" pyserial

pyserial は実機に繋ぐときだけ必要です。無くてもモックは動きます。

2. 動作確認(Claude に繋ぐ前に、まずこれ)

python benchtop_mcp.py --selftest

以下のように出れば成功です。

== benchtop-mcp セルフテスト ==
[1] ポート一覧: 3件 / pyserial=True
[2] IDN応答: MOCK,BENCHTOP-SIM,0001,1.0.0
[3] パース: 4形式すべてOK
[4] 計測: 60行 / channels=['T', 'H', 'V']
[5] 解析: T平均=25.019967 σ=0.473851 外れ値=2件
[6] CSV書き出し: ... (61行=ヘッダ1+データ60)
[7] plot: width=40 T='▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▂▄▄▄▄▄▆' (len=40, range=5.041)
[8] compare: shared=['T', 'H', 'V'] T delta_mean=0.146467 z=1.573 significant=False
[9] search: note='selftest' で 8 件ヒット (s=True, s2=True)
[10] invalid id → structured error='session_not_found' / 有効 id → Session OK
[11] compare threshold: |z|=0.507 welch_df=89.075 strict(3.0)=False loose(0.5)=True
[12] partial measurement: n_rows=5/20 aborted=True reason='RuntimeError: simulated device failure after 5 reads'
[13] partial downstream: analyze.partial=True/False plot.partial=True/False cmp.any_aborted=True/False cmp.aborted_inputs=['b'] search.partial=True/False
[14a] zero variance guard: evaluable=False reason=zero_variance z=None sig=None df=None
[14b] insufficient n guard: evaluable=False reason=insufficient_samples n_a=1 n_b=60
[14c] guard 独立性: 正常 case (phase [11] 再利用) evaluable=True 対 guard case evaluable=False
[15a] date-only 'since=2026-08-13' → resolved_utc=2026-08-12T15:00:00+00:00 date_only=True tz=Asia/Tokyo
[15b] full ISO 'since=2026-08-13T00:00:00+00:00' → resolved_utc=2026-08-13T00:00:00+00:00 date_only=False
[15c] JST 早朝 session (started=2026-08-12T15:30:00+00:00) が since='2026-08-13' で 拾える → found=True (旧 v0.2.3 では 拾えなかった)
[15d] started_at_local 補助 field: search[0]=2026-08-13T00:30:00+09:00 analyze=2026-08-13T00:30:00+09:00 (JST +09:00 一貫)

全テスト成功。実機が無くてもこのサーバーは動作します。

数値はランダム性で毎回変わりますが、行の形と phase 数 (1〜15) が一致し、末尾が「全テスト成功」で終われば正常です。Windows の cp932 端末でも Unicode スパークラインが表示できるよう、selftest 内で stdout を UTF-8 に切り替えています。phase [15] は BENCHTOP_TZ='Asia/Tokyo' を test 内で 一時的に設定 (finally で復元) して tz 依存を 固定しています。

3. Claude Desktop に登録する

設定ファイル(%APPDATA%\Claude\claude_desktop_config.json)に追記します。

{
  "mcpServers": {
    "benchtop": {
      "command": "python",
      "args": ["C:\\path\\to\\benchtop_mcp.py"]
    }
  }
}

Claude Desktop を再起動すると、ツール一覧に benchtop が現れます。あとは普通に日本語で頼めます。

3.5. 再起動後の動作確認 (推奨)

いきなり本番の指示に入る前に、下の 3 step を挟むと「MCP server が本当に load されているか」「新 3 tool が Claude 側から見えているか」を確実に切り分けられます。MCP server load に失敗していても Claude は既存 tool で "それらしく" 答えてしまうので、失敗が結果に紛れないようにするための保険です。

Step 3.5-a: tool load 確認 (最優先)

使える tool を全部挙げて

期待値: benchtop の 9 tool (list_ports / send_command / measure / list_sessions / analyze_session / export_session_csv / plot_session / compare_sessions / search_sessions) が挙がること。挙がらなければ config が読まれていない → %APPDATA%\Claude\claude_desktop_config.json の path を確認。

Step 3.5-b: seed データを 3 つ作る

search_sessionscompare_sessions の verify には、note で区別できる複数セッションが必要です。

mock で 30 回、note='seed-A' で測って。終わったら少し待って、同じく note='seed-B' で 30 回、
また少し待って note='seed-C' で 30 回、計 3 セッション作って。

期待値: 3 つの session_id が返ること。各 started_at が数秒〜数十秒ずつずれていること (これが後の「一番古い/新しい」判定の根拠になる)。

Step 3.5-c: 新 3 tool を verify

1. さっき作った seed-B の T チャンネルを plot で見せて  (→ plot_session)
2. note に 'seed' を含むセッションを全部リストして      (→ search_sessions、started_at で新旧確認)
3. seed-A と seed-C を z_threshold=2.0 で比べて、
   T が有意にシフトしているか教えて                       (→ compare_sessions with explicit threshold)

期待値: (1) ▁▂▃▄▅▆▇█ のスパークライン + min/max/mean、(2) seed-A seed-B seed-C の 3 セッションが started_at 付きで一覧、(3) mean_shift_z の数値 + z_threshold_used: 2.0 + significant_shift の bool。compare_sessions の判定閾値は明示指定した値で解釈されること (v0.2.1 の責任分界)。


実機に繋ぐ

装置が1行1レコードで値を送ってくるなら、それだけで動きます。Arduino 側の最小例:

void setup() { Serial.begin(9600); }

void loop() {
  float t = analogRead(A0) * 0.0048828125 * 100.0;
  float v = analogRead(A1) * 0.0048828125;
  Serial.print("T="); Serial.print(t, 3);
  Serial.print(",V="); Serial.println(v, 4);
  delay(100);
}

あとは portCOM3(Windows)や /dev/ttyUSB0(Linux/Mac)を指定するだけです。


コードの読みどころ

学習目的で読む場合、この3点が設計の要点です。

1. コアと MCP 層を分離している Bench クラスは MCP を一切知りません。MCP 層(@server.tool() の部分)は薄い皮です。こうしておくと、コアだけ単体テストできますし、将来 CLI や Web API を生やすときにも書き直しが要りません。

2. モック装置を最初から入れている Device という共通インターフェースを挟み、実機(SerialDevice)とモック(MockDevice)を差し替え可能にしています。ハードが手元に無い日でも開発が止まりません。デモも CI も通せます。ハードウェア絡みのソフトでは、これがあるか無いかで開発速度が何倍も変わります。

3. docstring が AI への説明書になる @server.tool() を付けた関数の docstring と型注釈は、そのまま AI に渡されます。ここが雑だと AI は道具を正しく使えません。普通のコードではコメントは人間向けですが、MCP では機械向けの仕様書です。 ここを丁寧に書くことが、そのまま品質になります。


ライセンス

v0.x = MIT (LICENSE file 参照)。 藤本さん 2026-08-12 judgment per 選択。

v1.0+ 以降は AGPL-3.0 + commercial dual への 切替可能性 予告 (LICENSE file 内 「License trajectory notice」 参照)。 但し v0.x code は 永久 MIT (irrevocable) = fork 継続 path は 永久に開く。

背景: Product Transition Judgment Framework v0.1 の 5 checklist を benchtop-mcp v0.x 段階では 0-1 件該当 = 無料継続 default。

参考: 有料化候補 3 点 fit (chat-Claude 2026-08-12 arc 分析)

benchtop-mcp は 「売れる条件 3 点」 全該当 = 有料化 candidate:

  • 誰もが必要: 計測ログ + 統計 + CSV 出力 は 差別化要素でない (全部の 計測現場が やる作業)

  • 自作面倒: シリアル通信 + セッション管理 + AI 説明 docstring は 毎回書きたくない

  • 静かに壊れて高い: 監視ログが 数日 気付かず 溜まる、 品質記録が 消えると 監査で困る

将来 v1.0+ で 有料 tier 検討する場合の 線引き案:

推奨する組み合わせ (将来 v1.0+ の 参考、 現時点 v0.x = MIT)

ソフト部分: AGPL-3.0 + 商用ライセンスのデュアル

  • 個人・研究・社内利用は無料で自由に使える(あなたの「個人にも使ってほしい」という希望を満たす)

  • ただし、これを組み込んだ製品を売るなら、ソース公開か商用ライセンス購入かを選ぶことになる

  • MIT にすると、この選択を後から追加できません。AGPL なら、後から緩めるのは自由(著作権者はいつでも緩められる)

貢献者対応: CLA を最初に用意する

外部から Pull Request を受け取ると、その部分の著作権は相手のものになり、あなた単独でライセンスを変更できなくなります。将来の商用化を残すなら、最初から CLA(貢献者ライセンス同意書)を置いてください。後から遡って集めるのは、ほぼ不可能です。

無料/有料の線引き案

無料(AGPL)

有料

装置操作・計測・解析・CSV

同時接続する装置の数

1台

無制限

長時間の連続ロギング・自動再接続

閾値アラート・異常通知

校正記録・監査ログ(トレーサビリティ)

サポート・SLA

企業が金を払うのは機能ではなく、「止まったときに誰かに電話できる権利」と「監査に出せる記録」 です。個人が欲しがるのは上段だけなので、この線引きなら両者は競合しません。

回路・装置を含める場合の警告 (依然 有効)

公開する前に特許出願の要否を判断してください。 ソフトと違い、ハードウェアは公開した瞬間に新規性が失われ、特許が取れなくなります。日本には新規性喪失の例外(特許法30条、公開から1年以内の出願)がありますが、国によって扱いが異なり、海外出願で詰むことがあります。

これは一方通行のドアです。ユーザーが0人でも損失は確定します。

本 project の scope: benchtop-mcp = 純 software (Python + pyserial via generic protocol) = 特許性事実上ゼロ (シリアル通信 + 統計 + CSV export は 数十年 well-known)。 ハードウェア回路 (Arduino sketch 例は README 参照用のみで 本 repo に含まず) は 依然 上記警告対象。


次にやるとよいこと

  1. --selftest を通す(最優先。ここが通れば土台は正しい)

  2. Claude Desktop に登録して、実際に日本語で呼んでみる (再起動後は上の Step 3.5 の 3 step verify を先に)

  3. 手持ちの装置1台を繋いで、send_command*IDN? に応答が返るか確認

  4. 自分が毎回手でやっている面倒な作業を1つ、ツールとして足す — ただし判定基準は AND 2 条件:

    • (i) 1 回の測定で手作業が 3 step 以上 (装置接続 → コマンド送信 → CSV 貼付、のような複数手順)

    • (ii) 週 1 回以上 発生 (月 1 未満の作業は tool 化コスト > 手作業コスト)

    どちらか外れる作業は tool 化しない。この 2 条件を通ったものだけ 4 tool 目候補として拾う。ここからが本当のオリジナルです。

  5. ライセンスを決めて GitHub に公開

Elasticsearch は奥さんのレシピアプリから始まりました。最初から立派である必要はありません。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for quantum device physics laboratory instrumentation control, enabling LLMs to interact with physics instruments and measurement systems through QCodes and JupyterLab.
    36
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A professional MCP server for serial port communication, enabling AI assistants to list, connect, send/receive data, and manage serial connections with embedded systems, IoT devices, and hardware debugging hardware.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Serial communication and protocol analysis MCP server that gives AI coding assistants direct access to serial ports for reading, writing, decoding, and capturing embedded device output.
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    An MCP server for controlling lab instruments (oscilloscopes, signal generators, etc.) via standardized interfaces like USBTMC, RS-232, and LAN.
    100
    MIT