# Developer quickstart

Send one JSON-RPC 2.0 message per HTTP POST to `https://www.digitaljobs.com/mcp`. Public examples below require no token. The endpoint returns JSON, does not issue a session ID and does not offer a GET event stream.

## MCP 2025-11-25

This sequence matches the legacy path tested against the live service. Run the commands in a shell with curl installed.

### Initialise

```bash
curl --silent --show-error --max-time 30 'https://www.digitaljobs.com/mcp' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","clientInfo":{"name":"digitaljobs-example","version":"1.0"},"capabilities":{}}}'
```

Expect HTTP 200 and `result.protocolVersion` equal to `2025-11-25`. The current implementation only accepts that exact version in `initialize`. Do not send `2026-07-28` through this initialization path.

### Notify readiness

```bash
curl --silent --show-error --max-time 30 'https://www.digitaljobs.com/mcp' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  --data '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}'
```

Expect HTTP 202 with an empty body. No request ID is included in the notification.

### List available tools

```bash
curl --silent --show-error --max-time 30 'https://www.digitaljobs.com/mcp' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  --data '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
```

The tool catalogue is returned in one page. Do not supply a catalogue cursor. The server advertises enabled tools regardless of your scopes; enforce authorisation by handling each call's response.

### Search

```bash
curl --silent --show-error --max-time 30 'https://www.digitaljobs.com/mcp' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  --data '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_jobs","arguments":{"role":"developer","limit":2}}}'
```

Read `result.structuredContent.jobs`. The text in `result.content` is a summary, not a JSON copy of the records. Check for a top-level `error` and `result.isError` before consuming data. Fetch another page with only `{"cursor":"RETURNED_CURSOR"}` in `arguments`.

## MCP 2026-07-28

Use `server/discover` instead of legacy initialization. Every modern request requires the version header, matching `Mcp-Method` and the three metadata fields shown below. Tool calls also require `Mcp-Name` matching `params.name`. Metadata belongs under `params._meta`, outside `arguments`.

```bash
curl --silent --show-error --max-time 30 'https://www.digitaljobs.com/mcp' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2026-07-28' \
  -H 'Mcp-Method: server/discover' \
  --data '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"digitaljobs-example","version":"1.0"},"io.modelcontextprotocol/clientCapabilities":{}}}}'
```

Then request `tools/list` with `Mcp-Method: tools/list` and the same metadata. To search:

```bash
curl --silent --show-error --max-time 30 'https://www.digitaljobs.com/mcp' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2026-07-28' \
  -H 'Mcp-Method: tools/call' \
  -H 'Mcp-Name: search_jobs' \
  --data '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_jobs","arguments":{"role":"developer","limit":2},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"digitaljobs-example","version":"1.0"},"io.modelcontextprotocol/clientCapabilities":{}}}}'
```

Modern successful results include `resultType: "complete"`. Discovery and the catalogue include a five-minute TTL. Do not confuse catalogue freshness with the availability or current state of individual job records.

## Protected calls

Complete [OAuth and linking](authentication.html), then use the same `tools/call` envelope with an `Authorization: Bearer <access_token>` header and the tool's input object. Have the client manage credentials securely; do not paste them into chat or commit them to source control. Omit the header entirely for anonymous requests; an invalid token is rejected even for a public tool.

Use JSON integers for creation IDs and strings for `draft_id`. Request bodies are limited to 64 KiB. Unknown arguments and invalid types are rejected. Batch request arrays, resources and prompts are not supported by this implementation.

## Response handling

1. Record the HTTP status and `X-Request-Id` when available.
2. Handle a top-level JSON-RPC `error` as a request failure.
3. Check `result.isError`; a business-rule failure can arrive with HTTP 200.
4. On success, read `structuredContent` and preserve returned URLs and IDs.
5. Honour `Retry-After` and use bounded retries. Reuse the same idempotency key for an uncertain draft-creation outcome.

Browser-to-server integrations need deliberate origin and CORS support. The current PHP router validates origins but does not emit CORS allow headers. Use a supported server-side or native client; do not disable browser protections.

The current empty-object schema issue may stop strict MCP libraries before any call is made. This quickstart demonstrates HTTP behaviour; it does not establish compatibility with every MCP SDK. See [troubleshooting](troubleshooting.html).

Transport reference: [MCP Streamable HTTP](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports). Newer protocol reference: [MCP 2026-07-28](https://modelcontextprotocol.io/specification/2026-07-28).
