広告

EZRide Intel — Notion MCPを使ってボストンの“隠れた無料バス”のためのAIアシスタントを作った

Dev.to / 2026/3/30

💬 オピニオンDeveloper Stack & InfrastructureTools & Practical Usage

要点

  • 著者は、「EZRide Intel」というAI搭載の交通アシスタントを作成し、2002年から運行されているボストンの“隠れた無料”シャトルを人々が見つけて利用できるように支援した。
  • システムは唯一のバックエンド/データレイヤーとしてNotion MCPを使用し、読み取り・書き込み・分析のすべてを、従来のデータベースやファイルストレージではなくNotion経由でルーティングしている。
  • EZRide Intelには、ルート/停留所のQ&A、2015〜2025年の利用者数(ridership)を扱う分析ダッシュボード、そしてワンクリック操作で停留所の閉鎖情報をNotionに更新できるライブアラート管理が含まれている。
  • 旅程プランナー機能では、整形された旅程をリッチページとしてNotionに保存し、アシスタントはNotion全体の検索に対応するほか、「Notion Query Log」データベースにより最近の検索をサイドバーに表示する。
  • アーキテクチャはCharles River TMAのデータを一度きりのシードスクリプトで取り込み、その後エージェントが5つのNotionデータベースから取得し、Geminiが回答を生成し、MCPを通じてインタラクションをNotionへログする。

---
title: "EZRide Intel — Notion MCPでボストンの“隠れた無料バス”にAIアシスタントを作った話"
published: false
tags: devchallenge, notionchallenge, mcp, ai
---

これはNotion MCP Challengeへの提出です

What I Built

ボストンやケンブリッジに住む多くの人は、2002年から完全に無料の公共シャトルが走っていることを知りません――運賃なし、身分証なし、登録なしです。これはボストンのノースステーションから、ケンドル・スクエアとMITを経由してケンブリッジポートまでを結び、誰でも利用できます。

それがEZRideです。そして、ほとんど誰も存在を知りません。

私はEZRide Intelを作りました。Notionだけをデータベース層として、この隠れた公共資源を発見可能にするAIパワードの交通アシスタントです。実行時にPostgreSQLもFirebaseもJSONファイルもありません。読み取りも書き込みも、あらゆる分析クエリもすべてNotion MCPを通ります。

What it does:

  • AI トランジットアシスタント — ルート、停留所、時刻表、運賃について、Notionからライブ配信されるデータを使って質問に答えます
  • 利用者数分析ダッシュボード — 2015〜2025年の歴史的な利用者数分析をChart.jsの可視化で提供。すべてNotion Analyticsデータベースから取得したデータです
  • ⚠️ ライブアラート管理 — サイドバーにアクティブな停留所の閉鎖状況を表示。pages.updateでNotionをリアルタイム更新する“1クリック”で解決できます
  • トリッププランナー — フォーマットされた旅程を、blocks.children.appendでリッチページとしてそのままNotionに保存します
  • Notionグローバル検索 — Notionのsearch APIで、EZRideのすべてのデータベースを同時に横断検索します
  • 最近の検索 — サイドバーに、NotionのクエリログDBから取得したライブの質問が表示されます。チャットのやり取りごとに更新されます

Video Demo

Show Me the Code

How I Used Notion MCP

Notion MCPは、このプロジェクトでの単なるサイド連携ではありません――データ層そのものです。全体のアーキテクチャは以下の通りです:

チャールズリバーTMAのデータ(charlesrivertma.org)
        ↓
   ingest.py(1回限りのシードスクリプト)
        ↓
  Notionワークスペース(MCP経由で5つのデータベース)
  ├── Routes DB      — 停留所・時刻・方向を持つ4つのサービスパターン
  ├── Stops DB       — 地域名とサービスメモ付きの16停留所  
  ├── Alerts DB      — アクティブな停留所の閉鎖(pages.updateで解決可能)
  ├── Query Log DB   — すべてのユーザーの質問 + AIの回答 + タイムスタンプ
  └── Analytics DB   — 2015〜2025年の利用者数データ(11年分)
        ↕
   agent.py — 5つすべてのDBを読み取り → Geminiが回答を生成 → Notionにログを書き戻す
        ↓
   Flask Webアプリ(localhost:5000)

Notion MCPで使ったツール:

databases.query — RAGパイプラインの中核です。ユーザーのあらゆる質問がRoutes、Stops、Alerts、Analyticsの各データベースへのライブクエリを引き起こします。結果はGeminiのコンテキストウィンドウになります。つまりAIの知識は実行時に完全にNotionから供給されます。

pages.create — 2つの用途で使います。まず導入時にインジェストスクリプトが、16停留所、4ルート、2つのアラート、11年分の分析データをすべてNotionへシードします。次に実行時には、ユーザーのあらゆる質問をクエリログDBへの新しいページとして記録します。

pages.update — 人が介入して解決するアラートのための仕組みです。トランジットアラートが解決されたら、UIで「Mark Resolved」をクリックします。するとpages.updateが呼ばれ、Notion上のStatusプロパティをActive → Resolvedへライブで変更します。ページの再読み込みは不要です。

blocks.children.append — トリッププランナーが、ユーザーが旅程を保存するときに、見出し、コールアウトブロック、箇条書きの停留所リストを含む完全なリッチNotionページを作成します。このページは即座にユーザーのNotionワークスペースに表示されます。

searchsearch APIを使ってNotionの検索を行い、EZRideのすべてのデータベースを同時に横断します。マッチした停留所、ルート、分析レコードが返されます。

データベースとしてのNotionが重要な理由

多くのプロジェクトでは、Notionは「本物の」データベースの上に載るUIレイヤーとして使われます。EZRide Intelでは、Notionデータベースです。代替手段はありません。Notion連携を切断すると、AIにはコンテキストがなくなり、ダッシュボードにはデータがなくなり、クエリログは書き込む場所がなくなります。

つまり:

  • 非技術ユーザーは、Notion上で停留所データを編集したり、アラートを追加したり、時刻表を更新したりできます――コード変更は不要です
  • クエリログはNotion自身の“生きた分析ダッシュボード”になります――人々がリアルタイムで何を聞いているかを確認できます
  • アラートはトランジット事業者がNotion上で直接管理でき、Webアプリは変更を即座に反映します

この仕組みが解決する市民的な課題

EZRideはCOVID以前は年間平均50万人の乗客がいました――それでもケンブリッジ市議会の議員は、公の場で、バスの運転手でさえも「そのルートが一般公開されている」ことを知らないと述べました。人々はドアの前で追い返されます。認知のギャップは現実に存在します。

EZRide Intelは、自然言語を通じてサービスを見つけられるようにします。何でも聞いてください:

  • 「EZRideって本当に無料?」 → はい、100%無料。身分証は不要です
  • 「MITの近くの停留所はどこ?」 → 平日はMain/VassarとVassar/Mass Aveです
  • 「COVIDは利用者数にどう影響した?」 → 年間の利用者数は2019年の508,000人から2020年の142,000人へ――72%の減少です
  • 「今、停留所の閉鎖はある?」 → Broadway/Galileoは月〜金で閉鎖中。ケンドル・スクエア(71 Ames St)を利用してください

データソース

すべてのルート、停留所、時刻表データはチャールズリバーTMA公式サイトから取得しています。歴史的な利用者数のアンカーポイントは、公式発表に基づきます。2012年の日次平均2,500人の乗客と、COVID以前の年間利用者数約50万人はStreetsblog MassachusettsおよびWikipediaから取得しました。中間年は、既知のトレンドに従って現実的な合成データとして再構築しています。

Tech Stack

  • バックエンド: Python + Flask
  • AI: google-generativeai 経由のGoogle Gemini 2.5 Flash
  • データベース: Notion(notion-client のPython SDK経由)
  • フロントエンド: Vanilla HTML/CSS/JavaScript + Chart.js
  • データ取り込み: カスタムPythonシードスクリプト(ingest.py
  • パターン: RAG(Retrieval Augmented Generation)—コンテキストウィンドウとしてNotionデータを使用

広告