---
title: Connect an agent to Doing Work
description: Discovery, OAuth 2.1 with PKCE and dynamic client registration, then MCP tools or REST calls.
url: https://doingwork.work/docs/quickstart/
---

# Connect an agent

> REST is at https://doingwork.work/v1, MCP at https://doingwork.work/mcp and A2A at https://doingwork.work/a2a, all with the same operations and permissions.

## 1. Discover

Read `https://doingwork.work/.well-known/mcp/server-card.json` for the MCP endpoint, or `https://doingwork.work/openapi.json` for REST. The API sends a 401 with `WWW-Authenticate: Bearer resource_metadata=...` when you need to sign in.

## 2. Register your client

Dynamic client registration (RFC 7591). Public clients only, no secret. Redirect URIs must be https or loopback.

```http
POST https://doingwork.work/v1/oauth/register
content-type: application/json

{"client_name": "My shop assistant", "redirect_uris": ["http://127.0.0.1:8976/callback"]}
```

## 3. The person approves you

Send the person to the `authorization_endpoint` from [OAuth server metadata](https://doingwork.work/.well-known/oauth-authorization-server) with `client_id`, `redirect_uri`, `code_challenge` (S256), `state`, and `resource=https://doingwork.work/mcp`. They sign in with an email link and approve. You get a one-time code at your redirect.

## 4. Get a token

```http
POST https://doingwork.work/v1/oauth/token
content-type: application/json

{"grant_type": "authorization_code", "client_id": "...", "code": "...", "code_verifier": "...", "redirect_uri": "http://127.0.0.1:8976/callback", "resource": "https://doingwork.work/mcp"}
```

Access tokens are short-lived. Refresh tokens rotate: each works once, and reusing one revokes the whole chain. Store the new one every time.

## 5. Call tools

MCP: streamable HTTP at `https://doingwork.work/mcp`, `Authorization: Bearer <token>`. Tool names are operation ids with dots as underscores, for example `quotes_create`. Hosted-page and person-only operations are not listed as tools.

```json
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"jobs_list","arguments":{"shop_id":"..."},"_meta":{"idempotencyKey":"..."}}}
```

REST: the same operations under `https://doingwork.work/v1`. GET operations take query parameters; POST operations take a JSON body. See [conventions](https://doingwork.work/docs/conventions/).

## Other ways in

- **Named agent key.** The shop owner makes a key for you with their own sign-in ([keys.create](https://doingwork.work/docs/reference/keys-create/)). It starts with `dwk_`, is shown once, works in one shop, and can be narrowed to `read_only` or `no_money`. It works on REST, MCP and A2A.
- **Register and get claimed.** With no key yet, [agents.register](https://doingwork.work/docs/reference/agents-register/) gives you a claim token. [agents.claim](https://doingwork.work/docs/reference/agents-claim/) with the owner's email returns a 6 digit code the owner types on a hosted page. Poll the token endpoint until they approve. Details in [auth.md](https://doingwork.work/auth.md).
- **A2A.** `POST https://doingwork.work/a2a` (A2A 1.0 JSON-RPC) with a named agent key. Send `SendMessage` with one data part, `{"op": "<op id>", "input": {...}}`. There's no model behind it: the op runs exactly as on REST and MCP. A write the owner must approve comes back as an input required task. Card: [agent-card.json](https://doingwork.work/.well-known/agent-card.json).

## 6. Start with who you are

Call [me.get](https://doingwork.work/docs/reference/me-get/) to see the person and their shops. Then follow [Onboard a shop](https://doingwork.work/docs/onboarding/) or [Job to paid](https://doingwork.work/docs/job-to-paid/).
