Skip to content

PetarIsakovic/NotionHacks

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DealScout

DealScout is a local-first MVP for hunting online listings with deterministic Python orchestration, cheap Bedrock-based AI triage, SQLite caching, and Notion workspace sync over Notion's hosted MCP endpoint.

Folder Tree

DealScout/
├── .env.example
├── README.md
├── requirements.txt
├── app/
│   ├── __init__.py
│   ├── actions.py
│   ├── bedrock_client.py
│   ├── config.py
│   ├── dedupe.py
│   ├── main.py
│   ├── models.py
│   ├── notion_mcp_client.py
│   ├── orchestrator.py
│   ├── parser.py
│   ├── prompts.py
│   ├── scraper.py
│   ├── scoring.py
│   ├── search_loader.py
│   ├── storage.py
│   └── utils.py
├── data/
│   ├── cache.db
│   └── sample_listings.json
├── scripts/
│   ├── bootstrap_notion.py
│   └── run_once.py
└── tests/
    ├── test_dedupe.py
    ├── test_models.py
    ├── test_orchestrator.py
    ├── test_scraper.py
    └── test_scoring.py

Architecture

DealScout is intentionally split into deterministic and AI-backed layers:

  • scraper.py, parser.py, dedupe.py, scoring.py, and orchestrator.py do all web retrieval, normalization, filtering, dedupe, and feature computation in plain Python.
  • bedrock_client.py sends only compact structured context to Amazon Bedrock and uses Amazon Nova Micro for low-cost triage decisions.
  • storage.py keeps local-first state in SQLite: dedupe cache, raw snapshots, checkpoints, and run history.
  • notion_mcp_client.py handles OAuth 2.0 Authorization Code + PKCE, token refresh, secure local storage through the OS keychain, and Streamable HTTP MCP calls to https://mcp.notion.com/mcp.
  • actions.py applies the sync policy so listings are not blindly inserted and Notion gets updated only after local filtering and a decision pass.

Current source adapters:

  • sample: local deterministic fixture data.
  • ebay: official Browse API search via client-credentials OAuth.
  • amazon: Amazon Product Advertising API search via signed PA-API requests.
  • etsy: Etsy Open API active listing search via API key.
  • bestbuy: Best Buy Products API retail search via API key.
  • craigslist: RSS-based adapter kept for experimentation, but it is often rate-limited or blocked with 403.

Why Notion MCP

The app uses Notion's hosted MCP endpoint instead of the old self-hosted notion-mcp-server because:

  • it works against the live user workspace with OAuth,
  • it keeps auth local to the machine,
  • it fits the "AI operating on workspace data" model Notion is actively shipping,
  • it avoids owning and maintaining a separate Notion-side server.

Why Nova Micro

Nova Micro is a good fit here because the model is only asked to do cheap structured judgments:

  • track vs ignore,
  • match score,
  • deal score,
  • task creation,
  • short note generation.

All expensive or brittle work stays deterministic and local.

Setup

1. Create a virtualenv

python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

2. Create .env

cp .env.example .env

If you already have integration-accessible Notion databases, update the TODO values:

  • NOTION_SEARCHES_DATABASE_ID
  • NOTION_LISTINGS_DATABASE_ID
  • NOTION_TASKS_DATABASE_ID
  • NOTION_RUNS_DATABASE_ID

If you do not, the fastest path is to let DealScout bootstrap a fresh, integration-owned setup after you turn on Notion:

python scripts/bootstrap_notion.py

That command:

  • creates a new top-level DealScout page that the current MCP OAuth session can access,
  • creates fresh Searches, Listings, Tasks, and Runs databases under it,
  • seeds starter search rows by default,
  • rewrites the four NOTION_*_DATABASE_ID values in your local .env.

3. Configure AWS for Bedrock

You need AWS credentials on the local machine with Bedrock access in the region from AWS_REGION.

Typical options:

  • aws configure
  • SSO with aws sso login
  • environment variables such as AWS_PROFILE

BEDROCK_MODEL_ID defaults to us.amazon.nova-micro-v1:0, which is a practical cross-region US inference profile for North American development.

3b. Configure eBay for a live marketplace source

DealScout now supports eBay's official Browse API.

You need an eBay Developer Program app keyset:

  1. Create an app in the eBay developer portal.
  2. In Production, complete the Marketplace Account Deletion compliance flow if your app persists eBay data.
  3. Copy the application Client ID and Client Secret.
  4. Put them in .env:
EBAY_CLIENT_ID=your-ebay-client-id
EBAY_CLIENT_SECRET=your-ebay-client-secret
AMAZON_PAAPI_PARTNER_TAG=your-amazon-partner-tag
AMAZON_PAAPI_ACCESS_KEY=your-amazon-paapi-access-key
AMAZON_PAAPI_SECRET_KEY=your-amazon-paapi-secret-key
ETSY_API_KEY=your-etsy-api-key
BESTBUY_API_KEY=your-bestbuy-api-key
ENABLED_SOURCES=ebay,amazon,etsy,bestbuy

Optional eBay settings:

  • EBAY_MARKETPLACE_ID=EBAY_US
  • EBAY_PRICE_CURRENCY=USD
  • EBAY_RESULT_LIMIT=10

Amazon Product Advertising API note

