Skip to main content
Glama
nk1947-sudo

local-tech-digest-mcp

by nk1947-sudo
README.md
# πŸš€ local-tech-digest-mcp

A **local, privacy-first** Model Context Protocol (MCP) server that automatically tracks entry-level tech job openings and upcoming USA tech conferences β€” then emails you a clean HTML digest on a smart schedule.

Runs 100% on your machine. No cloud, no tracking, no third-party accounts beyond a Gmail App Password.

---

## ✨ Features

- **Dual digest** β€” entry-level jobs (daily) + tech conferences (weekly)
- **Smart scheduler** β€” fires at 08:00 ET daily; also triggers immediately if you open your laptop after 8 PM
- **3-gate job filter** β€” level β†’ exclusion β†’ domain β†’ stack scoring
- **F-1 OPT aware** β€” excludes clearance/citizenship-required and no-sponsorship roles
- **USA / International split** β€” USA roles first, foreign roles in a separate section
- **Zero API keys** β€” all data sources are free and public
- **Deduplication** β€” SQLite tracks every job/conference ever seen; emails only new entries
- **10 MCP tools** β€” query, search, and trigger digests directly from Claude Desktop
- **Auto-start** β€” silent Windows Startup launcher included

---

## πŸ—οΈ Architecture

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        local-tech-digest-mcp                        β”‚
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Claude      β”‚     β”‚              Scrapers                    β”‚  β”‚
β”‚  β”‚ Desktop     │────▢│  SimplifyJobs  β”‚  RemoteOK  β”‚  The Muse  β”‚  β”‚
β”‚  β”‚ (MCP tools) β”‚     β”‚  (GitHub JSON) β”‚  (API)     β”‚  (API)     β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                     β”‚                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Scheduler  β”‚     β”‚           Filter Pipeline                β”‚  β”‚
β”‚  β”‚  node-cron  β”‚     β”‚  Gate 1: Level  (junior/entry/intern)    β”‚  β”‚
β”‚  β”‚  08:00 ET   β”‚     β”‚  Gate 2: Exclusion (clearance/no-visa)   β”‚  β”‚
β”‚  β”‚  + 8 PM     β”‚     β”‚  Gate 3: Domain (cyber/cloud/web/sys)    β”‚  β”‚
β”‚  β”‚  on-open    β”‚     β”‚  Scorer: Stack match (Python/AWS/Linux…) β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚         β”‚                           β”‚                               β”‚
β”‚         β”‚            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚         β”‚            β”‚         SQLite  (digest.db)              β”‚  β”‚
β”‚         β”‚            β”‚   conferences table  β”‚  jobs table       β”‚  β”‚
β”‚         β”‚            β”‚   hash dedup         β”‚  hash dedup       β”‚  β”‚
β”‚         β”‚            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚         β”‚                           β”‚                               β”‚
β”‚         └──────────────────────────▢│                               β”‚
β”‚                                     β–Ό                               β”‚
β”‚                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚                      β”‚      Email Builder       β”‚                  β”‚
β”‚                      β”‚  Section 1: USA Jobs     β”‚                  β”‚
β”‚                      β”‚  Section 2: Conferences  β”‚                  β”‚
β”‚                      β”‚  Section 3: Intl Jobs    β”‚                  β”‚
β”‚                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚                                     β”‚                               β”‚
β”‚                                     β–Ό                               β”‚
β”‚                            Gmail SMTP (nodemailer)                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

---

## πŸ“ Project Structure

