jobhunter-mcp 2.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. jobhunter_mcp-2.4.0/LICENSE +21 -0
  2. jobhunter_mcp-2.4.0/PKG-INFO +483 -0
  3. jobhunter_mcp-2.4.0/README.md +457 -0
  4. jobhunter_mcp-2.4.0/desktop.py +112 -0
  5. jobhunter_mcp-2.4.0/jh/__init__.py +2 -0
  6. jobhunter_mcp-2.4.0/jh/ai_manager.py +168 -0
  7. jobhunter_mcp-2.4.0/jh/ats.py +105 -0
  8. jobhunter_mcp-2.4.0/jh/autofill.py +1191 -0
  9. jobhunter_mcp-2.4.0/jh/bigtech_directory.py +254 -0
  10. jobhunter_mcp-2.4.0/jh/company_directory.py +351 -0
  11. jobhunter_mcp-2.4.0/jh/company_research.py +219 -0
  12. jobhunter_mcp-2.4.0/jh/config.py +216 -0
  13. jobhunter_mcp-2.4.0/jh/contacts.py +858 -0
  14. jobhunter_mcp-2.4.0/jh/db.py +2985 -0
  15. jobhunter_mcp-2.4.0/jh/dedup.py +376 -0
  16. jobhunter_mcp-2.4.0/jh/demo.py +36 -0
  17. jobhunter_mcp-2.4.0/jh/digest.py +91 -0
  18. jobhunter_mcp-2.4.0/jh/email_drafter.py +495 -0
  19. jobhunter_mcp-2.4.0/jh/email_finder.py +332 -0
  20. jobhunter_mcp-2.4.0/jh/evidence.py +488 -0
  21. jobhunter_mcp-2.4.0/jh/exporters.py +337 -0
  22. jobhunter_mcp-2.4.0/jh/extension_installer.py +245 -0
  23. jobhunter_mcp-2.4.0/jh/filestore.py +437 -0
  24. jobhunter_mcp-2.4.0/jh/founder_outreach.py +371 -0
  25. jobhunter_mcp-2.4.0/jh/freshness.py +50 -0
  26. jobhunter_mcp-2.4.0/jh/gmail_tracker.py +482 -0
  27. jobhunter_mcp-2.4.0/jh/home.py +164 -0
  28. jobhunter_mcp-2.4.0/jh/httpd.py +921 -0
  29. jobhunter_mcp-2.4.0/jh/interview.py +181 -0
  30. jobhunter_mcp-2.4.0/jh/lifecycle.py +201 -0
  31. jobhunter_mcp-2.4.0/jh/localize.py +157 -0
  32. jobhunter_mcp-2.4.0/jh/mcp_configurator.py +215 -0
  33. jobhunter_mcp-2.4.0/jh/mcp_helpers.py +220 -0
  34. jobhunter_mcp-2.4.0/jh/mcp_tools.py +1150 -0
  35. jobhunter_mcp-2.4.0/jh/models.py +328 -0
  36. jobhunter_mcp-2.4.0/jh/normalization.py +141 -0
  37. jobhunter_mcp-2.4.0/jh/observability.py +385 -0
  38. jobhunter_mcp-2.4.0/jh/outreach_ledger.py +383 -0
  39. jobhunter_mcp-2.4.0/jh/pipeline.py +1346 -0
  40. jobhunter_mcp-2.4.0/jh/preferences.py +306 -0
  41. jobhunter_mcp-2.4.0/jh/radar.py +297 -0
  42. jobhunter_mcp-2.4.0/jh/refit.py +1880 -0
  43. jobhunter_mcp-2.4.0/jh/refresh_scheduler.py +217 -0
  44. jobhunter_mcp-2.4.0/jh/regional_boards.py +47 -0
  45. jobhunter_mcp-2.4.0/jh/regions.py +237 -0
  46. jobhunter_mcp-2.4.0/jh/resume_parser.py +451 -0
  47. jobhunter_mcp-2.4.0/jh/resume_registry.py +197 -0
  48. jobhunter_mcp-2.4.0/jh/save_flow.py +426 -0
  49. jobhunter_mcp-2.4.0/jh/schemas.py +512 -0
  50. jobhunter_mcp-2.4.0/jh/scoring.py +1110 -0
  51. jobhunter_mcp-2.4.0/jh/screening.py +276 -0
  52. jobhunter_mcp-2.4.0/jh/signals.py +474 -0
  53. jobhunter_mcp-2.4.0/jh/skills.py +220 -0
  54. jobhunter_mcp-2.4.0/jh/source_policy.py +193 -0
  55. jobhunter_mcp-2.4.0/jh/source_registry.py +310 -0
  56. jobhunter_mcp-2.4.0/jh/sources/__init__.py +2350 -0
  57. jobhunter_mcp-2.4.0/jh/sources/adzuna.py +57 -0
  58. jobhunter_mcp-2.4.0/jh/sources/ashby.py +59 -0
  59. jobhunter_mcp-2.4.0/jh/sources/ats_boards.py +239 -0
  60. jobhunter_mcp-2.4.0/jh/sources/base.py +88 -0
  61. jobhunter_mcp-2.4.0/jh/sources/feeds.py +374 -0
  62. jobhunter_mcp-2.4.0/jh/sources/greenhouse.py +60 -0
  63. jobhunter_mcp-2.4.0/jh/sources/himalayas.py +57 -0
  64. jobhunter_mcp-2.4.0/jh/sources/jobicy.py +56 -0
  65. jobhunter_mcp-2.4.0/jh/sources/jooble.py +33 -0
  66. jobhunter_mcp-2.4.0/jh/sources/lever.py +59 -0
  67. jobhunter_mcp-2.4.0/jh/sources/linkedin_adapter.py +41 -0
  68. jobhunter_mcp-2.4.0/jh/sources/local.py +455 -0
  69. jobhunter_mcp-2.4.0/jh/sources/remotive.py +56 -0
  70. jobhunter_mcp-2.4.0/jh/sources/smartrecruiters.py +59 -0
  71. jobhunter_mcp-2.4.0/jh/sources/usajobs.py +63 -0
  72. jobhunter_mcp-2.4.0/jh/sources/workable_account.py +60 -0
  73. jobhunter_mcp-2.4.0/jh/team/__init__.py +5 -0
  74. jobhunter_mcp-2.4.0/jh/team/brief.py +60 -0
  75. jobhunter_mcp-2.4.0/jh/team/ceo.py +944 -0
  76. jobhunter_mcp-2.4.0/jh/team/claims.py +397 -0
  77. jobhunter_mcp-2.4.0/jh/team/directives.py +53 -0
  78. jobhunter_mcp-2.4.0/jh/team/evals.py +461 -0
  79. jobhunter_mcp-2.4.0/jh/team/intents_ext.py +211 -0
  80. jobhunter_mcp-2.4.0/jh/team/missions.py +90 -0
  81. jobhunter_mcp-2.4.0/jh/team/qa.py +455 -0
  82. jobhunter_mcp-2.4.0/jh/team/recall.py +83 -0
  83. jobhunter_mcp-2.4.0/jh/team/reflect.py +99 -0
  84. jobhunter_mcp-2.4.0/jh/team/roles.py +85 -0
  85. jobhunter_mcp-2.4.0/jh/team/router.py +309 -0
  86. jobhunter_mcp-2.4.0/jh/team/safety.py +124 -0
  87. jobhunter_mcp-2.4.0/jh/team/surface.py +34 -0
  88. jobhunter_mcp-2.4.0/jh/team/tools.py +305 -0
  89. jobhunter_mcp-2.4.0/jh/team/voice.py +184 -0
  90. jobhunter_mcp-2.4.0/jh/tracker.py +631 -0
  91. jobhunter_mcp-2.4.0/jh/util.py +543 -0
  92. jobhunter_mcp-2.4.0/jh/v5_tools.py +779 -0
  93. jobhunter_mcp-2.4.0/jh/workspace.py +377 -0
  94. jobhunter_mcp-2.4.0/jobhunter_mcp.egg-info/PKG-INFO +483 -0
  95. jobhunter_mcp-2.4.0/jobhunter_mcp.egg-info/SOURCES.txt +172 -0
  96. jobhunter_mcp-2.4.0/jobhunter_mcp.egg-info/dependency_links.txt +1 -0
  97. jobhunter_mcp-2.4.0/jobhunter_mcp.egg-info/entry_points.txt +3 -0
  98. jobhunter_mcp-2.4.0/jobhunter_mcp.egg-info/requires.txt +6 -0
  99. jobhunter_mcp-2.4.0/jobhunter_mcp.egg-info/top_level.txt +5 -0
  100. jobhunter_mcp-2.4.0/mcp_server.py +152 -0
  101. jobhunter_mcp-2.4.0/prompts/__init__.py +2 -0
  102. jobhunter_mcp-2.4.0/prompts/application_follow_up.md +89 -0
  103. jobhunter_mcp-2.4.0/prompts/career_skill_roadmap.md +86 -0
  104. jobhunter_mcp-2.4.0/prompts/cover_letter.md +96 -0
  105. jobhunter_mcp-2.4.0/prompts/interview_prep.md +91 -0
  106. jobhunter_mcp-2.4.0/prompts/mock_interview_evaluator.md +96 -0
  107. jobhunter_mcp-2.4.0/prompts/recruiter_outreach.md +91 -0
  108. jobhunter_mcp-2.4.0/prompts/resume_tailor.md +88 -0
  109. jobhunter_mcp-2.4.0/prompts/screening_question_solver.md +80 -0
  110. jobhunter_mcp-2.4.0/prompts/team/__init__.py +2 -0
  111. jobhunter_mcp-2.4.0/prompts/team/analyst.md +12 -0
  112. jobhunter_mcp-2.4.0/prompts/team/ceo.md +22 -0
  113. jobhunter_mcp-2.4.0/prompts/team/coach.md +25 -0
  114. jobhunter_mcp-2.4.0/prompts/team/ops.md +11 -0
  115. jobhunter_mcp-2.4.0/prompts/team/reviewer.md +12 -0
  116. jobhunter_mcp-2.4.0/prompts/team/scout.md +12 -0
  117. jobhunter_mcp-2.4.0/prompts/team/writer.md +23 -0
  118. jobhunter_mcp-2.4.0/prompts/voice.md +44 -0
  119. jobhunter_mcp-2.4.0/pyproject.toml +50 -0
  120. jobhunter_mcp-2.4.0/run.py +234 -0
  121. jobhunter_mcp-2.4.0/setup.cfg +4 -0
  122. jobhunter_mcp-2.4.0/tests/test_ai_manager.py +93 -0
  123. jobhunter_mcp-2.4.0/tests/test_auto_tailor_pipeline.py +112 -0
  124. jobhunter_mcp-2.4.0/tests/test_bigtech_directory.py +84 -0
  125. jobhunter_mcp-2.4.0/tests/test_blueprint_v2.py +643 -0
  126. jobhunter_mcp-2.4.0/tests/test_calibration_and_scoping.py +78 -0
  127. jobhunter_mcp-2.4.0/tests/test_desktop_launcher.py +26 -0
  128. jobhunter_mcp-2.4.0/tests/test_email_finder.py +63 -0
  129. jobhunter_mcp-2.4.0/tests/test_evals.py +38 -0
  130. jobhunter_mcp-2.4.0/tests/test_extension_bundle.py +35 -0
  131. jobhunter_mcp-2.4.0/tests/test_extension_installer.py +41 -0
  132. jobhunter_mcp-2.4.0/tests/test_filestore.py +142 -0
  133. jobhunter_mcp-2.4.0/tests/test_founder_outreach.py +131 -0
  134. jobhunter_mcp-2.4.0/tests/test_frontend_assets.py +28 -0
  135. jobhunter_mcp-2.4.0/tests/test_gmail_tracker.py +118 -0
  136. jobhunter_mcp-2.4.0/tests/test_httpd.py +198 -0
  137. jobhunter_mcp-2.4.0/tests/test_httpd_ai_routes.py +126 -0
  138. jobhunter_mcp-2.4.0/tests/test_httpd_resume_upload.py +149 -0
  139. jobhunter_mcp-2.4.0/tests/test_job_package.py +63 -0
  140. jobhunter_mcp-2.4.0/tests/test_latest_models.py +33 -0
  141. jobhunter_mcp-2.4.0/tests/test_local_sources.py +237 -0
  142. jobhunter_mcp-2.4.0/tests/test_mcp_server.py +263 -0
  143. jobhunter_mcp-2.4.0/tests/test_mcp_tools.py +332 -0
  144. jobhunter_mcp-2.4.0/tests/test_phase_b10_signals.py +171 -0
  145. jobhunter_mcp-2.4.0/tests/test_phase_b11_company_research.py +155 -0
  146. jobhunter_mcp-2.4.0/tests/test_phase_b12_contacts.py +267 -0
  147. jobhunter_mcp-2.4.0/tests/test_phase_b13_email_and_slop.py +192 -0
  148. jobhunter_mcp-2.4.0/tests/test_phase_b14_outreach.py +247 -0
  149. jobhunter_mcp-2.4.0/tests/test_phase_b1_workspace.py +148 -0
  150. jobhunter_mcp-2.4.0/tests/test_phase_b2_database.py +348 -0
  151. jobhunter_mcp-2.4.0/tests/test_phase_b3_search_filters.py +241 -0
  152. jobhunter_mcp-2.4.0/tests/test_phase_b4_mcp_tools.py +189 -0
  153. jobhunter_mcp-2.4.0/tests/test_phase_b5_radar.py +160 -0
  154. jobhunter_mcp-2.4.0/tests/test_phase_b6_refresh.py +118 -0
  155. jobhunter_mcp-2.4.0/tests/test_phase_b7_lifecycle.py +237 -0
  156. jobhunter_mcp-2.4.0/tests/test_phase_b8_save_flow.py +305 -0
  157. jobhunter_mcp-2.4.0/tests/test_phase_b9_method.py +125 -0
  158. jobhunter_mcp-2.4.0/tests/test_pipeline.py +124 -0
  159. jobhunter_mcp-2.4.0/tests/test_preferences_autofill_and_cities.py +100 -0
  160. jobhunter_mcp-2.4.0/tests/test_profiles_api_sync.py +119 -0
  161. jobhunter_mcp-2.4.0/tests/test_prompt_contract.py +100 -0
  162. jobhunter_mcp-2.4.0/tests/test_prompts.py +297 -0
  163. jobhunter_mcp-2.4.0/tests/test_protected_linkedin.py +23 -0
  164. jobhunter_mcp-2.4.0/tests/test_regions_and_preferences.py +142 -0
  165. jobhunter_mcp-2.4.0/tests/test_resume_drop_folder.py +54 -0
  166. jobhunter_mcp-2.4.0/tests/test_run_and_mcp_config.py +89 -0
  167. jobhunter_mcp-2.4.0/tests/test_security.py +42 -0
  168. jobhunter_mcp-2.4.0/tests/test_sources.py +257 -0
  169. jobhunter_mcp-2.4.0/tests/test_team.py +515 -0
  170. jobhunter_mcp-2.4.0/tests/test_team_v23.py +456 -0
  171. jobhunter_mcp-2.4.0/tests/test_text_parsing.py +36 -0
  172. jobhunter_mcp-2.4.0/tests/test_tracker_partial_upsert.py +48 -0
  173. jobhunter_mcp-2.4.0/tests/test_workspace.py +88 -0
  174. jobhunter_mcp-2.4.0/tests/test_workspace_isolation_and_mode.py +156 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 JobHunter Maintainers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,483 @@
