Self-hosted career copilot and job search tracker for students and early-career professionals who want one place to manage skills, applications, resume feedback, and next steps.
kelsa.ai is a FastAPI-based career copilot and resume analysis app with a single-page frontend for students and early-career professionals. It helps you track skills, projects, applications, resume feedback, and personalized career guidance in one lightweight self-hosted workflow.
kelsa.ai helps students and early-career professionals organize job-search information such as skills, projects, applications, resume notes, and advisor conversations. It is for people who want a lightweight career copilot they can run locally without setting up a separate frontend build system or database on day one. The project makes personal career tracking easy to start with local JSON storage while leaving room for Hindsight-backed memory as your workflow becomes more advanced. It stands out by combining browser-based account flows, structured career records, and automation-friendly endpoints in a small self-hosted FastAPI app.
- Sign in through a browser-based account flow and keep each user's records isolated with signed sessions.
- Track skills, projects, applications, resume analysis, dashboard summaries, and advisor chats in one place.
- Review your job-search progress without stitching together separate spreadsheets, notes, and prompts.
- Start with local JSON-backed storage for simple self-hosted setups and internal demos.
- Switch to Hindsight-backed memory when you need richer recall and reflection across user history.
- Send structured updates from n8n or similar automation tools without relying on browser cookies.
- Python 3.10 or newer. Python 3.11 is the recommended local development target.
venv, which ships with standard Python installations on most platforms.- Git if you plan to clone the repository or use the one-command installers.
curlorwgetfor the optional Linux and macOS one-command installer flow.- Internet access if you need to install dependencies or connect to Hindsight Cloud.
Choose the automated installer or the manual setup path below.
The project includes auditable install scripts for Linux, macOS, and Windows.
Linux or macOS with curl:
curl -fsSL https://raw.githubusercontent.com/notysozu/kelsa.ai/main/install.sh | bashLinux or macOS with wget:
wget -qO- https://raw.githubusercontent.com/notysozu/kelsa.ai/main/install.sh | bashWindows PowerShell:
iwr https://raw.githubusercontent.com/notysozu/kelsa.ai/main/install.ps1 -UseBasicParsing | iexSecurity notes:
- review pipe-to-shell scripts before running them
- these installers are kept in-repo so they stay readable and auditable
- the scripts generate local development secrets in
.envand do not print them
Installer behavior:
- detects the current OS and package manager
- installs Git and Python when missing
- clones the repository if you are not already inside it
- creates
.envfrom.env.example - creates
.venv, installsrequirements.txt, and starts the app
Useful overrides:
START_APP=0 curl -fsSL https://raw.githubusercontent.com/notysozu/kelsa.ai/main/install.sh | bash
INSTALL_DIR="$HOME/apps/kelsa.ai" curl -fsSL https://raw.githubusercontent.com/notysozu/kelsa.ai/main/install.sh | bash
INSTALL_UPDATE=1 ./install.sh$env:START_APP="0"; iwr https://raw.githubusercontent.com/notysozu/kelsa.ai/main/install.ps1 -UseBasicParsing | iex
$env:INSTALL_DIR="$HOME\apps\kelsa.ai"; iwr https://raw.githubusercontent.com/notysozu/kelsa.ai/main/install.ps1 -UseBasicParsing | iexClone the repository and create a local environment:
git clone https://github.com/notysozu/kelsa.ai
cd kelsa.ai
cp .env.example .env
python -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -r requirements.txt -r requirements-dev.txtStart the app locally:
.venv/bin/python -m uvicorn main:app --reload --port 8090Verify the app responds:
curl -s http://127.0.0.1:8090/api/statusYou should see a JSON response that includes the app name, memory mode, and whether automation or Hindsight are enabled.
.
├── .github/
│ └── workflows/ # GitHub Actions CI definitions
├── tests/ # Pytest coverage for core app behavior
├── main.py # FastAPI app, auth flow, API routes, and local storage logic
├── index.html # Single-page frontend served directly by FastAPI
├── requirements.txt # Runtime Python dependencies
├── requirements-dev.txt# Developer-only dependencies such as pytest
├── .env.example # Sample environment variables for local and production setup
├── install.sh # Linux and macOS bootstrap installer
├── install.ps1 # Windows PowerShell bootstrap installer
├── DEPLOYMENT.md # Deployment-specific guidance
└── N8N_INTEGRATION.md # n8n payload examples and machine-to-machine workflow notes
Runtime data files such as users.json and memory_store.json are created locally when the app runs in JSON-backed mode.
Start from the example config:
cp .env.example .env| Variable | Default | Required | Description |
|---|---|---|---|
SESSION_SECRET |
replace-this-with-a-long-random-secret |
Yes for non-demo deployments | Signs login session cookies. Replace the placeholder before any shared or production use. |
APP_HOST |
0.0.0.0 |
No | Host used by python main.py or the built-in server entrypoint. |
APP_PORT |
8090 |
No | Port used by the built-in server entrypoint. |
APP_RELOAD |
false |
No | Enables reload mode when you run the app through python main.py. |
SESSION_COOKIE_SECURE |
false |
No | Set to true when you serve the app behind HTTPS. |
SESSION_COOKIE_SAMESITE |
lax |
No | Same-site policy for the session cookie. |
SESSION_COOKIE_MAX_AGE |
604800 |
No | Session cookie lifetime in seconds. |
AUTOMATION_API_KEY |
replace-with-a-shared-secret-for-n8n |
Optional | Shared secret for machine-to-machine requests such as n8n workflows. |
HINDSIGHT_ENABLED |
false |
No | Enables Hindsight-backed memory instead of the local JSON fallback mode. |
HINDSIGHT_BASE_URL |
https://api.hindsight.vectorize.io |
Only when Hindsight is enabled | Base URL for the Hindsight API. |
HINDSIGHT_API_KEY |
empty | Only when Hindsight is enabled | API key for the Hindsight service. |
Example .env:
SESSION_SECRET=replace-this-with-a-long-random-secret
APP_HOST=0.0.0.0
APP_PORT=8090
APP_RELOAD=false
SESSION_COOKIE_SECURE=false
SESSION_COOKIE_SAMESITE=lax
SESSION_COOKIE_MAX_AGE=604800
AUTOMATION_API_KEY=replace-with-a-shared-secret-for-n8n
HINDSIGHT_ENABLED=false
HINDSIGHT_BASE_URL=https://api.hindsight.vectorize.io
HINDSIGHT_API_KEY=- Start the app locally.
- Open
http://127.0.0.1:8090in your browser. - Create an account from the
Accountview or log in with an existing account. - Use the sidebar to add skills, projects, applications, resume text, and advisor prompts.
- Return to the dashboard to review a concise summary of what the app has stored for your account.
After setting AUTOMATION_API_KEY in your .env, you can send structured application updates without a browser session:
curl -X POST http://127.0.0.1:8090/api/n8n/applications \
-H "Content-Type: application/json" \
-H "X-Automation-Key: replace-with-a-shared-secret-for-n8n" \
-d '{
"email": "user@example.com",
"company": "Stripe",
"role": "Backend Intern",
"status": "applied",
"date_applied": "2026-03-20",
"notes": "Submitted through careers page"
}'See N8N_INTEGRATION.md for more payload examples and workflow prompts.
- Signup creates a user in
users.json - Login sets a signed cookie-based session
- Logout clears the session cookie
- Protected routes require authentication
- On page refresh, the frontend tries to restore the session automatically
- If the backend returns
401, the frontend sends the user back to the login screen
The app also supports machine-to-machine automation without browser cookies.
- Set
AUTOMATION_API_KEYin the app environment - Send
X-Automation-Keyin n8n HTTP Request nodes - Use
POST /api/n8n/memoryto store structured user data by email - Use
POST /api/n8n/applicationsfor direct application tracking - Use
POST /api/n8n/resume-analysisfor direct resume review - Use
POST /api/n8n/advisorto send a prompt and get an advisor response for that user
See N8N_INTEGRATION.md for example payloads and suggested workflow patterns.
When HINDSIGHT_ENABLED=false:
- users are stored in
users.json - user data is stored in
memory_store.json - data is separated by authenticated
user_id
When HINDSIGHT_ENABLED=true and valid Hindsight credentials are provided:
- the app initializes a Hindsight bank
- memory operations use Hindsight
- user isolation is preserved using user-specific tags
- n8n-triggered advisor prompts also use the same per-user Hindsight-scoped path
- The frontend is a single HTML file with inline CSS and JavaScript.
- The backend serves
index.htmldirectly from FastAPI. - Local runtime files like
.env,.venv,users.json,memory_store.json, and__pycache__should stay out of Git.
You can deploy this project, but in its current form it is best suited to demos, prototypes, or small internal use. Before you put it into heavier production use, review the following points carefully.
- set a strong
SESSION_SECRET - run without
--reload - serve behind a reverse proxy such as Nginx or Caddy
- use HTTPS
- protect and rotate secrets properly
- back up any persistent JSON files if you stay on local storage
Use a non-reload command:
.venv/bin/python -m uvicorn main:app --host 0.0.0.0 --port 8090You can also see DEPLOYMENT.md for a shorter deployment-specific checklist.
Recommended:
- terminate TLS at Nginx/Caddy
- proxy requests to the FastAPI app
- keep the app on a private internal port
Current persistence uses JSON files:
users.jsonmemory_store.json
This approach works well for local deployments, but it has tradeoffs:
- not ideal for concurrent multi-process writes
- not ideal for horizontal scaling
- no built-in migrations, backups, or admin tooling
For larger production use, move user and memory persistence to a database.
The app currently uses signed cookies for sessions. For real production deployment, review cookie security settings in main.py, especially if you are serving over HTTPS and want stricter cookie behavior.
If you enable Hindsight in production:
- set
HINDSIGHT_ENABLED=true - configure
HINDSIGHT_BASE_URL - set
HINDSIGHT_API_KEY - verify outbound network access from your server
If port 8090 is busy:
python -m uvicorn main:app --reload --port 8091If Git rejects your push because of local runtime files, make sure .gitignore is present and those files are not tracked anymore.
Check:
- the backend is running
SESSION_SECRETis set- your browser accepts cookies
Check:
HINDSIGHT_ENABLED=trueHINDSIGHT_API_KEYis set- the configured Hindsight URL is reachable
- JSON-backed storage is fine for demos but not ideal for large-scale production
- full browser-based automated end-to-end tests are not included
- session cookie behavior may need stricter production hardening depending on deployment setup
| Area | Tools |
|---|---|
| Language and runtime | Python 3.10+ |
| Backend framework | FastAPI, Uvicorn |
| Validation and auth helpers | Pydantic, Passlib, ItsDangerous, email-validator |
| Frontend | Single index.html file with inline HTML, CSS, and vanilla JavaScript |
| Storage | Local JSON files by default, optional Hindsight-backed memory |
| Developer tooling | Pytest, GitHub Actions CI, cross-platform install scripts |
Current status: active prototype suitable for demos, internal tools, and incremental hardening.
- Browser-based account flow for personal career tracking
- Local JSON-backed storage with optional Hindsight support
- n8n-compatible endpoints for machine-to-machine automation
- Replace JSON persistence with a more production-ready database backend
- Expand automated tests beyond the current core route and auth coverage
- Move startup handling from event hooks to FastAPI lifespan handlers
Contributions are welcome. Start with CONTRIBUTING.md for local setup, testing expectations, and Conventional Commit guidance.
If you plan to contribute:
- open an issue or discussion if you want to sanity-check a change before implementing it
- fork the repository, create a focused branch, and open a pull request with a short testing summary
- run
.venv/bin/pytestbefore submitting your PR
Please also read the Code of Conduct.
This project is licensed under the MIT License.