Skip to main content
Glama
Joblet-Official

joblet-mcp-grok

README.md
# joblet-mcp-grok

Standalone [MCP](https://modelcontextprotocol.io) server exposing read-only
joblet.ai job search to Grok and any other standards-compliant MCP host.
Independent deployment — shares no infrastructure, branch, or release train
with Joblet's other connectors.

Two tools, both read-only (`readOnlyHint: true`):

- **`search_jobs`** — keyword search with a real upstream location filter,
  MCP-layer relevance filtering (title/category/industry/role token match;
  description-only matches rejected), expVer/near-duplicate deduplication,
  and a hard cap of 8 results. Ships text + `structuredContent`, plus an
  MCP Apps job-card widget for hosts that render it.
- **`get_job_details`** — full posting (description, requirements,
  responsibilities, salary and workplace when known, apply link) by job id.

Application URLs are passed through byte-exact (Joveo tracking preserved,
no proxy or redirect). Employment type is deliberately not surfaced or
filtered: the upstream search does not provide an authoritative field.

## Requirements

- Node.js 18+ (developed and tested on Node 24)
- No API keys or secrets — the upstream joblet.ai API is public

## Local setup

```bash
npm ci
npm run build        # bundles the widget to dist/mcp-app.html (required before start)
PORT=3010 npm start  # MCP endpoint at http://localhost:3010/mcp
```

Health check:

```bash
# GET /health  ->  {"status":"ok","version":"1.1.0"}
```

MCP endpoint: `POST /mcp` — Streamable HTTP, JSON responses, stateless
(no session ids). Requires the spec-standard
`Accept: application/json, text/event-stream` header. `GET /` returns a
service banner.

## Verify the MCP contract locally

```bash
MCP_URL="http://localhost:3010/mcp" node test_client.mjs
MCP_URL="http://localhost:3010/mcp" node test_widget.mjs
```

Or interactively: `npm run inspect` (MCP Inspector → Streamable HTTP →
the /mcp URL).

## Development

```bash
npm run typecheck    # server + widget/tests configs
npm test             # vitest suites (server pipeline, widget, a11y, logging)
npm run build        # production widget bundle
```

## Configuration

See [.env.example](.env.example). Everything is optional; defaults are
production-sane. `MCP_REQUEST_LOG=1` enables sanitized per-call logging
(hashes/lengths/counts only — never raw query text, locations, apply URLs,
or credentials).

## Widget notes

The job-card widget reports its intrinsic height to the host via the MCP
Apps `sendSizeChanged` notification (height only, measured after
requestAnimationFrame, change-gated to avoid resize loops) and respects a
fixed host container height when one is declared. Whether a host resizes
the iframe accordingly is host behavior. The View & Apply CTA uses the
standards-compliant `ui/open-link` request with a visible, accessible
in-card fallback (link + copy action) whenever the host denies or does not
support it — it never fails silently.