# Selfcare MCP server: how to connect Claude, ChatGPT and Cursor

> Connect an AI assistant to Selfcare over MCP at https://api.selfcare.work/mcp, with OAuth 2.1, PKCE and your own user account. Steps for Claude, ChatGPT, Cursor and other clients, plus scopes, tools and limits.

Selfcare has an MCP (Model Context Protocol) server for AI assistants. Each person signs in with their own Selfcare account. The assistant can then check leave balances, request absences, log expenses, trips and mileage, open documents and handle approvals, always with the permissions that person has in the app.

HTML version: https://www.selfcare.work/en/mcp

## Summary

- **Server URL:** `https://api.selfcare.work/mcp`
- **Transport:** Stateless Streamable HTTP: each request is a POST with JSON-RPC.
- **Authentication:** OAuth 2.1 with PKCE (S256), using the person's own account. There is no shared fixed token.
- **Authorisation server:** `https://api.selfcare.work`
- **Client registration:** Dynamic (RFC 7591): the client registers itself, with no keys to copy.
- **Price:** Included in every plan, at no extra cost.

## Discovery and authorisation

1. Without a token, a request to https://api.selfcare.work/mcp returns 401 with the WWW-Authenticate header, which points to the protected resource metadata.
2. Protected resource metadata (RFC 9728): https://api.selfcare.work/.well-known/oauth-protected-resource/mcp. It also answers at the root, https://api.selfcare.work/.well-known/oauth-protected-resource, for clients that look there.
3. Authorisation server metadata (RFC 8414): https://api.selfcare.work/.well-known/oauth-authorization-server. It lists the authorisation, token, revocation and registration endpoints.
4. Dynamic client registration (RFC 7591): https://api.selfcare.work/oauth/register. Public clients only, with PKCE S256 required.
5. The token is issued for the resource https://api.selfcare.work/mcp (RFC 8707) and sent in the Authorization: Bearer header. An MCP token doesn't work on the REST API, or the other way round.

```http
HTTP/2 401
WWW-Authenticate: Bearer realm="selfcare", resource_metadata="https://api.selfcare.work/.well-known/oauth-protected-resource/mcp"
```

## How to connect

### Claude

1. In Settings → Connectors, choose Add custom connector.
2. Give it a name (Selfcare) and paste the URL https://api.selfcare.work/mcp.
3. Click Connect. The Selfcare authorisation screen opens: sign in with your account, choose the company and confirm what the assistant can do.

### Claude Code

1. In the terminal, add the server with the command below.
2. Inside Claude Code, run /mcp and choose the selfcare server. The browser opens so you can sign in to Selfcare and authorise.

```bash
claude mcp add --transport http selfcare https://api.selfcare.work/mcp
```

### ChatGPT

1. In Settings → Apps and connectors, turn on developer mode (in the advanced settings) and choose Create.
2. Paste the URL https://api.selfcare.work/mcp and choose OAuth as the authentication.
3. Confirm on the Selfcare authorisation screen, as with Claude.

### Cursor

1. Open the Cursor settings, MCP section, and add the server to mcp.json (project or global).
2. On first use, Cursor opens the browser so you can sign in to Selfcare and authorise.

```json
{
  "mcpServers": {
    "selfcare": { "url": "https://api.selfcare.work/mcp" }
  }
}
```

### Other MCP clients

Any client that speaks MCP over Streamable HTTP and does OAuth 2.1 with discovery connects the same way:

1. Configure a remote MCP server with the URL https://api.selfcare.work/mcp.
2. The client receives the 401, reads the metadata, registers itself and opens the browser on the Selfcare authorisation screen.
3. You sign in with your account, choose the company and approve the scopes. The screen warns that this is an AI assistant.

### Without OAuth: API key

A client that doesn't do OAuth can use a personal API key, created in Settings → API with the scopes of the tools you'll use. The key is yours: keep it out of repositories and shared files.

1. Send the key in the Authorization header, as in the example.

```json
{
  "mcpServers": {
    "selfcare": {
      "url": "https://api.selfcare.work/mcp",
      "headers": { "Authorization": "Bearer <your API key>" }
    }
  }
}
```

## Scopes

- `me:read`: Who I am, the company, the role and the day's summary.
- `absences:read`: Visible absences, leave balance, who is out and the approvals inbox.
- `absences:write`: Request and cancel absences.
- `absences:decide`: Approve and reject absences.
- `expenses:read`: Visible expenses and categories.
- `expenses:write`: Create expenses, upload receipts and send for approval.
- `expenses:decide`: Approve and reject expenses.
- `trips:read`: Visible business trips and ajudas de custo (per diem).
- `trips:write`: Log and cancel business trips.
- `trips:decide`: Approve and reject business trips.
- `mileage:read`: Visible mapas de kms (mileage logs) and the person's vehicles.
- `mileage:write`: Create logs, add routes, calculate distances, submit and cancel.
- `mileage:decide`: Approve and reject mileage logs.
- `documents:read`: Documents allowed through MCP and temporary links to open them.
- `employees:read`: Employee directory and shared birthdays.

The payments:write scope (mark as paid or revert a payment) is sensitive. It sits outside the scopes a self-registered MCP client can request. The payment tools only work with an app registered in Settings → API that declares this scope, and with the explicit consent of an owner or HR.

## Tools by area

### Me and summary

- `get_me` (`me:read`): User, company, role, employee profile, teams they lead and the connection's scopes.
- `get_my_summary` (`me:read`): Leave balance, upcoming absences, pending decisions, unread documents and notifications, in a single call.