```
local-tech-digest-mcp/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ db/
β”‚   β”‚   β”œβ”€β”€ schema.ts          # SQLite init β€” creates both tables on first run
β”‚   β”‚   β”œβ”€β”€ conferences.ts     # Conference CRUD & queries
β”‚   β”‚   └── jobs.ts            # Job CRUD, search, filter, stats
β”‚   β”œβ”€β”€ filters/
β”‚   β”‚   └── jobs.ts            # 3-gate pipeline, stack scorer, HTML stripper
β”‚   β”œβ”€β”€ scrapers/
β”‚   β”‚   β”œβ”€β”€ conferences.ts     # confs.tech GitHub JSON scraper
β”‚   β”‚   └── jobs/
β”‚   β”‚       β”œβ”€β”€ index.ts       # Parallel orchestrator for all job sources
β”‚   β”‚       β”œβ”€β”€ simplify.ts    # SimplifyJobs (new-grad + internships)
β”‚   β”‚       β”œβ”€β”€ remoteok.ts    # RemoteOK public API
β”‚   β”‚       └── themuse.ts     # The Muse public API
β”‚   β”œβ”€β”€ email/
β”‚   β”‚   β”œβ”€β”€ builder.ts         # Region classifier, USA/intl split, SMTP send
β”‚   β”‚   β”œβ”€β”€ jobs-section.ts    # Job cards HTML renderer
β”‚   β”‚   └── conf-section.ts    # Conference cards HTML renderer
β”‚   β”œβ”€β”€ server.ts              # MCP server β€” 10 tools for Claude Desktop
β”‚   └── scheduler.ts           # node-cron dual schedule + 8 PM on-open trigger
β”œβ”€β”€ data/                      # Auto-created β€” SQLite database (gitignored)
β”œβ”€β”€ dist/                      # Auto-created β€” compiled JS (gitignored)
β”œβ”€β”€ launch-silent.vbs          # Windows Startup silent launcher
β”œβ”€β”€ setup-autostart.ps1        # Register Windows startup task (optional)
β”œβ”€β”€ .env.example               # Environment variable template
β”œβ”€β”€ package.json
└── tsconfig.json
```

---

## πŸ”Œ Data Sources

