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

demo

Install

Recommended — pipx (installs CLI tools in isolated environments, no conflicts):

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

On macOS, avoid using the system pip3 — it points to Python 3.9 which is too old, and Homebrew's Python will block system-wide installs. pipx handles all of this automatically.

Alternative — pip (if you're inside a virtual environment):

pip install global-entry-scanner
pip install "global-entry-scanner[all]"

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"

Claude Code skill

This repo ships a skill for Claude Code that lets you ask Claude directly about slot availability, set up monitoring, and configure notifications — without remembering any commands.

Install the skill

Option 1: From this repo (available now)

In Claude Code, run:

/plugin marketplace add JaiminBrahmbhatt/Global-Entry-Appointment-Scanner
/plugin install global-entry-scanner@global-entry-scanner

Option 2: Official Anthropic marketplace (pending review)

/plugin install global-entry-scanner

What you can ask Claude

Once installed, just talk to Claude naturally:

  • "Are there any open Global Entry slots near Chicago or Dallas?"
  • "Set this up to text me whenever a slot opens at JFK or Newark"
  • "How do I hook up the MCP server to Claude Desktop?"
  • "Run the scanner in the background and notify me on Discord"

Claude will detect whether the MCP server is running and use it directly, or fall back to guiding you through the CLI.


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.3.tar.gz (347.5 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.3-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: global_entry_scanner-0.1.3.tar.gz
  • Upload date:
  • Size: 347.5 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.3.tar.gz
Algorithm Hash digest
SHA256 3264f12a8f3fb495787e7c75390664858f08b8903aa9f8db21250f4e3f441aa6
MD5 87adb4837f81754d5ec4f3bdc3889fd0
BLAKE2b-256 e6b82e2aca015929cba3d01bafaf0247d0912efaad804146c2f6f03e3f6a490b

See more details on using hashes here.

Provenance

The following attestation bundles were made for global_entry_scanner-0.1.3.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.3-py3-none-any.whl.

File metadata

File hashes

Hashes for global_entry_scanner-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b68191c0a72c8d0c0f2ff23a69af0942f51a002f0f2e0cd4d8e95b55b5682682
MD5 e1acf61a51c2aa775269f29c15959373
BLAKE2b-256 f0f477dc3f0c3e7a3423e0bb921e668fa7583164b1742634486d5cb04dc0d706

See more details on using hashes here.

Provenance

The following attestation bundles were made for global_entry_scanner-0.1.3-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