Amazon's official Product Advertising API can still be used for this project, but Amazon has announced that PA-API will be deprecated on April 30, 2026 and recommends new customers use Creators API going forward. If you already have PA-API access, DealScout can use it today; just treat it as a shorter-lived integration.

eBay notification compliance

DealScout stores eBay listing data in SQLite and Notion, so for eBay production compliance you should assume that your app is persisting eBay data. That means you should configure Marketplace Account Deletion, not the Not persisting eBay data exemption.

Current eBay docs for this flow:

Recommended setup:

  1. In the eBay developer portal, go to your production keyset's Alerts & Notifications tab.
  2. Select Marketplace Account Deletion.
  3. Enter an email address for alerts.
  4. Set a public https://... callback URL and a verification token.
  5. Run the local receiver:
python scripts/ebay_notification_receiver.py --print-token
python scripts/ebay_notification_receiver.py
  1. Expose the local receiver through a public HTTPS URL. For quick validation, a local tunnel works. For actual compliance, use a stable always-on public endpoint.
  2. Put the same URL/token in .env:
EBAY_NOTIFICATION_ENDPOINT_URL=https://your-public-host/ebay/marketplace-account-deletion
EBAY_NOTIFICATION_VERIFICATION_TOKEN=your-verification-token
EBAY_NOTIFICATION_PORT=8081
EBAY_NOTIFICATION_PATH=/ebay/marketplace-account-deletion

The receiver writes incoming notifications to:

  • data/ebay_marketplace_account_deletion.jsonl

Official docs:

4. Configure Notion OAuth for hosted MCP

DealScout uses Notion's hosted MCP endpoint:

  • https://mcp.notion.com/mcp

Flow details:

  • first live run performs OAuth 2.0 Authorization Code with PKCE,
  • the client registers dynamically if the authorization server allows it,
  • tokens are stored in the local OS keychain through keyring,
  • client metadata is stored at ~/.dealscout/notion_client.json,
  • refresh happens automatically on later runs.

If dynamic client registration is unavailable in your workspace, the code raises a TODO-style error telling you to provide a pre-registered client.

5. Create the Notion databases

Recommended path:

python scripts/bootstrap_notion.py

Manual path:

Create four databases in the workspace and record their IDs in .env.

Recommended property types:

Searches

Property Type
Search Name Title
Query Text
Category Select or Text
Min Price Number
Max Price Number
Location Text
Radius Number
Preferred Keywords Text
Avoid Keywords Text
Must Have Text
Nice To Have Text
Condition Preference Select
Alert Aggressiveness Select
Active Checkbox
Last Run At Date

Listings

Property Type
Title Title
Search Relation Relation to Searches
Source URL URL
Marketplace Select
Price Number
Currency Text
Location Text
Posted At Date
Condition Select
Seller Name Text
Extracted Attributes Text
Estimated Fair Value Number
Match Score Number
Deal Score Number
Priority Select
Status Select
Scam Risk Select
Duplicate Key Text
AI Notes Text
Seller Message Draft Text
Created By Run Text
Listing Hash Text
Image URL URL

Tasks

Property Type
Task Title
Related Listing Relation to Listings
Related Search Relation to Searches
Due Date Date
Priority Select
Status Select
Reason Text

Runs

Property Type
Run Time Title
Searches Processed Number
Listings Seen Number
Listings Added Number
Listings Updated Number
Tasks Created Number
Errors Text
Summary Text

Suggested select values:

  • Status: New, Reviewed, Hot, Contacted, Monitoring, Ignored, Suspected Scam, Closed
  • Priority: Low, Medium, High, Urgent
  • Scam Risk: Low, Medium, High

Live Run

Once AWS and Notion are configured:

python scripts/run_once.py

Recommended live run with the official marketplace source:

AWS_PROFILE=your-profile ENABLED_SOURCES=sample,ebay,etsy,bestbuy python scripts/run_once.py

If your hosted MCP workspace does not expose notion-query-data-sources, DealScout falls back to a local registry of search-row page IDs that is populated by bootstrap_notion.py. That keeps active search loading deterministic for the bootstrapped workspace.

Run flow:

  1. load active searches,
  2. fetch listings from enabled sources,
  3. normalize and deterministically filter,
  4. compute scoring features,
  5. call Nova Micro for a strict structured decision,
  6. search Notion for similar listings before inserting,
  7. create or update listing pages,
  8. create follow-up tasks when justified,
  9. log the run locally and optionally in Notion.

Tests

pytest

Current tests cover:

  • scoring,
  • dedupe,
  • scraper parsing and source wiring,
  • decision model validation,
  • basic orchestration flow.

Notes And TODOs

  • notion_mcp_client.py includes TODO markers where exact workspace-specific MCP tool schemas may need adjustment.
  • View creation is intentionally left as a TODO behind NOTION_CREATE_VIEWS=true until the workspace's notion-create-view tool schema is confirmed.
  • If your Notion workspace does not expose a structured query tool for data sources, the client falls back to notion-search plus notion-fetch, which is less deterministic.

Quick Run Walkthrough

  1. Configure .env with your Notion, AWS, and optional eBay settings.
  2. python scripts/bootstrap_notion.py
  3. AWS_PROFILE=your-profile python scripts/run_once.py
  4. Read the terminal summary.
  5. Inspect your Notion Listings, Tasks, and Runs databases.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages