Skip to main content

Scan for Global Entry / NEXUS appointment slots and get notified

Project description

Global Entry Appointment Scanner

Scan for open Global Entry / NEXUS appointment slots and get notified the moment one appears.

CI PyPI Python

Install

pip install global-entry-scanner           # core (email only)
pip install global-entry-scanner[slack]    # + Slack
pip install global-entry-scanner[discord]  # + Discord
pip install global-entry-scanner[sms]      # + Twilio SMS
pip install global-entry-scanner[mcp]      # + MCP server for AI agents
pip install global-entry-scanner[all]      # everything

Quick start

# 1. Interactive setup — pick locations and configure notifications
global-entry-scanner setup

# 2. Run the scanner
global-entry-scanner scan

CLI

global-entry-scanner locations                                    # list all enrollment centers
global-entry-scanner setup                                        # interactive config wizard
global-entry-scanner scan                                         # run with saved config
global-entry-scanner scan --locations "Chicago, Dallas"           # override locations
global-entry-scanner scan --notify email,slack                    # override channels
global-entry-scanner mcp                                          # start MCP server

Config is saved to ~/.config/global-entry-scanner/config.toml.

Python API

from global_entry_scanner import Scanner
from global_entry_scanner.notifications import SlackNotifier, DiscordNotifier, EmailNotifier

scanner = Scanner(location_ids=[5001, 5140])
scanner.add_notifier(SlackNotifier(webhook_url="https://hooks.slack.com/..."))
scanner.add_notifier(DiscordNotifier(webhook_url="https://discord.com/api/webhooks/..."))
scanner.add_notifier(EmailNotifier(from_email="you@gmail.com", to_email="you@gmail.com", password="app-password"))
scanner.start()  # blocking; Ctrl+C to stop

Scanner options:

Parameter Default Description
location_ids required List of enrollment center IDs
check_interval 900 Seconds between polls (no errors)
error_interval 60 Seconds between polls (on error)
limit 5 Max appointments to fetch per location

Notification channels

Channel Extra Credentials
Email (core) Gmail address + app password
Discord [discord] Webhook URL
Slack [slack] Webhook URL
SMS [sms] Twilio account SID, auth token, phone numbers

All configured channels fire concurrently. One failing channel does not block the others.

Discord webhook setup

  1. Open your Discord server → go to the channel you want notifications in
  2. Click Edit Channel (gear icon) → IntegrationsWebhooksNew Webhook
  3. Give it a name, optionally set an avatar, then click Copy Webhook URL
  4. Paste the URL into setup when prompted, or add it to your config:
[notifications.discord]
webhook_url = "https://discord.com/api/webhooks/1234567890/xxxx"

Twilio SMS setup

  1. Sign up at twilio.com (free trial includes a small credit)
  2. From the Twilio Console dashboard, copy your Account SID and Auth Token
  3. Go to Phone NumbersManageBuy a number to get a Twilio number to send from (free trial includes one)
  4. Add the credentials to your config:
[notifications.sms]
account_sid = "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
auth_token  = "your_auth_token"
from_number = "+12125550000"   # your Twilio number
to_number   = "+12125551234"   # number to notify

Free trial note: Twilio trial accounts can only send SMS to verified numbers. Go to Phone NumbersManageVerified Caller IDs to add your personal number.

Slack webhook setup

  1. Go to api.slack.com/appsCreate New AppFrom scratch
  2. Under Add features and functionality, choose Incoming Webhooks → toggle it on
  3. Click Add New Webhook to Workspace, pick a channel, and click Allow
  4. Copy the webhook URL that appears, then paste it into setup when prompted or add it to your config:
[notifications.slack]
webhook_url = "https://hooks.slack.com/services/T00000000/B00000000/xxxx"

MCP server

Install with pip install global-entry-scanner[mcp], then run global-entry-scanner mcp.

Exposes six tools to AI agents: get_locations, search_locations, check_appointments, start_scan, stop_scan, get_scan_status.

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "global-entry-scanner": {
      "command": "global-entry-scanner",
      "args": ["mcp"]
    }
  }
}

Configuration file

~/.config/global-entry-scanner/config.toml

[scanner]
check_interval = 900
error_interval = 60
limit = 5

[locations]
ids = [5001, 5140]

[notifications.discord]
webhook_url = "https://discord.com/api/webhooks/..."

[notifications.slack]
webhook_url = "https://hooks.slack.com/..."

[notifications.email]
from_email = "you@gmail.com"
to_email = "you@gmail.com"
password = "app-password"

[notifications.sms]
account_sid = "..."
auth_token = "..."
to_number = "+12125551234"
from_number = "+12125550000"

Development

git clone https://github.com/JaiminBrahmbhatt/Global-Entry-Appointment-Scanner
cd Global-Entry-Appointment-Scanner
pip install -e ".[all,dev]"

# Run tests
pytest

# Run live API tests
pytest -m integration

# Lint + type check
ruff check .
mypy global_entry_scanner/

Credits

Inspired by:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

global_entry_scanner-0.1.2.tar.gz (15.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

global_entry_scanner-0.1.2-py3-none-any.whl (15.5 kB view details)

Uploaded Python 3

File details

Details for the file global_entry_scanner-0.1.2.tar.gz.

File metadata

  • Download URL: global_entry_scanner-0.1.2.tar.gz
  • Upload date:
  • Size: 15.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for global_entry_scanner-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d855f299d8c9852b23ba3ddf4a9f6624b2f458ecfd4c7756fff739dab8b42d64
MD5 533d72a1da366c9fccc4338e08dcdc35
BLAKE2b-256 7684ccf2999943cdd0a058505265d5da343a2f62fd98569e166030890e71a8f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for global_entry_scanner-0.1.2.tar.gz:

Publisher: publish.yml on JaiminBrahmbhatt/Global-Entry-Appointment-Scanner

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file global_entry_scanner-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for global_entry_scanner-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 78f252c25e5f2da87deea40b407ffd24ddbca4eecd25bc751c8208e2d2805820
MD5 4f4f491d8a11e0563326748de3b74640
BLAKE2b-256 46b0ff8f29f4ab294fefc4115fec71561b83e08796a3f635221da8603bb19b0b

See more details on using hashes here.

Provenance

The following attestation bundles were made for global_entry_scanner-0.1.2-py3-none-any.whl:

Publisher: publish.yml on JaiminBrahmbhatt/Global-Entry-Appointment-Scanner

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page