---
title: "Authenticating with officina.it"
description: "How an AI agent obtains credentials for officina.it, the Italian car-workshop management system. Two paths: an OAuth connection for MCP clients, or an API key for software integrations."
---

# Authenticating with officina.it

> How an AI agent obtains credentials for officina.it, the Italian car-workshop management system. Two paths: an OAuth connection for MCP clients, or an API key for software integrations.

Every credential belongs to one workshop (company) and acts with the permissions of the user or key that created it. There is no anonymous access to workshop data and no self-service agent signup: a human workshop user always approves the connection.

## Discover

- MCP server: `https://mcp.officina.it/mcp`. Calling it without a token answers `401` with `WWW-Authenticate: Bearer resource_metadata="…"`.
- Protected-resource metadata (RFC 9728): `https://mcp.officina.it/.well-known/oauth-protected-resource`
- Authorization-server metadata (RFC 8414): `https://officina.it/.well-known/oauth-authorization-server`
- REST API contract: `https://api.officina.it/openapi.json`

## Pick a method

| You are | Use | Credential |
|---|---|---|
| An assistant (Claude, ChatGPT, any MCP client) acting for a workshop user in a conversation | MCP + OAuth | short-lived access token, scope `officina.read` (+ `offline_access` for a refresh token) |
| A program syncing data with api.officina.it | REST API | API key `ofk_live_…` with per-resource scopes |

## OAuth for MCP clients

1. **Register.** Use a Client ID Metadata Document (the authorization server advertises `client_id_metadata_document_supported`) or dynamic client registration at the `registration_endpoint`. Clients are public: PKCE, no client secret.
2. **Authorize.** Send the user to the `authorization_endpoint` with `response_type=code`, PKCE `S256`, `scope=officina.read offline_access` and `resource=https://mcp.officina.it/mcp`. The user logs in to officina.it and approves the connection.
3. **Exchange.** Trade the code at the `token_endpoint` for an access token (audience: the MCP resource) and, with `offline_access`, a rotating refresh token.
4. **Use.** Send `Authorization: Bearer <access_token>` on every MCP request. Tools: `search_api` finds the read operation for a question, `call_read` runs it.

Access requires a Pro plan or higher, or an active trial. Without it, tools answer with an error that names the reason; there is nothing an agent can do about it except tell the user.

## API keys for integrations

A workshop admin creates the key in **Impostazioni › Accesso API**, grants only the scopes needed (`resource.read` / `resource.write`), and copies it once. The REST API needs a Business or Illimitato plan.

```bash
curl https://api.officina.it/v1/whoami \
  -H "Authorization: Bearer ofk_live_YOUR_API_KEY" \
  -H "X-API-Version: 2026-10-31"
```

## Errors

- `401` + `WWW-Authenticate`: missing, expired or revoked token — refresh it, or restart the OAuth flow.
- `403 insufficient_scope`: the key or token lacks the scope for that operation.
- `402 plan_upgrade_required` (REST): the workshop's plan does not include API access.

## Revocation

A client revokes its own refresh token at the `revocation_endpoint` (RFC 7009). Users end AI connections from **Impostazioni › Sessioni attive › App collegate**; changing the password or logging out everywhere ends them too. Admins revoke API keys from **Impostazioni › Accesso API**. A revoked credential stops working: the next request answers `401`.

More: https://officina.it/api (API docs, Italian) · https://officina.it/api/skill.md (agent skill) · https://officina.it/llms.txt