| Source | Type | Auth | What it provides |
|---|---|---|---|
| [SimplifyJobs New-Grad](https://github.com/SimplifyJobs/New-Grad-Positions) | GitHub raw JSON | None | Entry-level CS full-time roles |
| [SimplifyJobs Internships](https://github.com/SimplifyJobs/Summer2026-Internships) | GitHub raw JSON | None | Summer/fall tech internships |
| [RemoteOK](https://remoteok.com/api) | Public API | None | Remote tech roles globally |
| [The Muse](https://www.themuse.com/api/public/jobs) | Public API | None | Entry-level filtered roles |
| [confs.tech](https://github.com/tech-conferences/conference-data) | GitHub raw JSON | None | USA tech conferences by topic |

---

## πŸ” Job Filter Pipeline

Every scraped job passes three sequential gates before being stored:

```
RAW JOB
   β”‚
   β–Ό GATE 1 β€” LEVEL FILTER  (title must match)
     junior Β· entry-level Β· associate Β· l1 Β· graduate Β· new-grad Β· intern(ship)
   β”‚
   β–Ό GATE 2 β€” EXCLUSION FILTER  (reject if found in title or description)
     us-citizenship-required Β· must-be-us-citizen Β· secret-clearance
     top-secret Β· ts/sci Β· dod Β· department-of-defense Β· itar
     no-sponsorship Β· sponsorship-not-available
   β”‚
   β–Ό GATE 3 β€” DOMAIN FILTER  (must match at least one)
     Cybersecurity  β†’ security | infosec | soc | devsecops | pentest | siem …
     Cloud/DevOps   β†’ cloud | aws | azure | devops | kubernetes | terraform …
     Web Development β†’ frontend | backend | full-stack | react | node | django …
     SysAdmin       β†’ linux | sysadmin | system-admin | sre | network-admin …
   β”‚
   β–Ό STACK SCORER  (points added for matching user's tech stack)
     Python          +2     Linux / Debian / Ubuntu  +2
     Bash / Shell    +2     AWS                      +2
     Security (CVE)  +2     Docker / Kubernetes      +1
     Terraform       +1     Git / GitHub             +1
     Networking      +1
     ────────────────────────────────────
     Maximum score: 14 points
   β”‚
   β–Ό STORED in SQLite
     Emailed if score β‰₯ MIN_JOB_SCORE (default: 0)
     Capped at MAX_JOBS_PER_DOMAIN per email (default: 25)
```

---

## πŸ“§ Email Layout

```
╔════════════════════════════════════════════════════════╗
β•‘          πŸš€ Weekly Tech Digest β€” May 29, 2026          β•‘
β•‘      πŸ‡ΊπŸ‡Έ 82 USA roles Β· 🌍 18 international Β· πŸŽ‰ 15 conf β•‘
β•‘  [Cybersecurity] [Cloud/DevOps] [Web Dev] [SysAdmin]   β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

πŸ’Ό NEW ENTRY-LEVEL OPENINGS (USA)
──────────────────────────────────────────────
πŸ”’ Cybersecurity  (N roles)
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Security Analyst Intern β€” CrowdStrike    β”‚
  β”‚ 🏒 CrowdStrike   πŸ“ Remote              β”‚
  β”‚ [Internship] [Remote] [βœ“ Visa Sponsor]  β”‚
  β”‚ Tags: python  linux  aws                β”‚
  β”‚ Match β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘  8/14                β”‚
  β”‚                        [Apply β†’]        β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β˜οΈβš™  Cloud / DevOps  (N roles)
🌐 Web Development  (N roles)
πŸ–₯️  SysAdmin  (N roles)

πŸŽ‰ UPCOMING USA TECH CONFERENCES  (Monday only)
──────────────────────────────────────────────
πŸ”’ Cybersecurity
  β€’ DEF CON 34 β€” Las Vegas  Β· Aug 7–10
☁️  Cloud / DevOps
  β€’ KubeCon NA β€” Atlanta  Β· Nov 10–14  ⏰ CFP: Jul 21

🌍 INTERNATIONAL OPPORTUNITIES
──────────────────────────────────────────────
ℹ️  These roles are outside the USA. Verify work
    authorization before applying.
[Same card layout, purple accent]
```

---

## πŸ› οΈ Prerequisites

- [Node.js](https://nodejs.org/) v18 or later
- A Gmail account with [App Password](https://myaccount.google.com/apppasswords) enabled (requires 2-Step Verification)

---

## βš™οΈ Setup

### 1. Clone & install

```bash
git clone https://github.com/YOUR_USERNAME/local-tech-digest-mcp.git
cd local-tech-digest-mcp
npm install
```

### 2. Configure environment

```bash
copy .env.example .env   # Windows
cp  .env.example .env    # Mac/Linux
```

Edit `.env` with your values:

```env
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=you@gmail.com
SMTP_PASS=xxxx_xxxx_xxxx_xxxx     # Gmail App Password (16 chars, no spaces)
NOTIFY_EMAIL=you@gmail.com

TZ=America/New_York               # Your timezone

MIN_JOB_SCORE=0                   # 0 = all jobs  |  4 = strong stack matches only
MAX_JOBS_PER_DOMAIN=25            # Max job cards per domain per email
```

> **Gmail App Password:** Go to [myaccount.google.com/apppasswords](https://myaccount.google.com/apppasswords), create a new app password, and paste the 16-character code (without spaces) as `SMTP_PASS`.

### 3. Build

```bash
npm run build
```

### 4. Register with Claude Desktop

Add to `claude_desktop_config.json`:

- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "tech-digest-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/local-tech-digest-mcp/dist/server.js"]
    }
  }
}
```

Restart Claude Desktop after saving.

### 5. Run the scheduler

```bash
node dist/scheduler.js
```

Keep this terminal open. The scheduler fires automatically on its schedule.

### 6. Auto-start on Windows login (optional)

Copy `launch-silent.vbs` to your Windows Startup folder:

```powershell
Copy-Item .\launch-silent.vbs ([Environment]::GetFolderPath('Startup'))
```

The scheduler will now start silently every time you log in.

---

## πŸ§ͺ Test Commands

```bash
# Trigger daily jobs digest immediately
node dist/scheduler.js --now-daily

# Trigger full weekly digest (jobs + conferences)
node dist/scheduler.js --now-weekly
```

---

## πŸ“… Schedule Behaviour

| When | Action |
|---|---|
| Every day 08:00 ET (Tue–Sun) | Scrape jobs β†’ send jobs-only email |
| Every Monday 08:00 ET | Scrape jobs + conferences β†’ send full email |
| Laptop opened **after 8 PM** | Runs the appropriate digest immediately |
| Nothing new | Email skipped β€” no empty digests |

---

## πŸ”§ MCP Tools (Claude Desktop)

| Tool | Description |
|---|---|
| `fetch_jobs` | Scrape all sources, filter, score, store new jobs |
| `list_new_jobs` | Pending (un-emailed) jobs sorted by score |
| `get_top_matches` | Top N jobs by stack-match score |
| `search_jobs` | Full-text search by keyword |
| `filter_jobs` | Filter by domain, type, min score |
| `fetch_conferences` | Scrape confs.tech for upcoming USA events |
| `list_upcoming_conferences` | Conferences in the next N days |
| `search_conferences` | Keyword search across conferences |
| `send_digest_email` | Manually trigger digest (`mode: daily\|weekly`) |
| `get_stats` | Database counts for jobs and conferences |

---

## πŸ—„οΈ Database Schema

```sql
-- Conference events
CREATE TABLE conferences (
  id, name, url, startDate, endDate, city, state, country,
  topics TEXT,        -- JSON array of domain labels
  cfpDeadline, cfpUrl, source,
  hash TEXT UNIQUE,   -- md5(name|startDate|city) for deduplication
  firstSeen, notified INTEGER DEFAULT 0
);

-- Job listings
CREATE TABLE jobs (
  id, external_id, title, company, url, apply_url,
  location, remote INTEGER,
  job_type,           -- full-time | internship
  domain,             -- primary domain bucket
  tags TEXT,          -- JSON array
  description TEXT,
  date_posted, sponsorship, source,
  hash TEXT UNIQUE,   -- md5(title|company|url) for deduplication
  score INTEGER,      -- 0–14 stack-match score
  first_seen, notified INTEGER DEFAULT 0
);
```

---

## πŸ”’ Privacy

- All data stays on your machine
- No analytics, no telemetry, no external accounts required
- The only outbound connections are to public GitHub raw URLs, RemoteOK, The Muse, and your own SMTP relay
- `.env` credentials are gitignored and never leave your machine

---

## πŸ“„ License

MIT β€” use freely, modify freely.

TDQS

A3.6/5.0

Scored across 13 tools

Disambiguation4/5

Tools are mostly distinct: fetch, list, search, filter, mark, pipeline, skills, conferences, email, stats each have clear roles. Minor overlap exists among job listing tools (list_new_jobs, get_top_matches, search_jobs, filter_jobs) but descriptions clarify their specific filters and purposes.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using lowercase with underscores (fetch_, list_, get_, search_, filter_, mark_, suggest_, send_). The pattern is uniform, and there are no mixed conventions or ambiguous verbs.

Tool Count5/5

13 tools is well within the ideal 3-15 range for a server with this scope. The count feels balanced: 8 tools for job operations, 3 for conferences, plus digest email and stats, each earning its place without bloat.

Completeness4/5

The surface covers the main workflows: fetching/ingesting data, searching/filtering, managing a job pipeline, suggesting skills, sending digests, and viewing stats. Minor gaps exist such as no dedicated get_job_details or conference detail view, but these are workable via searches/filters.

Maintenance

ActivityInactive
ResponsivenessNo issues