### Absences

- `get_vacation_balance` (`absences:read`): Leave balance.
- `list_absence_types` (`absences:read`): The company's absence types.
- `list_absences` (`absences:read`): Visible absences.
- `get_absence` (`absences:read`): One absence, without attachments such as medical certificates.
- `request_absence` (`absences:write`): Request leave or another absence.
- `cancel_absence` (`absences:write`): Cancel a request, or ask to cancel approved leave.
- `who_is_out` (`absences:read`): Who is out on a given day, with names and dates only.
- `list_pending_approvals` (`absences:read`): Requests waiting for the user's decision (absences, expenses and trips).
- `approve_absence` (`absences:decide`): Approve an absence the user can decide.
- `reject_absence` (`absences:decide`): Reject an absence the user can decide.

### Expenses

- `list_expenses` (`expenses:read`): Visible expenses, with status and reimbursement date.
- `get_expense` (`expenses:read`): One expense, with receipts and reimbursement status.
- `list_expense_categories` (`expenses:read`): Expense categories.
- `create_expense` (`expenses:write`): Create a draft expense.
- `get_expense_receipt_upload_url` (`expenses:write`): Get a link to upload the receipt.
- `add_expense_receipt` (`expenses:write`): Confirm the uploaded receipt, with the amount.
- `submit_expense` (`expenses:write`): Send the expense for approval.
- `approve_expense` (`expenses:decide`): Approve an expense.
- `reject_expense` (`expenses:decide`): Reject an expense, with a note for the person.

### Ajudas de custo (per diem and business trips)

- `list_business_trips` (`trips:read`): Visible business trips, with the per diem.
- `get_business_trip` (`trips:read`): One trip, with status, decision and amounts.
- `create_business_trip` (`trips:write`): Log a trip, which goes straight to approval.
- `cancel_business_trip` (`trips:write`): Cancel a trip.
- `approve_business_trip` (`trips:decide`): Approve a trip.
- `reject_business_trip` (`trips:decide`): Reject a trip, with a note for the person.
- `pay_business_trip` (`payments:write`): Mark as paid (only with payments:write).
- `revert_business_trip_payment` (`payments:write`): Revert the payment (only with payments:write).

### Mileage logs

- `list_mileage_maps` (`mileage:read`): Visible mileage logs.
- `get_mileage_map` (`mileage:read`): One log, with each route and the totals.
- `create_mileage_map` (`mileage:write`): Open the log for a month.
- `add_mileage_line` (`mileage:write`): Add a route to the log.
- `submit_mileage_map` (`mileage:write`): Send the log for approval.
- `cancel_mileage_map` (`mileage:write`): Cancel the log.
- `approve_mileage_map` (`mileage:decide`): Approve a log.
- `reject_mileage_map` (`mileage:decide`): Reject a log, with a note for the person.
- `pay_mileage_map` (`payments:write`): Mark as paid (only with payments:write).
- `revert_mileage_map_payment` (`payments:write`): Revert the payment (only with payments:write).
- `list_my_vehicles` (`mileage:read`): The user's vehicles, with the default one.
- `calculate_distance` (`mileage:write`): Calculate the km of a route, if the company has the maps service turned on.

### Documents

- `list_documents` (`documents:read`): Documents allowed through MCP.
- `get_document_link` (`documents:read`): Temporary link (5 minutes) to open a document. The access is logged.

### Employees and teams

- `search_employees` (`employees:read`): Search the directory as the user sees it in the app, with each person's teams and who leads them.
- `list_teams` (`employees:read`): The company's teams, with who leads each one and how many people it has (the leader counts once).
- `birthdays` (`employees:read`): A month's birthdays, only of people who share them (day and month).

### Prompts

- `request_vacation`: Book leave after checking the balance.

## Limits and rules

- **The person's profile decides.** The assistant acts as the person who authorised the connection, in the company they chose. It sees and does only what that person sees and does in the app, with the same roles and permissions.
- **Approvals are respected.** Each tool uses the Selfcare API, with the app's rules: who sees, who decides, each module's Who approves setting and idempotency. An assistant never gives anyone a decision power that person doesn't have in the app.
- **No salaries or IBANs.** Payroll, contracts, pay and the full IBAN never leave through MCP. Anything shaped like an IBAN is masked before it goes out.
- **Documents from the allowed list only.** Through MCP you can see only the company's internal rules, policies and manuals, and the person's own expense receipts. Payslips, contracts, identity documents, health documents, medical certificates and disciplinary documents never leave.
- **No accountants.** Accounts with the accountant role can't use MCP: the authorisation screen refuses and the server responds 403.
- **Everything is logged.** Each write goes into the company's audit log, marked as coming from MCP. The person revokes access in Settings → API → Authorized apps.

## Frequently asked questions

### Do I need a key or a token to connect the assistant?

No. The MCP client registers itself and opens the Selfcare authorisation screen, where you sign in with your account. The API key is only for clients that don't do OAuth.

### Does the assistant see the whole company's data?

It sees the same as you see in the app, and nothing more: your role and permissions apply to the assistant too.

### Can the assistant see salaries?

No. Payroll, contracts, pay and the full IBAN never leave through MCP.

### How do I disconnect the assistant?

In Settings → API → Authorized apps, revoke the assistant's connection.

### Does it cost anything?

No. The MCP server is included in every plan, as are the API and webhooks.

## More information

- Developer documentation: https://api.selfcare.work/docs#mcp
- API and integrations: https://www.selfcare.work/en/developers
- Security and GDPR: https://www.selfcare.work/en/security
