With an access token from Sign in with OAuth by hand, send each JSON-RPC 2.0 message as a POST to https://mcp.zorlya.com. This guide sends initialize, lists the tools, calls top_matches, reads a resource and renders a prompt with curl.
Set two variables:
TOKEN=paste-your-access-token
MCP=https://mcp.zorlya.com
1. Say hello
initialize starts the exchange. You send the protocol version you speak, and the server answers with the version it will use:
curl -s $MCP \
-H "authorization: Bearer $TOKEN" \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"my-client","version":"0.1.0"}}}'
The result carries protocolVersion, capabilities, serverInfo (name is zorlya) and instructions, a few paragraphs written for an AI model that explain how to read scores and how to page. The server accepts 2026-07-28, 2025-06-18, 2025-03-26, 2024-11-05 and 2024-10-07. If you ask initialize for a version it does not know, it answers with 2025-06-18.
From the 2026-07-28 revision, a request must say its method in an Mcp-Method header (and, for tools/call, resources/read and prompts/get, the tool, resource or prompt in Mcp-Name). Send MCP-Protocol-Version: 2026-07-28 with them. A header that is missing or disagrees with the body is refused with the JSON-RPC error -32020, and a version the server does not speak with -32022, which lists the versions it does. The examples below omit the headers and so speak the older revision, which needs none. A request from a browser page must come from one of Zorlya’s own app origins, or the server answers 403.
Real clients then send a notification that they are ready. A notification has no id, and the server answers it with an empty 202:
curl -s -o /dev/null -w "%{http_code}\n" $MCP \
-H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
The server keeps no session, so this step changes nothing on its side. You can call tools/list without it. Send it anyway if you want your client to behave like the others.
2. List the tools
curl -s $MCP -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
What you get depends on the account the person chose. For a job seeker with read access you get 15 tools, and with write access as well, 20. A hiring account lists up to 11, a support account up to 7 and a staff account up to 17, each filtered by the scopes granted and the person’s role. Each tool has a name, a description and an inputSchema in JSON Schema. Read the schema instead of guessing arguments: for example, get_job requires job_id, and search_jobs takes query, location, remote_only, min_score, limit and cursor.
3. Call a tool
curl -s $MCP -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"top_matches","arguments":{"limit":2}}}'
The result has a content array. Its first item is {"type":"text","text":"…"}, and the text is a JSON document you parse yourself. A trimmed example:
{
"count": 2,
"has_more": true,
"next_cursor": "anAxOjI=",
"matches": [
{
"job_id": "5a3b1e00-0009-4000-8000-00000000001f",
"title": "LLM Application Engineer",
"company": "Granite Peak",
"remote": true,
"score": 92.6,
"sub_scores": { "semantic": 98.0, "skills": 98.0, "salary": 70.0, "geo": 100.0 },
"explanation": "Your work with FastAPI lines up with the core of this role. Salary band not stated."
}
]
}
The same data also comes back as structuredContent next to content, already parsed, so a client that reads it can skip the text. has_more and next_cursor tell you there is another page. Page results and handle errors shows how to follow it.
4. Read a resource and a prompt
A resource is read by address:
curl -s $MCP -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":4,"method":"resources/read","params":{"uri":"zorlya://tracks"}}'
The result is contents, each with uri, mimeType (Markdown) and text. resources/list shows the four fixed resources, and resources/templates/list shows zorlya://job/{job_id}.
A prompt is rendered with its arguments:
curl -s $MCP -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":5,"method":"prompts/get","params":{"name":"find_roles","arguments":{"keywords":"python","remote_only":"true"}}}'
The result is messages ready to hand to a model. assess_fit needs job_id and the others take optional arguments.
Other methods
ping answers {}. tools/list, resources/list, resources/templates/list and prompts/list take no arguments. Anything else answers a JSON-RPC error with code -32601 (HTTP 404 from the 2026-07-28 revision).
What we checked
The requests in this guide were run against a local copy of the server on 2026-10-17, and the example output is trimmed from those runs. On 2026-10-18 the address and the header rules were updated from the server’s source and not run again. Nothing was run against the production server.