Skip to main content

Personal job-finding automation: fetch, rank, track job postings.

Project description

karyab

kaaryab (Persian کاریاب, "job finder") — a personal job-hunting automation.

karyab fetches job postings from multiple sources, ranks them against your profile, builds a daily shortlist you can act on, and tracks the applications you submit — nudging you to follow up when a posting goes quiet.

Privacy by design. This repository contains code, workflows and setup only. Your personal data — profile, CV, API keys, the application database — never lives in the repo. It lives under your XDG directories (~/.config/karyab, ~/.local/share/karyab). See AGENTS.md and docs/ARCHITECTURE.md.

What it does

 sources ──▶ normalize ──▶ store ──▶ rank ──▶ digest ──▶ you apply
                                                            │
                                                  track ◀───┘
                                                    │
                                            follow-up nudges
  • Fetch from ATS feeds (Greenhouse / Lever / Ashby), aggregator APIs (Adzuna / The Muse / Remotive), parsed email job-alerts, and remote-job boards.
  • Rank each posting for fit against your profile using an LLM, with a cheap pre-filter and a short human-readable reason per match.
  • Digest the top new matches into a daily Markdown file (and, later, an MCP server you query from inside Claude Code).
  • Track the jobs you apply to through a status lifecycle, and surface stale applications (applied, no response in N days) so you remember to follow up.

Status

Early scaffold. What actually runs today vs. what is planned is tracked honestly in docs/ROADMAP.md. Modules that are not yet implemented raise NotImplementedError rather than pretending to work.

Quick start

make is the single interface — it owns a local .venv, so you never manage dependencies by hand. make help lists everything.

make setup          # install + create config/secrets + init the database
make config         # edit your profile, sources, and keys (config + secrets)
make run            # fetch -> rank -> digest (the daily cycle)

Then, day to day:

make fetch          # pull + store postings from enabled sources
make rank           # score stored jobs for fit
make digest         # render the markdown shortlist
make show-digest    # print the latest digest
make followups      # applications gone quiet
make apply JOB=<id> # mark a job applied
make mcp            # run the MCP server for Claude Code

Schedule the daily fetch with a systemd user timer:

make timers-install # enable the daily timer   (make timers-status / -logs / -uninstall)

See docs/PLAN.md for the build plan and module interfaces.

Reading Outlook/Microsoft mail (OAuth2)

karyab supports OAuth2 device-code authentication for Microsoft IMAP (personal @outlook.com / @hotmail.com accounts, and work accounts with the right Azure permissions).

One-time setup:

  1. In ~/.config/karyab/config.toml, configure the email source:

    [sources.email]
    enabled = true
    imap_host  = "outlook.office365.com"
    folder     = "INBOX"
    username   = "you@outlook.com"
    auth       = "oauth"
    # oauth_client_id = "9e5f94bc-e8a4-4e73-b8be-63364c29d753"  # Thunderbird client (default)
    # oauth_authority = "https://login.microsoftonline.com/consumers"  # personal accounts
    
  2. Authenticate once:

    karyab email-auth
    # Prints a URL and a short code. Open the URL in your browser, enter the code.
    # karyab waits, then caches the refresh token in ~/.local/share/karyab/ms-token-cache.json
    
  3. Subsequent karyab fetch runs refresh the token silently — no browser needed.

If the default client ID stops working (Microsoft has restricted the Thunderbird public client in some regions), register a free Azure app: portal.azure.com → App registrations → New registration → allow public client flows → add delegated permission IMAP.AccessAsUser.All. Set the resulting Application ID as oauth_client_id in your config.

For Gmail and other providers, use auth = "basic" (default) and store your app password in ~/.config/karyab/secrets.toml.

Ranking with Claude Code (no API key)

Set [ranker] backend = "manual" in ~/.config/karyab/config.toml, then start the MCP server and ask Claude Code to rank your jobs:

[ranker]
backend = "manual"
make mcp   # starts karyab-mcp in stdio mode for Claude Code

In Claude Code, use the MCP tools:

  1. get_profile — review your candidate profile
  2. list_unranked_jobs — see jobs pending a score
  3. set_job_rank — score each job 0–100 with a short reason

After scoring, run make digest to build the shortlist from the scores you set.

Development

make dev            # install dev+runtime deps into .venv + git hooks
make test           # run tests
make check          # lint, format, type-check, secret-scan everything

Conventions, the no-secrets rule, and how data is laid out on disk live in AGENTS.md.

License

Apache-2.0.

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

karyab-0.1.0.tar.gz (132.2 kB view details)

Uploaded Source

Built Distribution

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

karyab-0.1.0-py3-none-any.whl (79.2 kB view details)

Uploaded Python 3

File details

Details for the file karyab-0.1.0.tar.gz.

File metadata

  • Download URL: karyab-0.1.0.tar.gz
  • Upload date:
  • Size: 132.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for karyab-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3e3275ee1c4dab00542f9245651b07d129b68ef4a2aecf8b97c39605b0b89950
MD5 c1379956f69b455c4c4ddb6cc5304c50
BLAKE2b-256 2a228ba3ea325f967426f2b12b9e2e9b7e557e43ce31777563d2389be1952653

See more details on using hashes here.

File details

Details for the file karyab-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: karyab-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 79.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for karyab-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b1eccf67f37ab67337de38f12a3063f7bdeb897b4b4100c00c14842b31a293e8
MD5 c7b4b69f4bd72ea78a98f02f149be1e0
BLAKE2b-256 149daca905d64cecbed59b4dd89f6a96c51d99b44a82456fd7af5e922f062b9c

See more details on using hashes here.

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