以前、こちらの記事で 月額0円の会計ソフト e-shiwake を紹介しました。
その後もコツコツ時間が空いた時に開発を続け、WebMCP 対応と、AIチャット機能(ローカルLLM / クラウドLLM 対応) を追加したので、その紹介です。
この記事で紹介すること
| 追加機能 | バージョン | 概要 |
|---|---|---|
| WebMCP 対応 | v0.2.0〜 |
navigator.modelContext にツールを登録し、ブラウザ側 AI エージェントから帳簿を操作可能に |
| AIチャット | v0.5.0 | ユーザーが用意した LLM(ローカル/クラウド)に接続し、アプリ内で帳簿を自然言語操作 |
先にオチを言うと、「ツール定義をプレーンな TS 関数として書いておいたら、WebMCP とアプリ内チャットの両方に同じ定義を供給できた」 というのがこの記事の一番のポイントです。
WebMCP 対応
WebMCP とは
WebMCP(Web Model Context Protocol)は、W3C で標準化が進められているブラウザ API です。Web アプリが navigator.modelContext.registerTool() でツールを登録すると、AI エージェント(Chrome 内蔵 AI など)がそのツールを認識・実行できるようになります。
スクリーンショットベースの画面操作と違い、構造化されたツール呼び出しで直接アプリを操作するため、高速・正確で、トークン消費も大幅に削減できるとされています。
e-shiwake が公開しているツール(17個)
起動時に データ操作型 12 + UI 操作型 5 の計 17 ツールを自動登録します。
| 分類 | ツール |
|---|---|
| 仕訳管理 |
search_journals, get_journals_by_year, create_journal, delete_journal
|
| マスタ参照 |
list_accounts, list_vendors
|
| 帳簿生成 |
generate_ledger, generate_trial_balance, generate_profit_loss, generate_balance_sheet
|
| 税務 | calculate_consumption_tax |
| ユーティリティ | get_available_years |
| UI 操作(HITL) |
navigate_to, open_journal_editor, set_search_query, confirm_delete_journal, open_invoice_editor
|
UI 操作型は Human-in-the-Loop パターンです。AI は仕訳フォームを開いてプリフィルするところまで。確定ボタンを押すのはユーザーです。会計データという性質上、「AI が勝手に帳簿を書き換える」のではなく「AI が下書きし、人間が確定する」を基本にしています。
試すには
- Chrome 146 以上
-
chrome://flags→ 「WebMCP for testing」を Enabled - ブラウザ再起動後に e-shiwake を開くと、DevTools Console に登録ログが出ます
[e-shiwake] WebMCP: 17 ツールをAIエージェントに公開しました
ここで気づいたこと
WebMCP のツール定義は、navigator.modelContext 専用に書く必要はありません。e-shiwake では次のような プレーンな TS 関数として定義しています。
{
name: 'search_journals',
description: '全年度を横断して仕訳を検索...',
inputSchema: { /* JSON Schema */ },
execute: async (args) => { /* IndexedDB を直接操作 */ }
}
navigator.modelContext.registerTool() への登録は薄いラッパーに過ぎない。ということは——
同じツール定義を、別の AI 実行系にもそのまま供給できる。
これが次の AIチャット機能につながります。
AIチャット機能(v0.5.0)
WebMCP は現状 Chrome のフラグが必要で、iPad Safari では動きません。そこで、ユーザーが用意した LLM に直接つなぐアプリ内チャットを実装しました。
アーキテクチャ
ポイントは3つ。
1. ツール定義は WebMCP と単一ソース
WebMCP に登録している 17 ツールを、そのまま OpenAI の function tool 形式に機械変換してチャットの LLM に渡します。inputSchema が JSON Schema サブセットなので、変換は十数行で済みます。
function toOpenAITool(t: WebMCPToolDefinition): OpenAIToolSchema {
return {
type: 'function',
function: {
name: t.name,
description: t.description,
parameters: t.inputSchema ?? { type: 'object', properties: {} }
}
};
}
2. エージェントループはブラウザ内・素朴実装
LangGraph.js のようなフレームワークは使わず、fetch ベースの tool calling ループ(100行程度)で実装しました。サーバーは一切不要で、iPad Safari でも動きます。
破壊的な delete_journal だけは、実行前に必ず承認ダイアログを挟みます(Human-in-the-Loop)。
3. 接続先は ProviderAdapter で抽象化
接続先を「OpenAI 互換の /v1/chat/completions」に限定して抽象化しました。アプリ本体は接続先が何かを知りません。
| プリセット | 接続先例 | API キー | データの扱い |
|---|---|---|---|
| ローカル LLM(LiteLLM / Ollama / vLLM / llamafile) | http://localhost:4000/v1 |
不要 or 任意 | LAN の外に出ない(推奨) |
| OpenAI | https://api.openai.com/v1 |
必須 | 外部送信あり |
| Anthropic | https://api.anthropic.com/v1 |
必須 | 外部送信あり |
| Google Gemini | https://generativelanguage.googleapis.com/v1beta/openai |
必須 | 外部送信あり |
| xAI Grok | https://api.x.ai/v1 |
必須 | 外部送信あり |
| カスタム(OpenAI 互換) | 任意(企業 VPC 内の LiteLLM 等) | 任意 | 接続先に依存 |
できること
- 「今月の経費トップ5は?」→ 仕訳を検索・集計して回答
- 「試算表を出して要約して」→ 帳簿生成 + 要約
- 「サーバー代 3,300円を計上して」→ 仕訳フォームをプリフィルして表示(確定はユーザー)
- デスクトップではチャットがサイドにドッキングし、AI が開いたフォームを並行操作できます
プライバシーの話(ローカルLLM が本命)
e-shiwake は「データは全てローカル保存、サーバーに送信しない」を売りにしてきました。ところがクラウド LLM につなぐと、チャット中に参照した仕訳・金額・取引先がプロバイダに送信されます。
この非対称性への答えは以下の通りです。
- 本命はローカル LLM。LiteLLM / Ollama を LAN 内に立てれば、帳簿データは一切外に出ません
- クラウドを選んだ場合は、設定画面で外部送信の警告を明示した上でユーザーの選択に委ねる
- API キーと会話履歴は端末内の IndexedDB のみに保存。e-shiwake はサードパーティスクリプトを含まない静的 PWA なので、キーが第三者スクリプトに読まれるリスクは低い構成です
- 企業利用なら、VPC 内の LiteLLM にクラウドキーを集約し、ブラウザには接続先 URL だけ置く構成も可能(LiteLLM がキー集約・監査ログ層になる)
ローカル LLM のハマりどころ
- CORS: ブラウザから直接 LLM サーバーを叩くため、LiteLLM / Ollama 側で e-shiwake のオリジンを許可する必要があります
-
Anthropic 直叩き:
anthropic-dangerous-direct-browser-access: trueヘッダーが必要です - tool calling 精度: ローカルの小型モデルはツールの呼び分けを間違えることがあります。読み取り系はローカル、複合仕訳の起票などはクラウド、と使い分けるのが現実的です
寄り道: stdio MCP サーバー版(e-shiwake-ai)も作ってみた
実は AIチャットの前に、ビジネスロジックを SQLite + stdio MCP サーバーとして切り出したモノレポ(e-shiwake-ai)も作りました。Claude Desktop などのブラウザ外エージェントから帳簿を操作する構成です。
ただ、これはアーカイブにしました。
理由はシンプルで、SQLite が本番データ(IndexedDB)と同期しないという構造的な制約があるためです。ブラウザ内チャットなら本番データを直接触れるので、そちらを本命にしました。
とはいえ「MCP ツールとして切り出せる粒度でビジネスロジックを設計する」練習としては収穫があり、必要になれば参照実装として復活させる予定です。試みとして記録に残しておきます。
今後の展望
別途、国税庁の通達・タックスアンサーや e-Gov 法令を AI から検索できる MCP サーバー群(houki シリーズ)も作っています。これらと組み合わせれば、「この経費、根拠となる通達は?」→ 帳簿と法令原文を突き合わせて回答、という記帳と税務根拠確認がつながる世界も見えてきます。このあたりはまた別の記事で。
まとめ
- WebMCP 対応で、ブラウザ側 AI エージェントから帳簿操作が可能に(Chrome 146+)
- ツール定義をプレーン TS 関数で書いておいたことで、同じ 17 ツールをアプリ内 AIチャットにそのまま流用できた
- AIチャットは OpenAI 互換 API なら何でも接続可能。ローカル LLM ならデータは LAN から出ない
- 破壊的操作は承認ダイアログ、起票はフォームプリフィル——AI が下書きし、人間が確定する
「月額0円・ローカル完結」のまま、AI アシスタント付きの会計ソフトになりました。
引き続きフィードバックは GitHub の Issue やコメントでお待ちしています🙏
