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 выполняет один явный навёрстывающий проход и завершается.

Требования

  • macOS с установленным Google Chrome для авторизованных операций

  • 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 работает как доверенный полный оператор.

Создайте ограниченную сущность, когда агенту нужны более узкие полномочия:

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

Состояние локального рантайма и кэшированных сессий

нет

offerup.auth_status

Проверка текущей учётной записи и возможностей OfferUp

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

Читать и подтверждать долговечные события

events.read

offerup.sync_listings

Синхронизировать активное, архивное и охранённое состояние аккаунта

account.read

offerup.sync_inbox

Синхронизировать потоки входящих и изменения в сообщениях покупателя

account.read

offerup.get_thread

Получить один полный диалог и контекст объявления

account.read

offerup.send_message

Отправить одно идемпотентное, внешне проверенное сообщение

message.send

offerup.validate_listing

Проверить текущий контракт объявления для покупателя

нет

offerup.publish_listing

Опубликовать и проверить объявление

listing.publish

offerup.update_listing

Отредактировать и проверить поддерживаемые поля

listing.update

offerup.close_listing

Пометить как проданное или архивировать, затем проверить состояние аккаунта

listing.close

Начните с skills/operating-offerupbot/SKILL.md; в соседних REFERENCE.md и WORKFLOWS.md содержатся подробные контакты и процедуры.

Инструменты продавца-оператора

Над инструментами исполнения находится второй слой интерфейса MCP для агентов, которые владеют физическими товарами и администрируют их на всём пути: 30 инструментов seller.*, покрывающих приём заявок и предметов, фотографий и доказательств с отслеживаемым происхождением, OCR/детерминированное распознавание и выбор идентичности, уточнение достаточности доказательств, исследование рыночных аналогов, решения о цене и о судьбе предмета, обоснованные черновики объявлений с проверенной публикацией и закрытием, классификацию покупалиц, предложения, эксклюзивные бронирования, встречи (с проверкой конфликтующих событий и идемпотентными напоминаниями), вероятностный цикл оператора по отложенным задачам, запись результатов передачи и аналитику жизненного цикла.

Права: seller.read (чтение, просмотр), seller.write (доменные записи; публикация и закрытие также требуют listing.publish и listing.close), seller.communicate (действия с покупателями). Сообщения по-прежнему проходят через проверяемый offerup.send_message. Начните с skills/operating-seller-operator/SKILL.md; в соседних REFERENCE.md и WORKFLOWS.md содержится руководство по доказательствам, рынку, покупателям и жизненному циклу.

Идентификаторы и записи

OfferUp использует два разных идентификатора объявлений:

  • listing_id: UUID, используемый для публичных данных, диалогов, проверки и передачи в мутации редактирования.

  • item_id: числовой идентификатор в инвентаре продавца, используемый в /selling, при отметке как проданное и при архивации.

Каждый значимый инструмент требует устойчивый идемпотентный ключ. Используйте тот же ключ повторно после таймаута или сбоя. При смене ключа попытка восстановления может превратиться в дублирующее внешнее действие.

Явные режимы планирования

Выполните все просроченные наблюдения один раз и завершитесь:

pnpm run:due

Удерживаете работу планировщика наблюдений на переднем плане только тогда, когда намеренно нужно непрерывное опрашивание:

pnpm monitor

Режим monitor никогда не запускается командами pnpm mcp, pnpm start, при установке или входе. Его закрытие останавливает непрерывный опрос. Последующий вызов run:due или MCP-команды offerup.run_due догоняет состояние из сохранённых наблюдений.

Поверхность передачи (по желанию)

Команда pnpm handoff запускает маленькую HTTP-поверхность на переднем плане для единственной человеческой точки: личная передача. Она показывает карточки передачи, ожидающие выполнения (покупатель, согласованная цена, назначенная встреча, аксессуары, дефекты, политика оплаты, резервные покупалители) на GET /, предоставляет GET /api/handoffs и записывает результат по через POST /api/handoffs/:itemId/result в то же SQLite-состояние.

Она привязана к 127.0.0.1 (переопределяется переменными OFFERUPBOT_HANDOFF_HOST/OFFERUPBOT_HANDOFF_PORT) и требует bearer-токен из OFFERUPBOT_HANDOFF_TOKEN; если токен не установлен, он генерируется и печатается один раз при запуске. Как и monitor, она никогда не запускается чем-либо ещё: исполнение по умолчанию остаётся 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

