+++ # 必須。Software名、一覧、HTML titleで使用する。 title = "ollama-web" # 任意。一覧とmeta descriptionで使用する。不要なら空文字列のままにする。 description = """ Docker や仮想マシンを必要とせず、ホスト OS 上で直接起動して利用できる、軽量な個人向け Ollama Web UI です。 """ # 必須。Software一覧の並び順で使用する。 date = 2026-08-22 # 必須。Notes中心のサイトfeedへSoftwareを含めない。 include_in_feeds = false [extra] # 任意。詳細ページの「使用言語」に表示する。 language = ["Python"] # 任意。詳細ページの「ライセンス」に表示する。 license = "MIT" # 必須。ソースコードの正本となるcgit URLを指定する。 source = "https://git.takashi-2521.com/ollama-web/" # 任意。GitHub mirrorがない場合は空文字列のままにする。 github_mirror = "https://github.com/takashi000/ollama-web" # 任意。content/を基準にしたNotesのMarkdown pathを指定する。 related_notes = [] +++ ## 概要 ブラウザから Ollama とのストリーミングチャット、 Web 検索・URL 取得、画像・ファイル・PDF 添付、MCP Tool Calling を利用できます。\ 大規模な AI プラットフォームを導入せず、個人が小さな構成で使うことを想定しています。 ![実行例](capture.gif) ## 背景 OpenWeb UIなどの生成AIプラットフォームだと、DockerなどのVM環境を立ち上げる必要があるのが、 結構煩わしく感じられました。\ 最近は、Ollamaでも GLM-5.2やDeepseek V4などの比較的エージェンティックに動作するオープンウェイトモデルが使用できます。\ より、手軽に使えるOllamaフロントエンドアプリケーションを作ろうと思いました。 ## 開発の過程 基本的には、CodexとZooCodeを使用して開発しました。 軽量化を重視したため、バックエンドにはStarletteとUvicorn、HTML生成にはJinja2を使用しています。 フロントエンドも専用フレームワークを導入せず、HTML、CSS、JavaScriptで構成しました。 会話履歴などもセッションで管理できるようにしました。\ ここもデータベースを導入せずに、 ディレクトリ単位でJSONを使って保存するようにしました。 見た目のUIに関しては、レスポンシブデザインに対応しました。\ スマホからだとレンダーできないケースが頻発しました。\ LLMからの応答を逐次受信するたびにMarkdown全体をHTMLへ変換していたからでした。\ 応答が長くなるほど再描画の負荷が増えました。\ なので、Markdownとしての最終的なHTML変換は応答完了時にまとめて行いました。\ ストリーミング中の表示はリアルタイムに更新します。 標準のツールには、Web検索・スクレイピング・PDF抽出を搭載しました。\ 必要になった部分だけを追加取得できるように、ツールにページング機能を付けました。\ ツール呼び出しが一定回数を超えた場合は、その時点で最終回答を生成させるようにしました。 MCPにも対応しました。プロトコルは2025-11-25版[^1]です。\ 対応したトランスポートは、stdioとStreamable HTTPです。\ SSEは非推奨でしたので、非対応です。\ tool/list、tool/callの最小限の機能だけ実装しました。 [^1]: [Model Context Protocol Specification — 2025-11-25](https://modelcontextprotocol.io/specification/2025-11-25) PIN認証、CSRF・CSP対策、取得先URLの検査、MCP実行ファイルと接続先の許可リスト化を採用しました。\ LANからの利用、Web取得、ファイル操作、MCPによる外部プログラムの起動をセキュアに保ちます。\ 任意のプロセスの起動を防ぐため、明示的に許可した実行ファイルだけstdio経由でのMCPに使用できます。 ## 参考資料