LucyESL

Empregos de ensino de inglês na Coreia do Sul: salário, divulgação e estatísticas por região. Somente leitura, sem chave.

Servidor MCP hospedado

npx add-mcp 'https://lucyesl.com/mcp'

Instala no Claude Code, Codex, Cursor e outros

Documentação

LucyESL for AI agents and developers

Everything LucyESL publishes for people is also published for programs: the live board as structured facts, the salary and disclosure statistics as open data, and a Model Context Protocol server so an assistant can search the board on a reader's behalf. Right now that is 597 live listings, updated 2026-10-20.

What you may do, and what you get

  • Statistics are CC BY 4.0. Quote them with the attribution LucyESL, https://lucyesl.com and the page they come from.
  • Listing records are LucyESL's extracted facts — title, employer, region, pay, hours, visas, housing, benefits, dates — and the list of facts the advert left unstated. The advert itself belongs to whoever wrote it. Records never include the description text, any contact route, or a source board's URL; the way to an original is the counted link on the listing page.
  • Most listings are copied from other public boards and say so ("source": "copied"). LucyESL does not verify them. A listing posted here by the employer is "first_party"; "verified_employer": true means the employer's business registration and contact were checked.
  • 600 requests an hour per address across the JSON view and the MCP server, then HTTP 429 with a Retry-After. There is also a ceiling on agent traffic across every address at once; it sits far above ordinary use, and a 429 that mentions shedding is that ceiling rather than anything about you. Both are there so one runaway client cannot take the board down — please honour Retry-After. Pages are 25 records, at most 50.
  • The keys are a contract. They are pinned by the repository's tests; keys are added, never renamed or removed. null always means the advert did not state it — never zero.

The board as JSON

https://lucyesl.com/jobs?format=json — the same filters and the same rows as the board: listings posted on LucyESL first, then copied ones, newest first in each. The board's page has a Featured box an employer can pay for, and it says so there; an answer has nowhere to print that mark, so here and on the MCP server a featured listing sits at its own date. No position in these results is paid for. Parameters: region, age, housing, visa, schedule, contract, setting, delivery, specialty, direct=1, smin (one of 2000000, 2300000, 2600000, 3000000), q, page, limit. Every response carries the label for every key under taxonomy.

Examples: jobs in Busan · direct hire, ₩2.6M and up · adult students only.

The statistics: /salaries?format=json, /disclosure?format=json and /market?format=json — the board by region, with the direct-hire split and each region's denominator — documented on Salaries, Disclosure and Where the jobs are. Each recorded month is at /monthly/YYYY-MM?format=json, area rows included from October 2026.

The MCP server

https://lucyesl.com/mcp — Model Context Protocol over Streamable HTTP, JSON responses, no authentication, no session. Add it where your assistant takes a custom connector or MCP server URL: in ChatGPT under Settings → Apps & Connectors, in Claude under Settings → Connectors, in any MCP client's server list. The search and fetch tools follow the shape ChatGPT's connectors expect; the rest return structured records.

The tools the MCP server offers

ToolWhat it does
searchSearch live English-teaching jobs in South Korea on LucyESL by free text. Returns ids, titles and URLs.
fetchFetch one LucyESL job listing by id as a plain-text document with its facts.
search_jobsFilter the live LucyESL board of English-teaching jobs in South Korea: region, student age, housing, visa, schedule, contract, setting, direct hire, minimum salary, free text. Returns structured records; pay in KRW per month unless stated otherwise; null means the advert did not say.
get_jobOne live listing as a structured record.
salary_statsEnglish-teacher salary statistics for South Korea computed from the live listings: median, quartiles, by region, by employer type, effective pay per teaching hour, disclosure rates, housing. CC BY 4.0.
disclosure_statsHow many live Korean ESL job adverts state the salary, hours, severance, pension, insurance, airfare, vacation and split shifts. CC BY 4.0.
market_statsLive English-teaching job adverts in South Korea counted by region: how many in each, direct hire against recruiters, how many state total on-site hours, and the median advertised salary where the sample allows. Counts of adverts, not of employers. CC BY 4.0.

A first call, by hand:

curl -s https://lucyesl.com/mcp -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"search_jobs","arguments":{"region":"busan","direct_only":true}}}'

When a call does not do what you expected: a listing that has closed or expired answers get_job and fetch with a tool error naming the id, because the board changes daily; a filter value the board does not know is named in the reply as ignored rather than quietly widening the search. Anything else, write to hello@lucyesl.com.

Any page as Markdown

Every public page answers as Markdown at its own address when asked: send Accept: text/markdown and the response is the page's main content — the words a reader sees, tables as tables, links made absolute — at well under half the bytes, with the canonical URL in a Link header. Agents that send that header by default get it without doing anything; a browser, which asks for HTML, never sees it. There is no second address to keep in sync: it is the rendered page, converted on the way out.

curl -s https://lucyesl.com/salaries -H 'Accept: text/markdown'

The same page for every reader

LucyESL serves every crawler and assistant exactly the page a browser gets. Nothing on this site changes with the user agent, and nothing is written for machines that a person cannot read: the Markdown answer above is the same page, converted, and only when it is asked for. We check it by fetching every kind of page as a browser and as the crawlers and assistants of Google, Bing, OpenAI, Anthropic, Perplexity, Apple, Naver, Daum, DuckDuckGo and Meta, and comparing what comes back.

Our crawler, LucyESLBot

Most listings on LucyESL are copied from other public English-teaching job boards, and a crawler called LucyESLBot does the copying. It names itself in every request as Mozilla/5.0 (compatible; LucyESLBot/1.0; +https://lucyesl.com/developers#crawler), reads only public job pages on a small number of boards about once a week, waits at least 1.2 seconds between requests (longer when the board's robots.txt asks), and checks robots.txt before every request. A refusal ends the visit: it never comes back under another name or by another route. It collects no email addresses, phone numbers or messenger handles, and every copied listing says it was copied and links to the original posting.

To stop it, add this to your robots.txt, or write to hello@lucyesl.com and we will also take down the listings of yours we already hold:

User-agent: LucyESLBot
Disallow: /

Why this exists

Readers increasingly arrive through an assistant that searched for them. An assistant can only cite what it can read and only search what it can query, so the board is published in the form a program needs, under terms a person would accept. If something here is wrong or missing, tell us.


Source: https://lucyesl.com/developers