Skip to main content
Glama

OfferUpBot

OfferUpBot は、外部エージェント向けの OfferUp 実行レイヤーです。エージェントは商品の特定、価格の選択、コピーの作成、応答の決定を行います。OfferUpBot は、OfferUp へのアクセス、ログイン状態、永続化、ブラウザ操作、リトライ、重複防止、外部検証を担当します。

エージェント向けガイダンス

会話履歴がないエージェントは AGENTS.md から開始します。OfferUp の直接実行には skills/operating-offerupbot/SKILL.md を、物理商品を最初から最後まで所有する場合は skills/operating-seller-operator/SKILL.md を、結果に影響する画像推論には skills/inspecting-visual-evidence/SKILL.md を使用します。各スキルは、タスクに必要な場合にのみ、より深い資料を読み込みます。

ランタイムの方針

デフォルトのインターフェースは オンデマンド MCP stdio です。

agent launches OfferUpBot
        ↓
MCP tools execute against shared SQLite state and browser profile
        ↓
agent disconnects
        ↓
OfferUpBot exits

状態は SQLite と専用の OfferUp ブラウザプロファイルに保持されます。デフォルトのプロセスは、スケジューラ、HTTP リスナー、バックグラウンドモニターを起動しません。

継続的な monitor モードはオプションで、デフォルトではオフです。run:due は期限切れのウォッチを明示的に一度だけキャッチアップして終了します。

要件

  • 認証付き操作には Google Chrome がインストールされた macOS

  • Node.js 22 以降

  • pnpm

Docker、外部データベース、Redis、個別管理のランタイムサービスは不要です。

インストールとビルド

git clone https://github.com/yinkev/OfferUpBot.git
cd OfferUpBot
pnpm install
pnpm build

開発用 MCP エントリポイントを実行します:

pnpm mcp

ビルド済みエントリポイントを実行します:

pnpm start

デフォルトのデータディレクトリは次のとおりです:

~/.offerupbot/
├── state.sqlite
├── browser-profile/
└── agents.json          # only after restricted agents are created

分離が必要な場合は、OFFERUPBOT_DATA_DIR で上書きします。

OfferUp ログイン

pnpm auth:login

専用の Chrome ウィンドウが開きます。OfferUp に直接認証情報を入力してください。OfferUp の認証済みアカウント問い合わせが実際のアカウント ID を返した場合にのみ、ログインが受け付けられます。認証情報がチャットで要求されたり、SQLite に保存されたりすることはありません。

MCP 設定

pnpm build の後、ビルド済みの stdio エントリポイントをエージェントホストに指定します:

{
  "mcpServers": {
    "offerupbot": {
      "command": "node",
      "args": [
        "/absolute/path/to/OfferUpBot/dist/src/index.js"
      ],
      "env": {
        "OFFERUPBOT_DATA_DIR": "/absolute/path/to/.offerupbot"
      }
    }
  }
}

エージェントトークンがない場合、ローカルの stdio プロセスは信頼されたフルオペレータとして実行されます。

エージェントに限定された権限を与える場合、制限付き ID を生成します:

pnpm agent:create -- \
  --id research-agent \
  --name "Research Agent" \
  --permissions market.read,events.read,watch.manage

返されたトークンを、そのエージェントの MCP 環境に OFFERUPBOT_AGENT_TOKEN として保存します。OfferUpBot は SHA-256 ハッシュのみを保存します。

エージェントツール

Tool

Purpose

Permission

offerup.health

ローカルランタイムとキャッシュ済みセッションの健全性

none

offerup.auth_status

現在の OfferUp アカウントの ID と権限を検証する

account.read

offerup.research_market

検証済みの OfferUp フィルタで検索

market.read

offerup.inspect_listing

リスティングの完全な証跡を取得。download_photos で指定した順序の写真を読み取り可能なローカルファイルとして任意にキャッシュ

market.read

offerup.watch_market

ウォッチの作成、確認、一時停止、再開、削除、実行

watch.manage

offerup.run_due

期限を過ぎた全ウォッチを一度だけ実行

watch.manage

offerup.next_events

永続イベントの読み取りと確認(acknowledge)

events.read

offerup.sync_listings

アクティブ、アーカイブ、保存済みのアカウント状態を同期

account.read

offerup.sync_inbox

受信箱、スレッド、および購入者メッセージの変更を同期

account.read

offerup.get_thread

1 件の完全な会話とリスティングコンテキストを取得

account.read

offerup.send_message

冪等で外部検証済みのメッセージを 1 件送信

message.send

offerup.validate_listing

現在のコンシューマー向けリスティング契約を検証

none

offerup.publish_listing

リスティングを公開・検証

listing.publish

offerup.update_listing

サポートされているフィールドを編集・検証

listing.update

offerup.close_listing

