Skip to content

feat: integrate Workable as a new ATS provider - #214

Merged
amikai merged 1 commit into
mainfrom
claude/integrate-workable-provider-a1cbb7
Jul 18, 2026
Merged

feat: integrate Workable as a new ATS provider#214
amikai merged 1 commit into
mainfrom
claude/integrate-workable-provider-a1cbb7

Conversation

@amikai

@amikai amikai commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add a Workable ATS adapter using the public apply.workable.com job-board API (POST /api/v3/.../jobs search, filters facets, GET /api/v2/.../jobs/{shortcode} detail).
  • Ship ogen-generated client, fixture-backed provider tests, seed roster (Blueground, PEOPLECERT, Persado, Skroutz, Zego), and cmd/workable debug CLI.
  • Wire the adapter into the MCP server registry, verify-companies, README provider list, and OpenAPI Makefile targets.

Design notes

  • Multi-company ATS surface via search_jobs_by_company (not dedicated tools).
  • Official token-gated SPI API was rejected; careers-page public v3/v2 endpoints are used instead.
  • Location fields are nullable (region/city often null on live accounts); OpenAPI uses OptNilString.
  • Unified page size 20 is served by walking Workable’s fixed 10-item cursor pages.

Test plan

  • go test ./...
  • make validate-openapi
  • Live MCP stdio smoke: search all 5 roster companies + Blueground detail + Zego location filter
  • Live cmd/workable search for persado (null region) and zego --city London

Add an adapter for Workable-hosted careers pages via the public
apply.workable.com job-board API (v3 search + v2 detail), with ogen
client, seed roster, debug CLI, and MCP wiring.
@amikai
amikai force-pushed the claude/integrate-workable-provider-a1cbb7 branch from 6da8947 to d530edd Compare July 18, 2026 12:01
@amikai
amikai merged commit 677dded into main Jul 18, 2026
9 checks passed
@amikai
amikai deleted the claude/integrate-workable-provider-a1cbb7 branch July 18, 2026 12:13
Comment thread internal/ats/workable.go
return JobSummary{
JobID: j.Shortcode,
Title: j.Title,
Location: workableLocationText(j.Location),

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Include secondary job locations

The summary formats only j.Location and ignores j.Locations. A live PeopleCert search filtered to London returns jobs whose output location says Tokyo or Stuttgart because London is secondary; Detail has the same omission. Combine distinct visible primary and secondary locations.

Comment thread internal/ats/workable.go
}
jobs := make([]dumpJob, 0, len(items))
for _, j := range items {
jobs = append(jobs, workableDumpJob(slug, j))

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Preserve body-only keyword matches

Workable’s query searches posting bodies, but workableDumpJob leaves description empty before searchDump reapplies the query. Live query=engineer returns 9 upstream matches while MCP returns only 4, dropping valid body-only results. Populate description text—likely through detail requests—before residual filtering, or avoid discarding upstream full-text matches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant