# PracticeReady MCP server — setup instructions for AI assistants

This document explains how to connect an AI assistant (Claude, Cursor, or any
MCP client) to PracticeReady so it can log internship activities and CPD
activities for the signed-in user, and answer compliance questions.

## Server

- **Endpoint:** https://practiceready.com.au/mcp
- **Transport:** remote HTTP, JSON-RPC 2.0 (POST). Streamable HTTP compatible.
- **Protocol versions:** 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05.
- Send `MCP-Protocol-Version: 2025-06-18` (or the version your client negotiates).
- Authentication: **OAuth 2.0 — no API key is created or pasted.**

## Authentication flow

1. Connect to the endpoint. Unauthenticated requests return HTTP 401 with a
   `WWW-Authenticate` header pointing at the protected-resource metadata.
2. Discover the authorization server:
   - `GET /.well-known/oauth-protected-resource/mcp`
   - `GET /.well-known/oauth-authorization-server/mcp`
3. Register the client dynamically:
   `POST /oauth/register` with `{"redirect_uris": ["<your client redirect URI>"]}`.
   The response contains `client_id` and `grant_types`.
4. Open the advertised `authorization_endpoint` in the user's browser with
   `response_type=code`, your `client_id`, `redirect_uri`, `scope=mcp:use`,
   `code_challenge` and `code_challenge_method=S256` (PKCE is required).
5. The user signs in to PracticeReady (if needed) and clicks **Authorize** on
   the consent screen once. No credentials pass through the AI.
6. Exchange the authorization code at the advertised `token_endpoint` with
   `grant_type=authorization_code`, `client_id`, `redirect_uri`, `code`, and
   `code_verifier`.
7. Send `Authorization: Bearer <access_token>` on every request to https://practiceready.com.au/mcp.

The token inherits the user's PracticeReady account and role. It is scoped to
`mcp:use`; tokens without that scope are rejected with HTTP 403.

## Adding the server to a client

**Claude (Desktop / claude.ai):** Settings → Connectors → Add custom connector,
enter `https://practiceready.com.au/mcp` as the remote MCP server URL, then complete the browser
sign-in.

**Cursor (`~/.cursor/mcp.json`):**

```json
{
  "mcpServers": {
    "practiceready": {
      "url": "https://practiceready.com.au/mcp"
    }
  }
}
```

Most MCP clients discover OAuth automatically from the 401 challenge. If your
client asks for an authorization URL instead, use the `authorization_endpoint`
from step 2 with `scope=mcp:use`.

## Tools

| Tool | Purpose |
| --- | --- |
| `create-log` | Log an activity from a natural-language description. Asks a clarifying question when details are missing; pass the answers back in a follow-up call (the draft continues automatically). |
| `get-compliance-status` | Internship compliance (ratio, hours, observations, advice) or CPD hours against the 30h/year requirement (20 education + 10 peer consultation). |
| `list-logs` | List internship logs or CPD activities and learning goals, with filters. |
| `get-weeks` | Internship only: weekly rollups of logs, hours and approval state. |
| `get-week-details` | Internship only: all logs in one week plus a breakdown. |
| `get-signoff-status` | Internship only: weeks still missing a signature. |

### Which domain applies

The user's role decides the domain — never ask the user to choose it:

- `supervisee` → internship logs (practice, education, supervision, reflection).
- `cpd` → CPD activities (education or peer consultation) and CPD learning goals.
- Any other role → the logging tools return an error payload.

## Verify the connection

1. Call `tools/list` — the six tools above must be present.
2. Call `get-compliance-status` — it should return the user's real data.
3. Log a small test activity with `create-log` only after confirming with the user.

## Safety rules for the assistant

- `create-log` writes real compliance records. Confirm the activity, type and
  hours with the user before logging.
- Never invent hours, dates, client details, or reflections.
- `create-log` is conversational: when it asks for missing details, relay the
  question to the user and call it again with the answers.
- Approved logs are immutable; corrections must be made by the user in
  PracticeReady.

## Troubleshooting

| Symptom | Cause and fix |
| --- | --- |
| HTTP 401 | No/expired token — re-run the browser authorization flow. |
| HTTP 403 | Token lacks the `mcp:use` scope — re-authorize requesting that scope. |
| 404 on discovery | Use the `/.well-known/...` paths above; they are served from the app root, not under `/mcp`. |
| Client registration rejected | The redirect URI is not permitted by the server's `mcp.redirect_domains` configuration. |
| 500 on authorization | Server signing keys are missing — run `php artisan passport:keys` (one-time, persistent storage). |