売約済みにするかアーカイブし、アカウント状態を検証

listing.close

skills/operating-offerupbot/SKILL.md から開始してください。その隣の REFERENCE.md と WORKFLOWS.md に、詳細な契約と手続きが記載されています。

セラーオペレータツール

実行ツールの上位に、物理商品をエンドツーエンドで所有するエージェント向けの第 2 の MCP サーフェスがあります。ケース・商品受入、写真と来歴が追跡された証跡、OCR・決定的な抽出と同一性解決、証跡の十分性に関する確認、比較リサーチ、価格決定と処分判断、検証済みの公開・クローズを含む裏付けのある下書き、購入者分類、オファー、優先予約、予約(競合チェック済み、冪等なリマインダー付き)、期限付きタスクのオペレータループ、引き渡しの記録、およびライフサイクル分析をカバーする 30 個の seller.* ツールがあります。

権限: seller.read(読み取り)、seller.write(ドメイン書き込み。公開・クローズには追加で listing.publish / listing.close が必要)、seller.communicate(購入者オペレーション)。メッセージは引き続き検証済みの offerup.send_message を経由します。skills/operating-seller-operator/SKILL.md から開始してください。その隣の REFERENCE.md と WORKFLOWS.md に、証跡・マーケット・購入者・ライフサイクルのガイダンスが記載されています。

ID と書き込み

OfferUp は 2 つの異なるリスティング識別子を使用します。

  • listing_id: パブリック詳細、会話、検証、編集ミューテーション入力に使用される UUID。

  • item_id: /selling、売約済み、アーカイブ操作で使用される数値のセラー在庫 ID。

重要なツールには、必ず永続的な冪等キーが必要です。タイムアウトやクラッシュ後の再試行では同じキーを再利用してください。キーを変更すると、リカバリ試行が外部アクションの重複になることがあります。

明示的なスケジュールモード

期限超過の全ウォッチを一度だけ実行して終了します:

pnpm run:due

連続ポーリングが意図的に必要な場合にのみ、フォアグラウンドでウォッチスケジューリングを維持します:

pnpm monitor

monitor は pnpm mcp、pnpm start、インストール、ログインでは起動されません。これを終了すると連続ポーリングは停止します。後から run:due または MCP の offerup.run_due を呼び出すことで、永続化されたウォッチ状態からキャッチアップできます。

ハンドオフサーフェス(opt-in)

pnpm handoff は、人間が直接対応する大人のタッチポイントである対面ハンドオフのための小さなフォアグラウンド専用 HTTP サーフェスを起動します。期限付き・未処理のハンドオフカード(購入者、合意価格、予約、付属品、不具合、支払い方針、予備購入者帯)を GET / で一覧表示し、GET /api/handoffs を公開し、同じ SQLite 状態に POST /api/handoffs/:itemId/result で結果を記録します。

127.0.0.1 にバインドし(OFFERUPBOT_HANDOFF_HOST / OFFERUPBOT_HANDOFF_PORT で上書き可能)、OFFERUPBOT_HANDOFF_TOKEN からの bearer トークンを要求します。未設定の場合は起動時にトークンを生成して一度だけ出力します。monitor funktionen、これも他の何からも起動されません。デフォルトのランタイムはリスナーなしのオンデマンド MCP stdio のままです。

失敗の意味論

書き込みが完了とみなされるのは、そのレスポンスが verified: true を含む場合のみです。

重要なコード:

  • OFFERUP_SESSION_EXPIRED / AUTH_REQUIRED: 認証済み作業の前に完全な OfferUp ログインが必要。

  • RESOURCE_BUSY: 別のプロセスがアカウントまたはブラウザのリースを保持している。同じ冪等キーを用いて後で再試行。

  • RESOURCE_LOCK_LOST: 書き込みが完了したと想定しない。再試行する前に、関連する読み取りまたは同期ツールを呼び出す。

  • IDEMPOTENCY_CONFLICT: 同じキートが異なる意図で提示された。呼び出し側エージェントの状態を調整する。

  • OFFERUP_FILTER_MISMATCH: OfferUp が検索制約を黙って無視した。返されたセットを有効な比較対象として使用しない。

  • AUTO_CATEGORY_MISMATCH: OfferUp が提出されたドラフトとは異なるカテゴリを強制した。

  • CATEGORY_PATH_NOT_TERMINAL: パスが選択可能な最終カテゴリではなく、親カテゴリで停止した。

検証

日常的な検証:

pnpm test
pnpm typecheck
pnpm build

設定された OfferUp プロファイルとパブリックサイトに対する読み取り専用ライブ検証:

OFFERUPBOT_LIVE_TESTS=1 pnpm exec tsx --test \
  tests/account/live.test.ts \
  tests/auth/live.test.ts \
  tests/offerup/public/live.test.ts