1
+ Metadata-Version: 2.4
2
+ Name: jobhunter-mcp
3
+ Version: 2.4.0
4
+ Summary: MCP server for job search: many sources, resume-grounded scoring, truthful document tailoring, application tracking
5
+ Author: JobHunter Maintainers
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/ErenYea9er69/jobhunter
8
+ Project-URL: Repository, https://github.com/ErenYea9er69/jobhunter
9
+ Project-URL: Bug Tracker, https://github.com/ErenYea9er69/jobhunter/issues
10
+ Keywords: mcp,model-context-protocol,job-search,resume,ats
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Topic :: Office/Business
17
+ Requires-Python: >=3.11
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: mcp[cli]<2,>=1.9
21
+ Requires-Dist: curl_cffi>=0.7
22
+ Requires-Dist: pypdf>=4.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=8.0; extra == "dev"
25
+ Dynamic: license-file
26
+
27
+ # JobHunter MCP Server
28
+ <!-- mcp-name: io.github.ErenYea9er69/jobhunter -->
29
+
30
+ JobHunter gives an AI assistant (Claude Desktop, Cursor, Antigravity, VS Code) tools for a full job search. It searches many sources, scores each job against your real resume, writes application documents from facts in that resume, and tracks every application. All data stays on your machine.
31
+
32
+ JobHunter works like a small company. You talk to one AI, and that AI is the CEO. It briefs a team of specialists (Scout, Analyst, Writer, Coach, Chief of Staff). A Reviewer checks every job and document before you see it. See `docs/team.md`.
33
+
34
+ By default the AI sees seven CEO tools. The 39 specialist tools sit behind them. `--surface full` shows all 46. There are no MCP prompts. The old prompt contracts are the `get_playbook` tool.
35
+
36
+ ## Quick start
37
+
38
+ ### 🚀 1-Command Run (Zero Clone, Zero Setup)
39
+
40
+ You **do not need to clone this repository** to run JobHunter with your AI assistant. Modern MCP environments run it directly with a single command via `uvx` (the fast, zero-install runner from Astral) or Smithery:
41
+
42
+ #### 1. Instant Terminal / Verification Run
43
+ ```bash
44
+ uvx --from git+https://github.com/ErenYea9er69/jobhunter jobhunter-mcp --check
45
+ ```
46
+ *(When published on PyPI, this is simply `uvx jobhunter-mcp`)*
47
+
48
+ #### 2. Claude Desktop Integration
49
+ Add JobHunter to your `claude_desktop_config.json`:
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "jobhunter": {
54
+ "command": "uvx",
55
+ "args": [
56
+ "--from",
57
+ "git+https://github.com/ErenYea9er69/jobhunter",
58
+ "jobhunter-mcp"
59
+ ]
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ #### 3. Cursor Integration (`.cursor/mcp.json` or Global Settings)
66
+ ```json
67
+ {
68
+ "mcpServers": {
69
+ "jobhunter": {
70
+ "command": "uvx",
71
+ "args": [
72
+ "--from",
73
+ "git+https://github.com/ErenYea9er69/jobhunter",
74
+ "jobhunter-mcp"
75
+ ]
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ #### 4. Smithery Integration
82
+ ```bash
83
+ npx -y @smithery/cli run @ErenYea9er69/jobhunter
84
+ ```
85
+ Or 1-click install directly into Claude Desktop:
86
+ ```bash
87
+ npx -y @smithery/cli install @ErenYea9er69/jobhunter --client claude
88
+ ```
89
+
90
+ ---
91
+
92
+ ### 🛠️ Developer Setup & Local Copilot Suite (Optional)
93
+
94
+ Clone only if you are developing JobHunter, customizing the codebase, or using the standalone local Web Dashboard and Chromium extension:
95
+
96
+ ```bash
97
+ git clone https://github.com/ErenYea9er69/jobhunter.git
98
+ cd jobhunter
99
+ pip install -r requirements.txt
100
+ ```
101
+
102
+ #### Run on Windows:
103
+ Double-click `run.bat` or execute in PowerShell / CMD:
104
+ ```cmd
105
+ run.bat
106
+ # or
107
+ python run.py
108
+ ```
109
+
110
+ #### Run on macOS & Linux:
111
+ ```bash
112
+ chmod +x run.sh
113
+ ./run.sh
114
+ # or
115
+ python3 run.py
116
+ ```
117
+
118
+ #### Launcher CLI Options:
119
+ ```bash
120
+ python run.py [OPTIONS]
121
+ --port PORT Port for HTTP daemon (default: 8765)
122
+ --host HOST Host to bind to (default: 127.0.0.1)
123
+ --no-browser Do not auto-launch Chromium with extension
124
+ --setup-only Provision directories, DB, and MCP configs, then exit
125
+ --set-key KEY Store API key for Standalone Direct API mode
126
+ --provider PROVIDER AI Provider (gemini, openai, anthropic, deepseek, groq, mistral)
127
+ --model MODEL Target model (e.g. gemini-3.8-flash, gpt-5-mini, claude-3-7-sonnet)
128
+ --clear-key Delete stored API keys and return to MCP mode
129
+ --ai-status Display active AI provider, mode, and masked key
130
+ --test-ai Test connection to the active AI endpoint and measure latency
131
+ ```
132
+
133
+ #### What happens automatically:
134
+ 1. **Candidate Drop Folder Provisioned**: Auto-creates `resumes/` with a `PUT_YOUR_RESUME_HERE.txt` guide. Drop your Word (**`.docx`**), PDF (**`.pdf`**), or Text (**`.txt`**, **`.md`**) resume right into this folder.
135
+ 2. **SQLite Database Initialized**: Automatically creates your private local database (`engine.db`) in `~/.jobhunter/` or your workspace.
136
+ 3. **AI Coding Agents Auto-Connected (MCP)**: Auto-detects and writes MCP configuration for **Cursor** (`.cursor/mcp.json`) and **Claude Desktop** so your AI assistant shares the exact same resume facts and tracking database.
137
+ 4. **Web Dashboard Served**: Starts the local HTTP daemon and serves the 6-tab autonomous dashboard on `http://127.0.0.1:8765`.
138
+ 5. **Browser Extension Loaded**: Detects your installed Chromium browser (Google Chrome, Microsoft Edge, Brave) and launches it with the ATS Autofill extension preloaded (`--load-extension`).
139
+ 6. **First-Run Web Drop Wizard**: If no resume exists yet, the web dashboard displays a drag-and-drop wizard allowing you to upload your Word, PDF, or Text resume directly from the browser with instant skill extraction.
140
+
141
+ ---
142
+
143
+ ### 🖥️ Modern Web Dashboard & Visual Workspace
144
+
145
+ JobHunter includes a responsive, dark/light themed single-page web application running locally on `http://127.0.0.1:8765`. The interface uses a black, gray and white theme with small green, amber and red score colors. See `DESIGN.md` and `UI-CHANGES.md`:
146
+
147
+ ```
148
+ ┌────────────────────────────────────────────────────────────────────────┐
149
+ │ JOBHUNTER DASHBOARD │
150
+ ├───────────────┬───────────────────────────────┬────────────────────────┤
151
+ │ TAB 1: RADAR │ TAB 2: PIPELINE KANBAN │ TAB 3: DOCUMENT STUDIO │
152
+ │ Opportunity │ 5-Stage Visual Funnel │ 100% Truthful QA │
153
+ │ Discovery │ Saved → Applied → Interview │ Cover Letters & Pitch │
154
+ ├───────────────┼───────────────────────────────┼────────────────────────┤
155
+ │ TAB 4: PROFILE│ TAB 5: AI & CALIBRATION │ TAB 6: AUTO-APPLY HUB │
156
+ │ Resume Drop │ Dual Engine (MCP vs API) │ ATS Extension Dispatch │
157
+ │ & Variants │ 2026 Frontier Models │ 1-Click Browser Launch │
158
+ └───────────────┴───────────────────────────────┴────────────────────────┘
159
+ ```
160
+
161
+ #### Tab 1: Radar & Opportunity Discovery
162
+ - **Multi-Source Aggregation**: Real-time unified search across 100+ platforms (Company Greenhouse/Ashby/Lever boards, Y Combinator, Hacker News, regional national sites, and remote boards).
163
+ - **Match Scoring Engine (0-100%)**: Every posting is ranked strictly against the candidate's verified skills, experience level, and target preferences.
164
+ - **Smart Filters**: Filter instantaneously by Work Mode (Remote, Hybrid, Onsite), Job Type (Full-time, Internship/PFE, Contract), and Score Floor.
165
+ - **1-Click Queue Auto-Apply**: Queue promising opportunities directly into the Auto-Apply batch runner.
166
+
167
+ #### Tab 2: Application Kanban Pipeline
168
+ - **Visual Funnel Tracking**: 5 automated progression lanes: `Saved` → `Queued Auto-Apply` → `Applied` → `Interviewing` → `Offers`.
169
+ - **Gmail Sync Integration**: 1-click sync scans your connected inbox for ATS confirmations, interview invitations, and status updates, automatically transitioning opportunities across lanes without manual entry.
170
+ - **Application Analytics**: Tracks submission velocity, response rates, and active interview conversions.
171
+
172
+ #### Tab 3: Truthful Document Studio & Copilot
173
+ - **Multi-Format Document Generation**:
174
+ - **Cover Letters**: Direct-impact, metrics-driven pitches tailored to the job description.
175
+ - **YC-Style Founder Cold Emails**: High-converting, short pitches with an automated **Founder Corporate Email Finder** that synthesizes and verifies executive email formats.
176
+ - **Big Tech Recruiter & Internal Referrals**: Calibrated for levels and terminology at Google (L3-L6), Meta (E3-E6), Uber, Amazon, Apple, Microsoft, Netflix, and Stripe.
177
+ - **STAR Interview Guides**: Complete preparation matrices with Situation, Task, Action, and Result outlines grounded in your actual work history.
178
+ - **Reviewer QA Badge**: Every generated paragraph is audited sentence-by-sentence against candidate resume facts before approval. Unsupported claims are rejected or flagged with zero hallucinations.
179
+ - **Direct Export**: 1-click Copy, Print to PDF, or "Open in Gmail" prefilled draft.
180
+
181
+ #### Tab 4: Candidate Profile & Resume Variants
182
+ - **Master Profile Display**: Visual hero card showing extracted coordinates, verified skills chips, and reverse-chronological professional timeline.
183
+ - **First-Run Drop Folder & Drag-and-Drop Web Wizard**: Upload Word (**`.docx`**), PDF (**`.pdf`**), or Text (**`.txt`**, **`.md`**) resumes directly in the browser or drop them into `resumes/`.
184
+ - **Variant Management**: Switch between specialized resume variants (e.g. Backend vs AI Engineer) with one click; all ranking and generation immediately recalibrate.
185
+
186
+ #### Tab 5: Search Calibration & AI Dual Engine
187
+ - **Target Filtering**: Configure target countries (e.g., Tunisia, France, Germany, Worldwide Remote), preferred cities, work mode, and search depth.
188
+ - **Dream & Excluded Companies**: Boost priority for dream employers; permanently blacklist companies and unwanted technologies.
189
+ - **AI Engine Control Deck**: Live mode badge (`Direct API Active` vs `External MCP Host Mode`), provider selector, 2026 frontier model picker, masked key display, latency test, and 1-click key wipe.
190
+
191
+ #### Tab 6: Auto-Apply & Desktop Hub
192
+ - **Queue Dispatcher**: Automatically iterates through queued applications and launches the autofill sequence.
193
+ - **Work Authorization & Visa Compliance**: Sets deterministic rules for legal authorization, sponsorship requirements, and notice period.
194
+ - **1-Click Chromium Launcher**: Detects your installed Chrome, Edge, or Brave browser and boots it with the JobHunter extension active.
195
+
196
+ ---
197
+
198
+ ### 🧩 Chrome ATS Autofill Extension
199
+
200
+ Located in `extension/`, the JobHunter extension turns your browser into an automated job application copilot:
201
+
202
+ - **Manifest V3 Architecture**: Fast, lightweight, and operates entirely against your local daemon (`http://127.0.0.1:8765`).
203
+ - **Supported ATS Platforms**:
204
+ - Greenhouse (`boards.greenhouse.io`)
205
+ - Lever (`jobs.lever.co`)
206
+ - Ashby (`jobs.ashbyhq.com`)
207
+ - Workday (`*.myworkdayjobs.com`)
208
+ - SmartRecruiters, Recruitee, Workable, and custom employer career portals.
209
+ - **Smart Form Autofill**: Instantly populates personal coordinates, resume attachments, LinkedIn, GitHub, portfolio URLs, and work authorization disclosures.
210
+ - **Grounded Screening Question Solver**: Intercepts custom employer questions (e.g., *"Describe a time you solved an architectural bottleneck"*, *"What is your experience with Kubernetes?"*) and formulates accurate answers drawn solely from candidate facts in SQLite.
211
+ - **Review panel**: A panel on the page lists every filled field with an Undo, lists fields that need you, and never submits unless you chose countdown mode.
212
+
213
+ ---
214
+
215
+ ---
216
+
217
+ ### 🔀 Dual Execution Modes: External MCP Host vs. Standalone Direct API
218
+
219
+ JobHunter operates seamlessly in two distinct modes, and you can switch between them at any time:
220
+
221
+ ```
222
+ ┌────────────────────────────────────────────────────────────────────────┐
223
+ │ MODE 1: EXTERNAL MCP HOST │
224
+ │ Zero API keys required in JobHunter! │
225
+ │ Claude Desktop or Cursor runs its own frontier LLM model │
226
+ │ and talks to JobHunter via MCP stdio tools. │
227
+ └────────────────────────────────────┬───────────────────────────────────┘
228
+ │ (Switch dynamically anytime)
229
+ ┌────────────────────────────────────▼───────────────────────────────────┐
230
+ │ MODE 2: STANDALONE DIRECT API │
231
+ │ No external AI IDE needed! Clone and supply your own API key. │
232
+ │ Powers the Web Dashboard & Chrome Extension directly via SQLite. │
233
+ │ Supports Gemini 3.8 Flash, GPT-5 Mini, Claude 3.7 Sonnet, etc. │
234
+ └────────────────────────────────────────────────────────────────────────┘
235
+ ```
236
+
237
+ #### Mode 1: External MCP Host Mode (Zero Keys Needed)
238
+ - If you use **Claude Desktop**, **Cursor**, **Antigravity**, or **Claude Code**, you **do NOT need to supply any API keys**.
239
+ - The AI IDE hosts the conversation and passes context to JobHunter's tools over stdio.
240
+ - All documents, tailoring, and scoring run through JobHunter's strict offline Reviewer QA engine.
241
+
242
+ #### Mode 2: Standalone Direct API Mode (Web Dashboard & Chrome Extension)
243
+ - If you want to use the Web Dashboard and ATS Autofill extension independently without running Claude Desktop or Cursor, you can supply your API key directly via CLI or Web UI.
244
+ - Your key is stored securely in your private local SQLite database (`engine.db`) and is **never** sent to external telemetry or exposed in logs.
245
+
246
+ ##### Configure via Command Line (Windows, macOS, Linux):
247
+ ```bash
248
+ # 1. Activate Google Gemini (Default frontier: gemini-3.8-flash)
249
+ python run.py --set-key YOUR_GEMINI_API_KEY --provider gemini --model gemini-3.8-flash
250
+
251
+ # 2. Activate OpenAI (Default frontier: gpt-5-mini or o3-mini)
252
+ python run.py --set-key YOUR_OPENAI_API_KEY --provider openai --model gpt-5-mini
253
+
254
+ # 3. Activate Anthropic Claude (Default frontier: claude-3-7-sonnet)
255
+ python run.py --set-key YOUR_ANTHROPIC_API_KEY --provider anthropic --model claude-3-7-sonnet
256
+
257
+ # 4. Activate DeepSeek
258
+ python run.py --set-key YOUR_DEEPSEEK_KEY --provider deepseek --model deepseek-chat
259
+
260
+ # 5. Check active mode & masked key
261
+ python run.py --ai-status
262
+
263
+ # 6. Test connection latency and endpoint health
264
+ python run.py --test-ai
265
+ ```
266
+
267
+ ##### Configure via Web Dashboard:
268
+ 1. Open `http://127.0.0.1:8765` in your browser.
269
+ 2. Navigate to the **Calibration & Filters** tab.
270
+ 3. In the **AI Engine & Dual Execution Mode** card:
271
+ - Select your provider (**Google Gemini**, **OpenAI**, **Anthropic**, **DeepSeek**, **Groq**, **Mistral**, or local **Ollama**).
272
+ - Pick a model or enter a custom identifier.
273
+ - Paste your key and click **Save & Activate**.
274
+ - Click **Test Connection** to verify round-trip ping and latency.
275
+
276
+ #### Reverting to MCP Mode / Deleting Your Key:
277
+ You can wipe your stored API key at any time to return JobHunter to External MCP / Deterministic mode:
278
+ ```bash
279
+ # Via CLI:
280
+ python run.py --clear-key
281
+
282
+ # Or via Web Dashboard:
283
+ Click the "Clear Key" button in Tab 5 (Calibration & Filters)
284
+ ```
285
+
286
+ #### 2026 Frontier Models Supported:
287
+ - **Google Gemini**: `gemini-3.8-flash` (recommended default), `gemini-3.1-pro`, `gemini-3.5-flash`
288
+ - **OpenAI**: `gpt-5-mini` (recommended default), `o3-mini`, `gpt-5`
289
+ - **Anthropic**: `claude-3-7-sonnet` (recommended default), `claude-3-5-haiku`
290
+ - **DeepSeek**: `deepseek-chat`, `deepseek-reasoner`
291
+ - **Groq**: `llama-3.3-70b-versatile`, `qwen-2.5-coder-32b`
292
+ - **Mistral**: `mistral-large-latest`
293
+ - **Ollama**: `llama3.3`, `deepseek-r1` (local, zero cloud keys)
294
+
295
+ ---
296
+
297
+ ---
298
+
299
+ ### Alternative: Standalone MCP Server via uvx
300
+
301
+ If you only want the stdio MCP server without the web dashboard:
302
+
303
+ ```bash
304
+ uvx --from git+https://github.com/ErenYea9er69/jobhunter jobhunter-mcp
305
+ ```
306
+
307
+ ### Claude Code CLI
308
+
309
+ Add JobHunter directly with the Claude CLI:
310
+
311
+ ```bash
312
+ claude mcp add jobhunter -- uvx --from git+https://github.com/ErenYea9er69/jobhunter jobhunter-mcp
313
+ ```
314
+
315
+ ### Claude Desktop Configuration
316
+
317
+ Add the server to your `claude_desktop_config.json`:
318
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
319
+ - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
320
+
321
+ ```json
322
+ {
323
+ "mcpServers": {
324
+ "jobhunter": {
325
+ "command": "uvx",
326
+ "args": [
327
+ "--from",
328
+ "git+https://github.com/ErenYea9er69/jobhunter",
329
+ "jobhunter-mcp"
330
+ ],
331
+ "env": {
332
+ "JH_DATA_DIR": ""
333
+ }
334
+ }
335
+ }
336
+ }
337
+ ```
338
+
339
+ *(Leave `JH_DATA_DIR` empty to default to `~/.jobhunter`, or provide a custom directory path).*
340
+
341
+ ### Local Development
342
+
343
+ ```bash
344
+ pip install -r requirements.txt
345
+ python mcp_server.py --check # starts the server, lists the tools, exits
346
+ ```
347
+
348
+ Put a PDF, DOCX or TXT resume in your workspace folder (or in `resumes/`), or use `scan_resumes` / `parse_resume_file`. Local configuration can also be pointed at a workspace:
349
+
350
+ ```json
351
+ {
352
+ "mcpServers": {
353
+ "jobhunter": {
354
+ "command": "python",
355
+ "args": ["/absolute/path/to/jobhunter/mcp_server.py"],
356
+ "env": { "JH_WORKSPACE": "/absolute/path/to/your/workspace" }
357
+ }
358
+ }
359
+ }
360
+ ```
361
+
362
+ First conversation. Just talk to the AI:
363
+
364
+ 1. "Set me up. I want to work in Tunisia and France." The CEO reads your resumes and saves your preferences.
365
+ 2. "Find backend engineer jobs." The Scout searches, the Reviewer checks each job and reads the top posting pages.
366
+ 3. "Find small companies hiring python developers in Sfax." Same, with a bias toward small and local employers.
367
+ 4. "Write a cover letter for the second one." or "...for the Adyen job." The CEO resolves the pointer against the last list. The Writer drafts. The Reviewer checks every sentence against your resume.
368
+ 5. "I applied to Adyen." "Not interested in banks." "Why is the fit low for the first one?" The CEO updates your tracker or your exclusions, then reads the change back to confirm it. Or it explains the score.
369
+
370
+ The answer is a short brief. The full report and data are behind it. Every answer says what was not verified. Nothing is submitted for you.
371
+
372
+ ## Make it yours
373
+
374
+ `set_preferences` stores your choices in `.jobhunter/preferences.json`. They apply to every resume and every search.
375
+
376
+ | Key | Meaning |
377
+ | --- | --- |
378
+ | `target_countries` | Where you want to work, for example `["Tunisia", "France", "Germany"]`. Picks the local sources. |
379
+ | `home_country`, `cities` | Where you live and the cities you prefer. |
380
+ | `work_mode` | `Any`, `Remote`, `Hybrid` or `Onsite`. Onsite skips remote-only boards. |
381
+ | `target_titles` | Roles to search. The first is the main one. |
382
+ | `min_salary`, `salary_currency` | A yearly floor. Salaries in TND, MAD, EGP, AED and SAR are read as monthly figures. |
383
+ | `job_types`, `seniority` | Full-time, Contract, Internship. Junior to director. |
384
+ | `excluded_keywords`, `excluded_companies`, `dream_companies` | Hide or boost. |
385
+ | `company_focus` | `any`, `avoid_big_names` or `only_big_names`. |
386
+ | `max_age_days` | Hide postings older than this. Default 30. |
387
+ | `search_depth` | `quick`, `standard` or `deep` (more query variants). |
388
+ | `enabled_sources`, `disabled_sources` | Choose exactly which sources run. |
389
+ | `needs_visa_sponsorship`, `open_to_relocation`, `languages` | Stored and applied to the resume profile. |
390
+
391
+ Example: `set_preferences({"target_countries": ["Tunisia", "France"], "company_focus": "avoid_big_names", "excluded_keywords": ["php"]})`.
392
+
393
+ ## Where the jobs come from
394
+
395
+ Which sources run depends on your target countries. A search from Tunisia no longer calls India's Naukri or France's HelloWork. A search that targets France calls HelloWork and `fr.indeed.com`.
396
+
397
+ | Source | Serves | Notes |
398
+ | --- | --- | --- |
399
+ | Company Boards | Worldwide | Greenhouse, Lever (US and EU), Ashby, Workable, SmartRecruiters, Recruitee, Personio, Teamtailor, BambooHR, Breezy |
400
+ | Y Combinator, Hacker News | Worldwide | Hacker News now reads three pages of the monthly thread |
401
+ | LinkedIn | Worldwide | Unchanged. See "Protected code" below |
402
+ | Indeed | 41 countries | One call per target country, on the local site |
403
+ | Bayt | Middle East and North Africa | One call per target country |
404
+ | Arbeitsagentur | Germany | Public employment service, no key |
405
+ | HelloWork, Naukri, ZipRecruiter | France, India, US and Canada | |
406
+ | Adzuna | 19 countries | Needs a free key (`ADZUNA_APP_ID`, `ADZUNA_APP_KEY`) |
407
+ | Regional Boards | Tunisia, Morocco, Algeria, Egypt, Nigeria, Kenya, South Africa | Local boards (Keejob, ReKrute, Wuzzuf and others) read through their job data and sitemaps. Tries local-language queries too |
408
+ | Jooble | Many countries | Aggregator that collects small local boards. Needs a free key (`JOOBLE_API_KEY`) |
409
+ | JobTech | Sweden | Public employment service, no key |
410
+ | Himalayas, Remotive, Jobicy, RemoteOK, We Work Remotely, Working Nomads | Remote | Skipped when you want onsite work |
411
+ | Arbeitnow, The Muse | Europe, US and UK | |
412
+ | Custom Feed, Career Page, Job Sites | Anywhere you point them | Added with `add_job_source` |
413
+
414
+ ### Reaching small and regional employers
415
+
416
+ The big boards show the same famous names. These features reach the rest:
417
+
418
+ - `add_job_source(kind="company", value="Acme")` finds the company's public board by name, or reads a careers URL directly. Every open role is searched.
419
+ - `add_job_source(kind="feed", value=<rss url>)` adds any RSS, Atom or JSON feed, such as a national job board. The feed is test-read before it is saved.
420
+ - `add_job_source(kind="career_page", value=<url>)` reads schema.org job data on a careers page, or follows an embedded ATS link.
421
+ - `add_job_source(kind="site", value=<url>)` adds a small job board or any site that publishes schema.org job data (what Google for Jobs reads). The reader finds job pages through the sitemap and the page's links. It obeys `robots.txt` and refuses a site that forbids reading, even with `force`. Not sure which kind to use? `discover_job_source(url)` explains how a site can be read and adds nothing.
422
+ - Regional Boards runs the catalog in `jh/regional_boards.py` for your target countries. Queries are also sent in French for countries where local boards post in French ("software engineer" also searches "ingénieur logiciel").
423
+ - Pinpoint is a new company board type, so small employers on that system are found by name.
424
+ - Boards discovered along the way: every job link that points at a known ATS adds that company's board to later searches. Each search teaches the next one. Boards that fail three times rest for 24 hours.
425
+
426
+ The built-in starter list of company boards is short and its slugs are unverified. Dead ones prune themselves.
427
+
428
+ Honest limits of this reach: the catalog names real local boards, but nobody has checked here which of them publish readable job data or allow reading. A board that does not shows zero in `source_health`. Add your own with `kind="site"`. A site that builds its job list with scripts cannot be read this way. Use `kind="company"` if the employer uses a known ATS.
429
+
430
+ ## Tools
431
+
432
+ The full list with arguments is in `docs/tool-contracts.md`. The CEO tools (`ceo_run` and six more) are described in `docs/team.md`. Specialist groups: resumes (5), preferences and sources (7), finding jobs (4), analysis (5), documents (7), interview and outreach (4), playbooks (1), tracking (5), server (1).
433
+
434
+ Every tool returns one envelope: `status` (`ok`, `partial`, `error`), `success`, `data`, `warnings`, `sources`, `correlation_id`. Errors carry a `code` and a `hint`. Search results are compact cards, so a search never floods the model's context. Use the `job_id` from a card with any tool.
435
+
436
+ ## Truthful by design
437
+
438
+ - The Reviewer does not trust the employee who made the work. It checks every job (fields, link, date, country, duplicates, matched skills, scams, text aimed at your AI), reads live posting pages, and checks every document sentence against your resume. Invented employers, titles, degrees, certifications, skills, numbers and awards are removed or rejected. Details in `docs/team.md`.
439
+ - The Reviewer is measured. `python -m jh.team.evals` scores it on fixed cases, and `docs/evals.md` reports the numbers and how far to trust them. The honest estimate on text it has never seen is lower than the scores on the cases it was built with.
440
+ - The CEO's report comes from tool results only, and every job and document names the call that produced it.
441
+ - The prompts follow their own rules. A linter checks every prompt for dashes, capital-letter shouting, persona boasting and invented statistics, and a test checks that each playbook asks the model for the keys the code reads. Drafts are scanned for machine-sounding phrases, and the Reviewer warns about them. See `docs/prompts.md`.
442
+ - When a search finds nothing, the CEO widens it in steps and then says so. It does not fill the gap.
443
+ - Generated text uses only facts the resume supports. `get_evidence` lists them.
444
+ - `verify_draft` checks any text against that evidence and flags unsupported claims. `tailor_resume`, `cover_letter` and `prepare_application` run the same check and return the result.
445
+ - Tools never accept or return API keys. Optional LLM keys come from environment variables (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY` and others). Without a key the deterministic engine writes the documents.
446
+
447
+ ## Your data
448
+
449
+ Everything lives in your user home directory at `~/.jobhunter/` by default, or the folder configured via the `JH_DATA_DIR` environment variable.
450
+
451
+ - `engine.db` is the SQLite database: resumes, stored jobs, applications, watchlist, board health.
452
+ - `preferences.json` holds your preferences, feeds and career pages.
453
+ - `output/` holds adapted resumes, cover letters, interview prep and exports.
454
+
455
+ Applications live in SQLite. Any old `applications.json` is imported once and renamed.
456
+
457
+ ## Protected code
458
+
459
+ The LinkedIn scraper (`LinkedInGuest`), the LinkedIn radar in `jh/pipeline.py`, and its two config getters are not to be edited. `tests/test_protected_linkedin.py` checks them byte for byte. The radar's background workers are not started by the MCP server. See `AGENTS.md`.
460
+
461
+ ## Tests
462
+
463
+ ```bash
464
+ pip install -r requirements-dev.txt
465
+ python -m pytest tests -q
466
+ ```
467
+
468
+ The suite runs offline. A fake network serves fixtures that pin each vendor's response format. Live behaviour of the newer adapters (Recruitee, Personio, Teamtailor, BambooHR, Breezy, Working Nomads, The Muse, Arbeitsagentur, Jooble, JobTech, Pinpoint) and of the regional boards was not checked against real servers. The site reader and the Reviewer's link check follow public standards (schema.org JobPosting, sitemaps, robots.txt) and are tested against fixtures. `source_health` shows any adapter whose format has drifted.
469
+
470
+ ## Known limits
471
+
472
+ - Job IDs ignore location, so one title at one company in two cities shares an ID. The LinkedIn radar uses the same key, so it was left alone.
473
+ - Salary comparison does not convert currencies.
474
+ - The CEO's request router is rule-based. It reads English and French, and a few Arabic words. On phrasings it had never seen, it was right about two times in three. An unclear request makes the CEO ask. The AI should pass `hints.intent` and `hints.reference` so nothing is guessed.
475
+ - The Reviewer is also rules, not a model. It was built to catch what language models tend to invent. A new kind of fabrication can get through. Facts about the employer beyond the posting cannot be checked at all, so they are flagged.
476
+ - When no model writes the text, the code's own templates do, and some still contain stock phrases (the outreach, follow-up and screening templates). The Reviewer flags them. They are listed in `docs/prompts.md`.
477
+ - Only the top five jobs of a search get a live link check. Ask the CEO to recheck one before you apply.
478
+ - Several scrapers return an empty list instead of an error when blocked, so `source_health` shows them as ok with zero results.
479
+ - Reading some boards (LinkedIn, Indeed, ZipRecruiter and others) uses browser-like requests. See `docs/data-policy.md` and use `disabled_sources` if you do not want that.
480
+
481
+ ## License
482
+
483
+ MIT. See `LICENSE`.