OfferUpBot
OfferUpBot
OfferUpBot es la capa de ejecución de OfferUp para agentes externos. Los agentes identifican artículos, eligen precios, redactan el texto y deciden las respuestas. OfferUpBot se encarga del acceso a OfferUp, del estado de sesión, de la persistencia, del trabajo en el navegador, de los reintentos, de la prevención de duplicados y de la verificación externa.
Guía del agente
Los agentes que trabajan sin historial de conversación comienzan en AGENTS.md. La ejecución directa de OfferUp utiliza skills/operating-offerupbot/SKILL.md; la gestión integral de artículos físicos utiliza skills/operating-seller-operator/SKILL.md; el razonamiento de imágenes con implicaciones utiliza skills/inspecting-visual-evidence/SKILL.md. Cada skill carga material más profundo solo cuando la tarea lo requiere.
Decisión del runtime
La interfaz predeterminada es MCP stdio bajo demanda:
agent launches OfferUpBot
↓
MCP tools execute against shared SQLite state and browser profile
↓
agent disconnects
↓
OfferUpBot exitsEl estado sobrevive en SQLite y en el perfil de navegador dedicado de OfferUp. El proceso predeterminado no inicia un programador, un listener HTTP ni un monitor en segundo plano.
El modo continuo monitor es opcional y está desactivado por defecto. run:due ejecuta una única pasada explícita de puesta al día y sale.
Requisitos
macOS con Google Chrome instalado para operaciones autenticadas
Node.js 22 o posterior
git
No se necesita Docker, base de datos externa, Redis ni un servicio de ejecución gestionado de forma separada.
Instalación y compilación
git clone https://github.com/yinkev/OfferUpBot.git
cd OfferUpBot
pnpm install
pnpm buildEjecutar el punto de entrada de MCP de desarrollo:
pnpm mcpEjecutar el punto de entrada compilado:
pnpm startEl directorio de datos predeterminado es:
~/.offerupbot/
├── state.sqlite
├── browser-profile/
└── agents.json # only after restricted agents are createdSe debe sustituir con OFFERUPBOT_DATA_DIR cuando se requiera aislamiento.
Inicio de sesión en OfferUp
pnpm auth:loginSe abre una ventana de Chrome dedicada. Introduce las credenciales directamente en Propia. El inicio de sesión solo se acepta cuando la consulta de cuenta autenticada de OfferUp devuelve un identificador de cuenta real. Las credenciales no se piden por chat ni se almacenan en SQLite.
Configuración de MCP
Después de pnpm build, apunta el host del agente al punto de entrada stdio compilado:
{
"mcpServers": {
"offerupbot": {
"command": "node",
"args": [
"/absolute/path/to/OfferUpBot/dist/src/index.js"
],
"env": {
"OFFERUPBOT_DATA_DIR": "/absolute/path/to/.offerupbot"
}
}
}
}Sin token de agente, el proceso stdio local se ejecuta como el operador completo de confianza.
Crea una identidad restringida cuando un agente deba recibir una autoridad más limitada:
pnpm agent:create -- \
--id research-agent \
--name "Research Agent" \
--permissions market.read,events.read,watch.manageGuarda el token devuelto en el entorno MCP de ese agente como OFFERUPBOT_AGENT_TOKEN. OfferUpBot almacena únicamente su hash SHA-256.
Herramientas del agente
Herramienta | Propósito | Permiso |
| Salud del runtime local y de la sesión en caché | none |
| Verificar la identidad y las capacidades actuales de la cuenta OfferUp |
|
| Búsqueda con filtros validados de OfferUp |
|
| Evidencia completa del esta; opcionalmente guardar fotos ordenadas como archivos locales legibles con |
|
| Crear, inspeccionar, pausar, reanudar, eliminar o ejecutar una vigilancia |
|
| Ejecutar una vez todas las vigilancias vencidas |
|
| Leer y confirmar la recepción de eventos duraderos |
|
| Sincronizar el estado de la cuenta activo, archivado y guardado |
|
| Sincronizar los hilos de la bandeja de entrada y los cambios en los mensajes del comprador |
|
| Recuperar una conversación completa y el contexto del anuncio |
|
| Enviar un único mensaje idempotente y verificado externamente |
|
| Validar el contrato actual de anuncio de consumidor | none |
| Publicar y verificar un anuncio |
|
| Editar y verificar los campos admitidos |
|
| Marcar como vendido o archivar y, a continuación, verificar el estado de la cuenta |
|
Comienza en skills/operating-offerupbot/SKILL.md; sus adyacentes REFERENCE.md y WORKFLOWS.md contienen los contratos y procedimientos detallados.
Herramientas de seller-operator
Sobre la capa de herramientas de ejecución hay una segunda superficie MCP para los agentes que gestionan artículos físicos de principio a fin: 30 herramientas del espacio seller.* que cubren la toma de casos/artículos, fotografías y evidencia con trazabilidad de procedencia, extracción por OCR/determinista y selección de identidad, aclaraciones de suficiencia de la evidencia, investigación de comparables, decisiones de precio y disposición, borradores de anuncio fundamentados con publicación/cierre verificados, clasificación de compradores, ofertas, reservas exclusivas, citas (con comprobación de conflictos y recordatorios idempotentes), el bucle de tareas pendientes del operador, registro de entrega y analíticas del ciclo de vida.
Permisos: seller.read (lecturas), seller.write (escrituras de dominio; publicar/cerrar exigen además listing.publish/listing.close), seller.communicate (operaciones con compradores). Los mensajes siguen saliendo a través del verificado offerup.send_message. Comienza en skills/operating-seller-operator/SKILL.md; sus adyacentes REFERENCE.md y WORKFLOWS.md guardan la guía sobre evidencia, mercado, compradores y ciclo de vida.
IDs y escrituras
OfferUp utiliza dos identificadores distintos de anuncio:
listing_id: UUID usado para el detalle público, las conversaciones, la verificación y la entrada de mutaciones de edición.item_id: identificador numérico del inventario de vendedor que usan las operaciones de/selling, marcado como vendido y archivado.
Toda herramienta con efectos consecuentes requiere una clave de idempotencia persistente. Reutiliza la misma clave después de un timeout o un bloqueo. Cambiar la clave puede convertir una decisión de recuperación en una acción externa duplicada.
Modos de programación explícita
Ejecuta todas las vigilancias atrasadas una vez y sale:
pnpm run:dueMantén con vida la programación de vigilancias en primer plano solo cuando sea necesario explícitamente un sondeo continuo:
pnpm monitormonitor nunca se inicia mediante pnpm mcp, pnpm start, la instalación ni el inicio de sesión. Al cerrarlo de detiene el sondeo continuo. Una llamada posterior a run:due es la interfaz MCP API offerup.run_due se pone al día desde el estado de vigilancia persistido.
Instalación de entrega (opt-in)
pnpm handoff inicia una pequeña superficie HTTP solo de primer plano, con el único punto de contacto humano: la entrega en persona. Muestra las tarjetas de entrega pendientes/accedidas (comprador, precio acordado, cita, accesorios, defectos, política de pago, compradores de respaldo) en GET /, expone GET /api/handoffs y registra el resultado a través de POST /api/handoffs/:itemId/result sobre el mismo estado SQLite.
Se vincula a 127.0.0.1 (se puede sobrescribir con OFFERUPBOT_HANDOFF_HOST/OFFERUPBOT_HANDOFF_PORT) y requiere un token bearer de OFFERUPBOT_HANDOFF_TOKEN; si no está definido, se genera un token al inicio y se imprime una vez. Igual que monitor, nunca lo inicia nada más: el entorno predeterminado sigue siendo MCP stdio sin listener.
Semántica de fallos
Una escritura se considera completa solo cuando su respuesta contiene verified: true.
Códigos importantes:
OFFERUP_SESSION_EXPIRED/AUTH_REQUIRED: completa el inicio de sesión en OfferUp antes de hacer trabajo autenticado.RESOURCE_BUSY: otro proceso tiene la cuenta o el arrendamiento del navegador; reintenta más tarde con la misma clave de idempotencia.RESOURCE_LOCK_LOST: no asumas que la escritura se completó; llama a la herramienta de lectura o paso de sincronización correspondiente antes de reintentar.IDEMPOTENCY_CONFLICT: la misma clave se ha presentado con intención diferente; concilia el estado del uid que llama.OFFERUP_FILTER_MISMATCH: OfferUp ha ignorado silenciosamente una restricción de búsqueda; no uses el conjunto devuelto como comparables válidos.AUTO_CATEGORY_MISMATCH: OfferUp ha impuesto una categoría distinta de la del borrador presentado.CATEGORY_PATH_NOT_TERMINAL: la ruta se detuvo en una categoría inicial, no en una final desconectable.
Verificación
Verificación rutinaria:
pnpm test
pnpm typecheck
pnpm buildAceptación en vivo de solo lectura contra el perfil de OfferUp configurado y el sitio público:
OFFERUPBOT_LIVE_TESTS=1 pnpm exec tsx --test \
tests/account/live.test.ts \
tests/auth/live.test.ts \
tests/offerup/public/live.test.tsAceptación segura de contrato de escritura interceptado:
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.tsLas pruebas de interceptación ejercitan las rutas de uso actual: mensaje, publicación de consumidor, edición, subida de medios, marcado como vendido y archivado, contra la interfaz OfferUp en vivo, mientras satisfacen la consonante mutaciones de forma local. No crear, ni modificar, ni vender, ni archivarán un anuncio del real.
Límite de aceptación actual
El conjunto, las lecturas públicas, las lecturas autenticadas, las mutaciones actuales de mensajes web, los contratos de la interfaz de publicación/edición de consumidor y las mutaciones de cierre, toda está implementando y probado. Un control de agente en memoria cubre la investigación a publicación, bandeja de entrada, mensaje, actualización y cierre.
Un ciclo real completo de una listing designado se hizo el 24 de agosto de 2026 contra la cuenta de aceptación configurada: un Philips Norelco BG7030/49 se publicó con seis fotos, se verificó externamente, se cambió de $60 a $55 y se volvió a verificar conservando su condición Nueva; después se archivo y se verificó en el inventario autenticado como UNLISTED.` El gestor dejó expuestos y cerrados dos defectos en vivo: la selección de la categoría terminal mientras el diálogo externo de publicación siga visible, y la pérdida de condición en las ediciones solo de precio.
La puerta de transporte real restante se completó el mismo día: offerup.send_message envió una oferta en efectivo de 50 USD mediante el adaptador directo, el ID de mensaje devuelto se releó en la conversación exacta y la sincronización de la bandeja de entrada autenticada confirmó la conversación. Luego de que el vendedor respondiera «Its a pokemon center etb», destaca una falla de razonamiento independiente. En la primera foto del anuncio se veía la variante exclusiva de Pokémon, pero el agente había valorado la oferta estándar ETB. El producto exacto de TCGplayer 692949 rondaba los 120 USD, por lo que la oferta de 50 USD era aproximadamente el 42 % del precio exacto de mercado, no el 78 %. Pasó la escritura exactamente una vez; fallaron la identificación de la variante, la valoración y la selección del objetivo. El inficent que se inciste de 2026: documentos/
Aceptada.
Las dos aceptaciones de transporte de escritura consecutiva designadas están completas. En el futuro, las escrituras reales siguen exigiendo un anuncio o conversación explícitamente designado; las pruebas de regresión línea restante siguen interceptadas y deben no mutar objetos de la cuenta arbitrarios.
Capa de-operator (añadida en 2026-08)
Por encima de esta capa de ejecución está el sistema operator-seller: artículos físicos canonicos con evidencia de procedencia, resolución de identidad, investigación de mercado/precios con separación de comparables realizados vs activos, orquestación de publicación con compuertas, estado de compradores/ofertas/reservas/citas, registro de resultado de entrega y la reconstructable del caso. Está totalmente integrado en el runtime de producción (todos los esquemas asegurados al arrancar; runtime.runDue() ejecuta una el pase de puesta al día de vigilancia y tareas de vendedor; la sincronización de los anuncios del T está expuesto una serie de vistas/discusiones/precio) y se expone a los agentes a través de las herramientas seller.* de arriba.
Integrations optional, all off by default:
OFFERUPBOT_READ_ONLY=1— bloquea toda escritura consequential de OfferUp (publicación/actualización/cierre/envío, incluida la ruta del orquestador).OFFERUPBOT_EBAY_CLIENT_ID/OFFERUPBOT_EBAY_CLIENT_SECRET— device las fuentes de comparación de eBay (pedido activo + vendidos, APIs oficiales). Sin ellas, las fuentes informan no disponible y los comparables quedan vacíos; no se scrapea nada.El OCR se ejecuta a través de macOS Vision cuando está disponible (darwin + métodoscript) y se degrada, en el resto, a extracción determinista únicamente.
La analítica de resultados (src/analytics) calcula el conjunto completo de métricas tanto sobre los artículos vendidos como sobre los no vendidos, y las prioris de categoría derivadas de los resultados completados retroalimentan la fijación de precios y la disposición (acotadas, reducidas por tamaño de muestra, registradas en la justificación de la decisión). Véase docs/seller-operator-architecture.md para el mapa de capas y los invariantes, docs/seller-operator-tracker.md para el estado de compilación, y tests/e2e/seller-operator.test.ts para el caso de aceptación controlada del ciclo de vida completo (escrituras externas simuladas — sin mutaciones reales en el marketplace).
This server cannot be installed
Maintenance
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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