Subito Monitoring
Sends direct Telegram notifications for new matching listings from monitored Subito.it searches, with queued delivery that persists across restarts and watch changes.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Subito Monitoring monitor ThinkCentre i5 listings under €150 every five minutes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Subito Monitoring
A single-user, open source Subito.it search and watch service: autonomous polling, SQLite state and delivery queue, direct Telegram notifications, and eight MCP tools for Hermes or any MCP client. No LLM, dashboard, external database or Vinted runtime. MIT licensed; the monitoring core is adapted from Vinted Monitoring with attribution.
Integration status (2026-11-03): limited live validation passed. The production
provider now uses ordinary system curl, which succeeded on macOS and in the Linux
container. Page 2, all four orders, Motori, Immobili, valid empty results and a narrow
Market silent baseline/rescan were checked against actual Subito responses. Chrome
also confirmed page 2 and the site's real ordering URL. No Telegram message was sent;
long-running availability is not guaranteed. See verification.
Subito's terms prohibit automated extraction without permission. Network access is
disabled by default (SM_UPSTREAM_ENABLED=false). Obtain appropriate permission
before enabling it; this switch does not grant permission or bypass a block.
401/403/challenges persistently suspend access until an administrator investigates.
Quick start with Docker
Public image: ghcr.io/alexxanddr/subito-monitoring:latest, Linux amd64/arm64.
Use a version or commit tag for a repeatable deployment; see publishing.
The image includes Python, curl and CA certificates. Chrome is not required.
git clone https://github.com/Alexxanddr/subito-monitoring.git
cd subito-monitoring
cp .env.example .env
# Edit .env privately before starting:
# - replace SM_HTTP_TOKEN with a random secret of at least 32 characters;
# - set both Telegram variables for watches, or leave both unset for search only;
# - set SM_UPSTREAM_ENABLED=true only after reviewing Subito access permission.
chmod 600 .env
docker compose pull
docker compose up -d --no-build
curl --fail http://127.0.0.1:8000/health/readyThe example bearer value is intentionally invalid: startup refuses the unchanged
placeholder. Compose binds HTTP to loopback on port 8000 and mounts a persistent
named volume at /data. Never use docker compose down -v on real state.
Set actual service DNS in SM_ALLOWED_HOSTS before connecting remote MCPHub.
Every MCP call requires the bearer token; health probes contain booleans only.
Readiness proves the polling task is running, not that Subito scans are fresh.
Related MCP server: Avito Monitor MCP
Local installation and development
Python 3.12–3.14, system curl >=8.4, and a local filesystem with POSIX locks
are required (Linux/macOS). On Debian/Ubuntu install curl and ca-certificates;
macOS ships curl, which can be checked with curl --version.
uv sync --frozen --no-editable --extra dev
uv run --no-sync subito-monitoringThe default transport is MCP stdio, state is data/monitor.sqlite3, and Subito
network access is off. Inject environment settings through your supervisor/client;
the local CLI does not automatically load .env. Stdio owns the database until
stdin closes. For Hermes-independent monitoring use supervised HTTP or Compose.
Do not run a second stdio owner alongside the HTTP service on the same database.
To build the image locally instead of pulling the published image:
docker compose up --build -dSee all environment variables and MCP examples and backup, restore, upgrades and troubleshooting.
MCP tools
Tool | Effect |
| Immediate one native page; no watch, state baseline or Telegram send |
| Persistent query, silent initial complete baseline |
| Queries, baseline, errors and last successful scan |
| Replace query or change name/interval; query change resets baseline |
| Change polling; queued deliveries remain |
| Delete watch; retain global history and queued deliveries |
| Freshness, incomplete coverage, suspension and delivery backlog |
“Show the 10 newest ThinkCentre i5 under EUR 150” → search_items:
{"query":{"text":"ThinkCentre i5","section":"market","max_price":"150","order":"newest_first"},"limit":10,"page":1}“Monitor ThinkCentre i5 under EUR 150 every five minutes” → create_watch:
{"name":"ThinkCentre i5","query":{"text":"ThinkCentre i5","section":"market","max_price":"150","order":"newest_first"},"interval_seconds":300}Watches default to 600 seconds, validated 60–604800. Supported query orders:
newest_first, relevance, price_low_to_high, price_high_to_low; watches require
newest_first. Text searches Italy sale listings. section selects market,
motori or immobili; default all combines known supported categories and
excludes Lavoro, including jobs, services and work equipment. marketplace: IT
is the legacy country field, not a Subito section. Motori/Immobili use the observed
category paths; Market/all are filtered locally by the first-party category catalog.
Motori/Immobili and a narrow Market query have limited live validation.
relevance is available for Market/all, not Motori/Immobili.
Price filtering is local:
missing prices are excluded when a range is set. Native pages contain at most 30
ordinary listings; promoted gallery listings are intentionally excluded. A limit
of 1–30 truncates the current native page, and incrementing page skips its unused
remainder. Sparse price matches can return fewer than requested. No individual subcategory,
location, radius, time filters, photos or price-drop alerts in this version.
Reliability and operations
Baseline and associations commit atomically only after reaching an explicit last page within the scan budget and checking the first page for newly arrived IDs. Failures never advance state. IDs are the numeric listing ID validated against its URN and URL; there is no maximum-ID/timestamp heuristic. Global ID/destination history suppresses reposted IDs across overlapping watches; a different ID is new. Baseline records are distinguished from successfully sent messages. Pending sends survive restart, pause, edits and deletion. A crash after Telegram accepted a message but before the SQLite commit can duplicate it: delivery is at least once.
A mutable paginated site is not an exhaustive snapshot. The default scan budget is five native pages plus a first-page check; broad searches may never complete a baseline. Narrow the text query. Downtime can lose ads that disappear before a successful scan; no timestamp recovery window is promised. Process health does not prove scan freshness or Telegram delivery.
Build and check
uv run --no-sync pytest -q
uv run --no-sync ruff check .
uv run --no-sync ruff format --check .
docker build -t subito-monitoring:test .
python3 scripts/container_check.pyPull requests run offline tests, lint, a full-history secret scan, a locked-dependency
export check, and container/volume verification. Pushes to master additionally
build and test native amd64 and arm64 images before publishing the multi-platform
latest and sha-<commit> tags. Release tags publish versioned images only after
the same checks; version tags must match pyproject.toml. CI never contacts Subito
or Telegram and needs no personal registry token.
See publishing and release procedure, verification evidence, and dependency license inventory. This project is unaffiliated with Subito. No cluster, MCPHub or Hermes installation is implied by a public image; those are separate administrator operations.
Available Tools
8 toolscreate_watchB
Create persistent polling independent of Hermes; silent initial complete baseline.
Telegram destination is administrator configured. New IDs only, not price drops. Polling defaults to 600 seconds. Watch queries must use newest_first.
Inputs: name (required), query (required), interval_seconds.
delete_watchC
Delete a watch and its seen IDs; retain global deduplication and queued deliveries.
Inputs: watch_id (required).
list_watchesB
List persistent searches, baseline state, scan freshness and errors. No credentials.
Inputs: no named parameters.
monitoring_statusC
Authenticated scan freshness, errors and persistent Telegram backlog.
Inputs: no named parameters.
pause_watchC
Pause scans; previously queued notifications still deliver.
Inputs: watch_id (required).
resume_watchC
Resume scans with existing baseline, bounded recovery and ID deduplication.
Inputs: watch_id (required).
search_itemsA
Immediate one-page Italy/EUR search, no watch or Telegram message.
Set section to market, motori or immobili; all (default) excludes Lavoro. Market is filtered locally; Motori/Immobili use category paths. Set order explicitly for the desired ranking (default newest_first). Newest is ordering, not a time filter. Page results can move or repeat. No reliable listing timestamp, exhaustive coverage, or price-drop detection.
Inputs: query (required), page, limit.
update_watchA
Replace the entire query, or change interval/name. Filter changes reset a silent baseline.
Existing queued notifications are retained. No price-drop or time filter support.
Inputs: watch_id (required), name, query, interval_seconds.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
list_watches and monitoring_status both report freshness/errors, creating some overlap, though one is explicitly unauthenticated and the other is authenticated with Telegram backlog. search_items is clearly immediate versus persistent watches, and pause/resume/update/delete are distinct lifecycle actions.
Seven of eight tools follow a clear verb_noun pattern: list_watches, pause_watch, search_items, create_watch, update_watch, resume_watch, delete_watch. monitoring_status breaks the verb pattern as a noun phrase, but the overall convention remains readable and predictable.
Eight tools is well-scoped for this domain, covering the full watch lifecycle, status inspection, and an immediate search path. Each tool has a clear role without obvious bloat.
The surface covers create/list/update/delete plus pause/resume and status for persistent searches, and list_watches exposes baseline and freshness state. A dedicated get_watch by ID is absent, but it is a minor gap agents can work around via list_watches.
Maintenance
Related MCP Connectors
Your own WhatsApp as an MCP server: read, search and send from any MCP client.
Hosted Telegram MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Remote streamable-HTTP MCP server running on a single Cloudflare Worker. Your assistant gets live Airbnb, Amazon, Booking.com, Google Flights, Maps and Reddit data, social search on X, Instagram and TikTok, the Meta Ad Library, and image/video generation without any keys. Connect your own accounts to let it send WhatsApp or Telegram messages, work an IMAP inbox, manage Meta Ads campaigns and publish to X and LinkedIn. OAuth 2.1 with PKCE; stored credentials are AES-256-GCM encrypted.
Telegram bridge for your MCP-compatible agent. Bidirectional, no LLM in our stack.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceAn MCP server that connects to a Telegram group chat, persists messages to a local SQLite database, and exposes tools to search, retrieve, and send messages via SSE.-
- FlicenseNot gradedqualityDmaintenanceA remote MCP server that searches Avito for new classified ads, filtering by price and returning only previously unseen listings. Designed for scheduled monitoring via ChatGPT tasks.-
- FlicenseNot gradedqualityDmaintenanceCaches Telegram channel posts locally in SQLite and exposes them via MCP tools for querying and management.-
- FlicenseAqualityCmaintenanceLocal SQLite archive and MCP search service for the Telegram channel @markettwits, enabling users to query asset-specific twits by instrument and time range.1-