Skip to main content
Glama
VaibhavMugulavalli

Bengaluru AI Job Radar

README.md
# Bengaluru AI Job Radar

**Bengaluru AI Job Radar** is a Python FastMCP server that helps an AI agent search for AI internship and early-career AI roles in Bengaluru, save them to a local JSON job tracker, and render a Prefab dashboard UI.

Built with [FastMCP](https://github.com/PrefectHQ/fastmcp) 3.4.x, [Prefab UI](https://pypi.org/project/prefab-ui/) 0.20.x, [Tavily](https://tavily.com/) for internet search, and JSON for local persistence.

---

## Assignment Mapping

| Assignment Requirement | Implementation |
|---|---|
| Custom MCP server | Python FastMCP server (`server.py`) |
| Internet-related function | `search_ai_jobs` uses Tavily API |
| Local file CRUD | `job_tracker_db` performs CRUD on local JSON file (`data/bengaluru_ai_job_radar.json`) |
| UI communication | `render_job_dashboard` returns FastMCP Prefab UI components |
| Web app / dashboard | Prefab-rendered dashboard inside MCP-compatible host |
| Prompt forcing all 3 tools | Included in `demo_prompt.md` |

---

## Architecture

```text
User prompt
  → Agent calls search_ai_jobs (Tavily internet search)
  → Agent saves results via job_tracker_db (JSON CRUD)
  → Agent reads records via job_tracker_db (JSON CRUD)
  → Agent calls render_job_dashboard (Prefab UI)
  → Prefab dashboard appears in MCP host
```

### MCP Tools

| Tool | Purpose | Category |
|---|---|---|
| `search_ai_jobs` | Search Tavily for AI/ML/GenAI internships and junior roles in Bengaluru | Internet |
| `job_tracker_db` | Create, read, update, delete, and manage job leads in a local JSON database | Local CRUD |
| `render_job_dashboard` | Render a rich Prefab UI dashboard with summary metrics, job table, and charts | UI |

---

## Setup (Windows)

```powershell
cd C:\Cursor\EAGv3\S4
cd bengaluru-ai-job-radar

python -m venv .venv
.venv\Scripts\activate

pip install -e ".[dev]"

copy .env.example .env
# Edit .env and add your TAVILY_API_KEY
```

### Setup (macOS / Linux)

```bash
cd /path/to/bengaluru-ai-job-radar

python3 -m venv .venv
source .venv/bin/activate

pip install -e ".[dev]"

cp .env.example .env
# Edit .env and add your TAVILY_API_KEY
```

---

## Environment Variables

Create a `.env` file (or set system environment variables):

```env
TAVILY_API_KEY=tvly-xxxxxxxxxxxxxxxxx
DATABASE_PATH=data/bengaluru_ai_job_radar.db
```

- **`TAVILY_API_KEY`** (required): Get one free at [tavily.com](https://tavily.com/).
- **`DATABASE_PATH`** (optional): Defaults to `data/bengaluru_ai_job_radar.db` relative to the project root.

---

## Running the MCP Server

### Direct Python execution

```powershell
python -m bengaluru_ai_job_radar.server
```

### Using FastMCP CLI

```powershell
fastmcp run src/bengaluru_ai_job_radar/server.py
```

### App preview (if supported)

```powershell
fastmcp dev src/bengaluru_ai_job_radar/server.py
```

---

## Connecting to an MCP Host

Add this to your MCP host configuration (Claude Desktop, Cursor, VS Code, etc.):

```json
{
  "mcpServers": {
    "bengaluru-ai-job-radar": {
      "command": "python",
      "args": ["-m", "bengaluru_ai_job_radar.server"],
      "cwd": "C:\\Cursor\\EAGv3\\S4\\bengaluru-ai-job-radar",
      "env": {
        "TAVILY_API_KEY": "your_key_here",
        "DATABASE_PATH": "data/bengaluru_ai_job_radar.db"
      }
    }
  }
}
```

> **Note:** Exact MCP host configuration may differ depending on Claude Desktop, Cursor, VS Code, ChatGPT MCP Apps, or another host.

---

## Demo Prompt

Copy this prompt into your MCP-connected AI agent to exercise all 3 tools:

> Use the Bengaluru AI Job Radar MCP server to complete this full workflow.
>
> First, use the MCP internet search tool `search_ai_jobs` to find companies currently hiring AI Interns, ML Interns, GenAI Interns, LLM Engineer Interns, AI Implementation Engineer Interns, or Junior AI Engineers in Bengaluru.
>
> Prioritize roles involving Python, LLMs, RAG, AI agents, embeddings, prompt engineering, fine-tuning, model training, NLP, or AI backend development.
>
> Save at least 5 relevant job leads to the local JSON job tracker using the MCP CRUD tool `job_tracker_db`.
>
> Then read the saved records back using `job_tracker_db` with the `list_jobs` operation.
>
> Finally, render the saved results using the FastMCP Prefab UI tool `render_job_dashboard`.
>
> Do not answer from memory. Do not skip any step. You must call all 3 tools:
> 1. `search_ai_jobs`
> 2. `job_tracker_db`
> 3. `render_job_dashboard`

The full prompt is also available in [`demo_prompt.md`](demo_prompt.md).

---

## Example Workflow

### 1. Search for roles

The agent calls `search_ai_jobs` with:
```json
{
  "role_query": "AI Intern",
  "location": "Bengaluru",
  "max_results": 10
}
```

### 2. Save job leads

The agent calls `job_tracker_db` for each result:
```json
{
  "operation": "create_job",
  "payload": {
    "company": "Sarvam AI",
    "role_title": "AI Intern",
    "role_type": "internship",
    "location": "Bengaluru",
    "skills": ["Python", "LLM", "RAG"],
    "fit_score": 85,
    "source_platform": "LinkedIn",
    "source_url": "https://linkedin.com/jobs/view/123"
  }
}
```

### 3. List saved jobs

```json
{
  "operation": "list_jobs",
  "payload": {"min_fit_score": 50}
}
```

### 4. Update a role status

```json
{
  "operation": "update_status",
  "payload": {
    "job_id": "...",
    "new_status": "applied",
    "event_note": "Applied via company careers page"
  }
}
```

### 5. Add a note

```json
{
  "operation": "add_note",
  "payload": {
    "job_id": "...",
    "note": "Reach out to founder on LinkedIn"
  }
}
```

### 6. Render dashboard

The agent calls `render_job_dashboard` → a Prefab UI dashboard appears with summary cards, a job table, recent activity, and skill frequency.

---

## Running Tests

```powershell
pytest tests/ -v
```

Tests cover:
- **Fit score calculator** — scoring rubric, caps, keyword boosts
- **Normalization** — company names, slug IDs, role type inference, skill extraction
- **JSON store** — full CRUD lifecycle, upsert, deduplication, dashboard aggregation

---

## Project Structure

```text
bengaluru-ai-job-radar/
  README.md
  pyproject.toml
  .env.example
  .gitignore
  demo_prompt.md

  src/
    bengaluru_ai_job_radar/
      __init__.py
      server.py          # FastMCP server entrypoint
      config.py           # Environment variable loading
      schemas.py          # Pydantic validation models

      tools/
        __init__.py
        search.py          # search_ai_jobs MCP tool
        database.py        # job_tracker_db MCP tool
        dashboard.py       # render_job_dashboard MCP tool (Prefab UI)

      services/
        __init__.py
        tavily_service.py  # Tavily API integration
        fit_score.py       # Deterministic fit-score calculator
        normalization.py   # Company/role normalization, skill extraction

      storage/
        __init__.py
        json_store.py      # JSON CRUD store (JobRadarStore)

  data/
    .gitkeep              # JSON DB created here at runtime

  tests/
    test_fit_score.py
    test_normalization.py
    test_json_store.py
```

---

## Known Limitations

- Tavily search result quality depends on public indexing of job boards.
- Some job platforms may block direct scraping, so the tool relies on Tavily snippets and source links.
- Compensation data may be unavailable for many listings — shown as "unknown".
- Prefab UI APIs are actively evolving; dependency pinning to `prefab-ui>=0.20.0,<1.0.0` is used.
- Dashboard interactivity depends on the MCP host's support for FastMCP Apps / Prefab rendering.
- Company name extraction from search results is best-effort; some may show as "unknown".
- The fit-score algorithm is deterministic and rule-based — it does not use ML or LLM reasoning.

---

## Dependencies

| Package | Purpose |
|---|---|
| `fastmcp[apps]` ≥3.4.0 | MCP server framework + Prefab app support |
| `prefab-ui` ≥0.20.0 | Prefab UI components (Card, DataTable, Badge, etc.) |
| `pydantic` ≥2.0.0 | Request/response validation |
| `python-dotenv` ≥1.0.0 | .env file loading |
| `httpx` ≥0.27.0 | HTTP client (Tavily fallback) |
| `tavily-python` ≥0.5.0 | Tavily search SDK |
| `rich` ≥13.0.0 | Rich terminal output |

---

## License

MIT