安全なインターセプト書き込み契約の受け入れテスト:

OFFERUPBOT_LIVE=1 pnpm exec tsx --test --test-concurrency=1 \
  tests/messages/live-direct.test.ts \
  tests/listings/live-browser.test.ts \
  tests/listings/live-close.test.ts

インターセプトされたテストは、ライブの OfferUp の UI に対して現在のメッセージ、コンシューマー公開、編集、メディアアップロード、売約済み、アーカイブの各要求経路を、重要なミューテーションをローカルで満たしながら実行します。実際のリスティングを作成・変更・売約・アーカイブはしません。

現在の受け入れ境界

実装・テスト済みの範囲は、コード、パブリック読み取り、認証済み読み取り、現在の Web メッセージミューテーション、コンシューマー公開・編集 UI コントラクト、クローズミューテーションです。制御されたインメモリエージェントテストは、リサーチから公開、受信箱、メッセージ、更新、クローズまでをカバーします。

2026 年 8 月 24 日、設定された受け入れアカウントに対して、指定された実リスティングのライフサイクルが完了しました。Philips Norelco BG7030/49 は 6 枚の写真で公開し、外部検証を行い、$60 から $55 に更新して New を維持したまま再検証し、その後アーカイブして認証済み在庫で UNLISTED として検証しました。この実行で 2 つの実稼働障害が検出され、修正されました: 外側の投稿ダイアログが表示されたままの終端カテゴリ選択と、価格だけの編集時ケットあっている場合に誤ったジャンル条件が入る問題。

残された実メッセージの transport ゲートはその日のうちに完了しています: offerup.send_message は直接アダプタを通して $50 の現金オファーを送信し、返されたメッセージ ID を同一スレッドで読み直し、認証済みの通知ディジットでその斯会話を確認しました。後日販売者から、「Its a pokemon center etb.」と返信があり、別の推論の失敗が明らかになりました。リスティングの最初の写真はポケモンセンター限定バリエーションを識別できるものでしたが、エージェントは標準の ETB を評価していました。TCGplayer の正確な商品 692949 は約 $120 で、$50 のオファーは正確な市場価格の 42% 程度—78% ではありません。exactly-once の書き込み承認は合格しましたが、バリアントの特定、価値算定、ターゲット選択が失敗しました。修正された postmortem は docs/acceptance/2026-08-24-real-message-send.md にあります。

規定された重要な書き込み転送の受け入れは両方完了しました。将来の実際の書き込みには、明示的に指定されたリスティングまたは会話が引き続き必要です。再現可能なリグレッションテストは引き続き本人確認されたままであり、任意のアカウントオブジェクトを変更してはなりません。

セラーオペレータレイヤー(2026-08 追加)

この実行レイヤーの上に、セラーオ店コアレータシステムがあります。正規の物理商品と来歴が追跡された証跡、ID 解決、修繕済みと活発な比較を分離したマーケット・価格研究、ゲート付きのリスティングオーケストレーション、バイヤー、オファー、予約、アポイントの状態、ハンドオフの結果記録、再構築可能なケースコンテキストを備えています。これはプロダクションランに完全に配線されており、起動時にすべてのスキーマを保証、runtime.runDue() がウォッチとセラーのタスクを一度だけキャッチアップして実行し、アカウントリスティングの同期がビュー、ディスカッション、価格の時系列を追記しています。エージェントには上記の seller.* ツールとして公開されます。

オプションの統合(デフォルトはすべてオフ):

  • OFFERUPBOT_READ_ONLY=1 — すべての重要な OfferUp 書き込みをブロックします(公開 / 更新 / クローズ / 送信、オーケストレータも含む)。

  • OFFERUPBOT_EBAY_CLIENT_ID / OFFERUPBOT_EBAY_CLIENT_SECRET — eBay の比較ソースを有効にします(求約中の貼り付け額 + 完売、公式 API)。これらがない場合、ソースは利用不可と報告し、比較対象は空のままです。スクレイピングはありません。

  • OCR は利用可能な場合は macOS Vision を介して実行され(darwin + now "plus"ノー)、その他の環境では決定的抽出のみに縮小されます。

アウトカム分析(src/analytics)は、販売された商品と非販売商品の両方を対象に完全なメトリックセットを計算し、完了したアウトカムに基づくカテゴリ事前分布が価格設定と処分にフィードバックされます(有界、サンプルサイズで縮小、決定理由に記録)。レイヤーマップと不変条件については docs/seller-operator-architecture.md を、ビルド状況については docs/seller-operator-tracker.md を、また、モックされた外部書き込み(実際のマーケットプレイス変更なし)による制御された完全ライフサイクル受け入れについては tests/e2e/seller-operator.test.ts を参照してください。

Maintenance

ActivityMaintained
ResponsivenessSyncing

Related MCP Connectors