Перехваченные тесты прогоняют текущие пути запросов: сообщение, публикация для покупателя, редактирование, загрузка медиа­файлов, отметка «продано» и архивация — против живой UI OfferUp, выполняя значимые мутации локально. Они не создают, не модифицируют, не продают и не архивируют реальные объявления.

Текущая границ обжатия

Код, публичные обращения, авторизованные чтения, текущие веб-мутации сообщений, контракт публикации/редактирования для покупательских объявлений и мутации закрытия реализованы и протестированы. Контролируемый агент-тест в памяти покрывает исследования, публикацию, входящие, сообщение, обновление и закрытие.

Целевой реальный цикл объявления был выполнен 24 июля 2026 года на вой настроенном приёмочном аккаунте: Philips Norelco BG7030/49 был опубликован с шестью файлами, подтверждён внешней проверкой, обновлён с $60 до $55 и проверен повторно без потери состояния New, затем архивирован и проверен в авторизованном инвентаре как UNLISTED. Прогон показал и закрыл два живых дефекта: выборвыбор информации о категории при внешне видимом диалоге публикации, и потерю состояния при правке только цены.

Оставшийся реальный транспортный шар был закрытия в тот же день: offerup.send_message отправил одно предложение $50 наличными через прямой адаптер, возвращённый ID сообщения был перечитан в этом же диалоге и авторизованная синхронизация входящих подтвердила переписку. Продавец позже ответил: «Это покемонический центр по ошибке,» — при выяснении неверной логики. Первое фото объявления явно идентифицировало эксклюзивного варианта Pokémon Center, но агент оценивал стандартный ETB. Точный продукт в TCGplayer 692949 был около $120, поэтому предложение $50 составляло около 42% от точной рыночной цены — не 78%. Проверка «ровно один раз» прошла, провалилисьей идентификация варианта, оценка и выбор цели. Полный анализ в docs/acceptance/2026-08-24-real-message-send.md.

Оба назначенных транспортных приёма значущих записей завершены. Будущие реальные записи по-прежнему требуют явно выделенного объявления или диалога; повторяемые регрессы остаются перехваченными и не должны изменять произвольные объекты аккаунта.

Слой продавца-оператора (добавлен в 2026-08)

Поверх исполнительного слоя находится система продавца-оператора: канонические физические позиции с отслеживаемым происхождением доказательств, разрешение сущностных личностей, исследование рынка и цен с разделением реализованных и активных аналогов, управляемая публикационная оркестрация, состояние покупателя/предложения/брони/встречи, запись результатов передачи и восстанов парируемый контекст дела. Она полностью включена в промышленный рантайм (вse schemas at startup; runtime.runDue() выполняет catch-up проход по наблюдениям и задачами продавца; синхронизация листингов добавляет ряды views/discussions/prices) и доступна через инструменты seller.* выше.

Дополнительные интеграции — все по умолчанию выключены:

  • OFFERUPBOT_READ_ONLY=1 — блокирует любые значимые записи OfferUp (опубликовать, обновить, закрыть, отправить — либо через организацию).

  • OFFERUPBOT_EBAY_CLIENT_ID / OFFERUPBOT_EBAY_CLIENT_SECRET — включает источниканный eBay-аналоги (активные цены и проданные, официальые API). При отсутствии эти источники сообщают о недоступности, поиск остаётся пустым; ничего не скрапится.

  • OCR выполняется через macOS Vision, когда она есть (darwin + osascript), и в остальных случаях программно падает на детерминированное извлечение.

Аналитика исходов (src/analytics) вычисляет полный набор метрик как для проданных, так и для непроданных товаров, а категориальные априорные распределения (ограниченные, скорректированные по размеру выборки и фиксируемые в обосновании решения), полученные из завершённых исходов, используются в ценообразовании и распоряжении товарами. См. docs/seller-operator-architecture.md для карты слоёв и инвариантов, docs/seller-operator-tracker.md для статуса сборки и tests/e2e/seller-operator.test.ts для контролируемого приёмочного теста полного жизненного цикла (мокированные внешние записи — без реальных мутаций маркетплейса).

-
license - not tested
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Runtime permission, approval, and audit layer for AI agent tool execution.

  • Reliable async execution for agent tool calls: schema gating, retries, idempotency, audit trail.

  • A witness layer for AI agent tool calls.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yinkev/OfferUpBot'

If you have feedback or need assistance with the MCP directory API, please join our Discord server