Connectar un client
Connecta qualsevol client MCP per Streamable HTTP, o mitjançant el servidor local de npm, i autentica’l amb OAuth o API key.
S’hi pot connectar qualsevol client MCP que admeti servidors remots per Streamable HTTP: el servidor implementa la revisió 2026-07-28 i també atén clients a 2025-11-25 i 2025-06-18 (consulta protocol i transport). Els clients que només executen processos locals fan servir el servidor local stdio.
Configuració de connexió
L’endpoint és https://mcp.factuarea.com (/mcp continua com a àlies). Configura el transport HTTP i OAuth 2.1 o una API key a Authorization: Bearer, més la capçalera X-Company-Id quan la clau abasta diversos NIF. La guia del protocol inclou una petició de discovery executable; els recursos i prompts expliquen l’orientació fiscal.
Catàleg i compatibilitat
Els clients de la revisió actual comencen per server/discover i els anteriors per initialize; en tots dos casos, segueix els cursors de tools/list amb la mateixa credencial. El catàleg complet té 668 eines; OAuth pot accedir a 541. Cap salutació inicial crea una sessió que substitueixi la credencial. A Claude Code, el plugin oficial registra el servidor per tu.
Servidor local stdio
Els clients que només executen processos locals —el fitxer de configuració de Claude Desktop, els frameworks d’agents, els runners de CI— poden fer servir el paquet oficial de npm @factuarea/mcp. És un petit servidor stdio que reenvia cada petició a https://mcp.factuarea.com amb una API key, així que les eines, els scopes, els guardrails i el mode test es comporten exactament igual que per HTTP. Necessita Node 20 o superior.
{
"mcpServers": {
"factuarea": {
"command": "npx",
"args": ["-y", "@factuarea/mcp"],
"env": { "FACTUAREA_API_KEY": "fact_test_xxxxxxxxxxxxxxxxxxxxxxxx" }
}
}
}Codi font, configuració i versions: github.com/factuarea/factuarea-mcp.
Autenticació
El servidor MCP accepta dos tipus de credencial al mateix
endpoint https://mcp.factuarea.com, per a dues audiències diferents. Totes dues arriben com a
Authorization: Bearer <token>; el servidor les distingeix per la
forma del token (fact_* → API key, qualsevol altra cosa → access token d'OAuth).
Política de canal
Aquesta és la regla més important de la superfície MCP:
| Canal | Qui | Com es trien els scopes | Tools accessibles |
|---|---|---|---|
| API key | El titular d'un compte automatitzant els seus NIF, o un proveïdor que opera els comptes dels seus clients | Tries els scopes en crear la clau — fins al super-scope *, que mai no cobreix els privilegiats accounts:* | 668 (tot), més les nou tools de comptes gestionats quan la clau llista accounts:* |
| OAuth 2.1 | Una app de tercers actuant en nom d'un usuari, sobre l'únic NIF triat al consentiment | L'usuari concedeix els scopes a la pantalla de consentiment, des d'un catàleg curat | 541 |
El model reflecteix el de GitHub: un personal access token (API key) és la credencial del propi compte i pot tenir qualsevol permís d'aquest, mentre que una OAuth app és externa i es limita a un conjunt verificat de scopes que l'usuari aprova explícitament.
Les 127 tools que una OAuth app mai pot abastar (només una API key pot) són les operacions fiscals i de privacitat més sensibles, a més de l'administració first-party del compte:
- Escriptures de VeriFactu (
verifactu:write) — 11 tools: registrar/reintentar/subsanar registres i esdeveniments de VeriFactu (inclòs reintentar d'un cop tots els bloquejats), registrar/revocar la representació que permet a Factuarea remetre en nom teu, pujar/activar/revocar certificats FNMT, actualitzar ajustos de VeriFactu. Toquen el compliment de l'AEAT i són exclusives del propietari. - Esborrament RGPD (
delivery_notes:gdpr_forget) — 1 tool: esborrar la PII d'auditoria de signatura (Art. 17). Privilegiada, només per a administradors. - Pagaments, passarel·les i botigues (
stripe_autoinvoicing:*,payouts:read,integration_events:*,stores:*,woocommerce_store:write,shopify_store:write) — 20 tools: 13 d’autofacturació Stripe, comptes connectats, payouts i safata/replay d’esdeveniments de passarel·la, més 7 de gestió de botigues i diagnòstic de connexió. Scopes granulars, només API key, sense equivalent de consentiment OAuth. - Emails i registre de peticions (
emails:read,developers:read) — 7 tools: l'historial de correus enviats i els registres de peticions, d'un NIF i del compte. - Cartera de NIF (
companies:*) — 15 tools: llistar, consultar, donar d'alta, editar, activar, desactivar i arxivar els NIF del compte, i el resum consolidat de compliment de jornada. - Claus i personalització (
account:write) — 5 tools: crear, rotar i revocar les API keys del compte, canviar els NIF que abasta una clau i actualitzar la personalització del compte. - Titularitat i traspassos de NIF (
account:owner,nif_transfers:*) — Tools per transferir la titularitat del compte i emetre, acceptar, revocar i llistar traspassos de NIF. - Equip (
members:*,invitations:*) — Tools per a membres, els seus grants en cada NIF, les seves restriccions de mòdul i les invitacions. - Webhooks de compte (
webhooks:*) — 10 tools: els webhook endpoints del compte i els seus lliuraments. El scope es pot concedir per consentiment, però aquestes tools s'exclouen d'OAuth una per una. - Escriptures/transicions privilegiades de personal — 33 tools amb
time_entries:write,absences:write,absences:transitionowork_schedules:write; les lectures iemployees:writecontinuen accessibles per OAuth. - Esborrat d'automatitzacions (
automations:delete) — 1 tool: eliminar una regla d'automatització, cosa que no es pot desfer des de l'API.
Aquests grups sumen les 127 tools. Altres deu tools, les de comptes
gestionats, queden fora dels dos recomptes: necessiten l'accounts:read o accounts:write
privilegiats, que el super-scope * no cobreix i el consentiment mai no concedeix, així que
només les abasta una API key d'un compte que tingui el privilegi
(comptes gestionats).
Tota la resta — les 541 tools de lectura/escriptura/transició/enviament — està disponible per a tots dos canals. Consulta Scopes & permisos per veure el catàleg.
Tools del compte
El model de comptes afegeix tools per administrar el compte i els seus NIF. Aquest és el canal que abasta cadascuna:
| Què | Tools | Scope | Canal |
|---|---|---|---|
| Titularitat i traspassos de NIF | transfer_account_ownership, create_nif_transfer, accept_nif_transfer, revoke_nif_transfer, list_nif_transfers (detall) | account:owner, nif_transfers:* | Només API key |
| Equip: membres, grants, restriccions de mòdul i invitacions | Tools com list_account_members, set_account_member_grant i create_account_invitation (detall) | members:*, invitations:* | Només API key |
| Cartera de NIF | 15 tools, com list_companies, create_company i get_consolidated_workforce (detall) | companies:* | Només API key |
| Consum del compte | get_account_usage | account:read | API key i OAuth |
| Els NIF que abasta una clau | update_api_key_nif_scope | account:write | Només API key |
| Comptes gestionats | 9 tools, com provision_managed_account i end_account_management | accounts:read, accounts:write | Només API key, i només amb el privilegi |
| Webhooks i registre de peticions del compte | 10 tools de webhooks (detall) i 2 de registre | webhooks:*, developers:read | Només API key, excloses d'OAuth tool per tool |
Les tools de compte necessiten una API key, i amb una també comproven qui crida: les de webhooks i registre del compte necessiten darrere la clau un titular o administrador del compte, i els scopes privilegiats necessiten el privilegi del compte a cada crida. Scopes i permisos descriu totes dues coses.
Algunes coses no tenen tool MCP, per disseny:
- La importació massiva de comptes gestionats. Les seves tres operacions són privilegiades
i llegeixen fitxers pujats, que el servidor MCP no transporta. Fes servir l'API REST o l'app,
o aprovisiona els comptes d'un en un amb
provision_managed_account: importació massiva. - La gestió d'un accés cedit. Cedir, canviar, revocar, acceptar, rebutjar i renunciar a l'accés d'un compte als NIF d'un altre són decisions d'una persona de cada compte, que l'app confirma: cap credencial cedeix ni accepta accés als NIF del seu compte. Accés cedit.
- El costat del client d'un compte gestionat. Consultar el proveïdor, pujar o baixar-ne el nivell, acabar la gestió, assumir el pagament i reclamar el compte ho fa el titular a l'app. Comptes gestionats.
API keys
Una API key és un Bearer token opac que pertany al teu compte i abasta els NIF del seu àmbit, creat al dashboard de desenvolupadors a Ajustos → Desenvolupadors → API Keys. El format i les regles són idèntics als de l'API REST:
fact_live_<24 alphanumeric characters> → production company
fact_test_<24 alphanumeric characters> → isolated sandbox companyEl prefix és la font de veritat de l'entorn — consulta Mode de prova. El secret es mostra només una vegada en la creació; el backend només emmagatzema un hash amb clau (HMAC-SHA256) d'ell. Passa'l al teu client MCP com a:
Authorization: Bearer fact_test_xxxxxxxxxxxxxxxxxxxxxxxxPer al cicle de vida complet de la clau — creació, scopes, rotació amb període de gràcia,
revocació, llista d'accés d'IPs, expires_at — consulta la
guia d'Autenticació canònica. Les claus es comparteixen entre les superfícies REST
i MCP.
OAuth 2.1
Per a apps de tercers, Factuarea és un OAuth 2.1 Authorization Server complet. És compatible amb Dynamic Client Registration, el flux d'authorization-code amb PKCE i la rotació de refresh-token. No cal pre-registre ni aprovació manual de l'app — un client es registra a si mateix i l'usuari l'autoritza. (Els clients interactius com Claude Code i el MCP Inspector executen tot aquest flux per tu; els passos de sota són per construir el teu propi client.)
Descobriment
Els clients descobreixen les capacitats del servidor a través d'endpoints de metadata estàndard
(sense prefix /api):
| Endpoint | RFC | Propòsit |
|---|---|---|
/.well-known/oauth-authorization-server | 8414 | Authorization Server Metadata — llista els endpoints authorize/token/register/introspect/revoke, els scopes admesos, code_challenge_methods_supported: ["S256"]. |
/.well-known/oauth-protected-resource | 9728 | Protected Resource Metadata — declara el recurs MCP i quin authorization server emet tokens vàlids. |
Quan una petició no autenticada abasta l'endpoint, el servidor respon 401
amb un header WWW-Authenticate: Bearer ..., resource_metadata="<url>" perquè els clients RFC
9728 trobin l'authorization server sense endevinar.
1. Dynamic Client Registration (RFC 7591)
Un client es registra a si mateix fent POST de la seva metadata; el servidor retorna un
client_id (i un client_secret per a clients confidencials):
curl -X POST https://mcp.factuarea.com/api/oauth/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "My Invoicing Assistant",
"redirect_uris": ["https://myapp.example.com/callback"],
"token_endpoint_auth_method": "none"
}'Els clients públics (apps de navegador/natives) es registren amb
token_endpoint_auth_method: "none" i depenen de PKCE; els clients confidencials fan servir
client_secret_basic. El registre té un rate limit de 60 per minut per IP. El registre dinàmic admet només aquests dos mètodes; per a private_key_jwt consulta clients identificats per un document de metadades.
2. Autorització amb PKCE
Envia l'usuari a l'endpoint authorize amb un challenge PKCE
(code_challenge_method=S256 és l'únic mètode acceptat):
GET https://mcp.factuarea.com/api/oauth/authorize
?response_type=code
&client_id=<client_id>
&redirect_uri=https://myapp.example.com/callback
&scope=factuarea.read invoices.write
&state=<opaque>
&code_challenge=<base64url(sha256(verifier))>
&code_challenge_method=S256Això renderitza la pantalla de consentiment, on l'usuari:
- Tria el compte i l'empresa (NIF) al qual donar accés. La pantalla llista les teves
empreses i les dels comptes dels teus clients, cadascuna amb el compte al qual pertany i el
teu nivell d'accés (Veure o Operar). El token queda vinculat a aquesta única empresa i
X-Company-Idno la pot ampliar. - Tria l'entorn — Producció (l'empresa real,
live) o Proves (un sandbox aïllat,test), a l'estil Stripe. Proves és opt-in; si és absent ⇒ producció. - Revisa i selecciona els scopes a concedir. Els scopes sensibles es marquen i
no vénen pre-seleccionats. Amb nivell Veure només es poden concedir els de lectura (els
que acaben en
.readi el macrofactuarea.read), i a Proves no es concedeixen els dels mòduls que el sandbox no ofereix; consulta què concedeix la pantalla segons el nivell i l'entorn.
La sol·licitud de consentiment caduca als 5 minuts d'obrir-se i la pantalla diu quants minuts queden. Si caduca, torna a llançar l'autorització des de la teva app.
En aprovar, el servidor redirigeix de tornada amb un code d'un sol ús (i el teu
state). Les operacions sensibles es filtren del catàleg que l'usuari pot
aprovar — consulta la política de canal.
3. Intercanvi de token
Intercanvia el code per un access token, enviant el verificador PKCE:
curl -X POST https://mcp.factuarea.com/api/oauth/token \
-d grant_type=authorization_code \
-d code=<code> \
-d redirect_uri=https://myapp.example.com/callback \
-d client_id=<client_id> \
-d code_verifier=<verifier>{
"access_token": "<opaque>",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "<opaque>",
"scope": "profile.read contacts.read invoices.read invoices.write"
}El token persisteix els scopes expandits i de gra fi (les macros com
factuarea.read s'expandeixen en el moment de l'emissió). Fes servir l'access token com a
credencial Bearer. L'endpoint token té un rate limit de 60 per minut per (client,
IP) i requereix autenticació de client (HTTP Basic per a clients confidencials,
client_id al body per als públics).
4. Rotació de refresh-token
Els refresh tokens roten per família: cada refresh emet un nou access token i un nou refresh token, i invalida el que vas fer servir.
curl -X POST https://mcp.factuarea.com/api/oauth/token \
-d grant_type=refresh_token \
-d refresh_token=<refresh_token> \
-d client_id=<client_id>Si un refresh token es reutilitza (usat després de la rotació — el senyal clàssic d'una fuita), el servidor detecta la reutilització, revoca tota la família de tokens i llança una alerta de seguretat. Emmagatzema i fes servir sempre només el darrer refresh token.
Revocació i introspecció
| Endpoint | RFC | Propòsit |
|---|---|---|
POST /api/oauth/revoke | 7009 | Revoca un access o refresh token. |
POST /api/oauth/introspect | 7662 | Comprova si un token està actiu i llegeix els seus scopes/metadata. |
Tots dos requereixen autenticació de client. Els usuaris també poden revisar i revocar apps connectades des del dashboard de Factuarea, i a un administrador d'empresa que perd l'accés se li revoquen els tokens automàticament en la següent crida.
Triar el NIF
Una credencial abasta un NIF o diversos. L'àmbit d'una API key es fixa quan l'emets, i pot
incloure NIF del teu propi compte, NIF que un altre compte cedeix al teu
(accés cedit) i NIF dels comptes gestionats que aprovisiones
(comptes gestionats). L'API REST anomena el NIF al segment
{company} de la ruta
(arribar a un NIF pel segment d'empresa). Una crida
JSON-RPC no té ruta, així que la sessió l'anomena amb una capçalera HTTP:
X-Company-Id: 01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8b11El valor és l'id públic del NIF, l'UUID v7 que accepta el segment {company} i que
GET /v1/me llista per a cada NIF que
abasta la credencial. Declara'l un cop a la configuració del teu servidor, al costat
d'Authorization: mai no és un argument d'una tool. Una capçalera present però buida compta
com a absent.
| Credencial | X-Company-Id | Què passa |
|---|---|---|
| API key que abasta un NIF | absent | La sessió treballa sobre aquest NIF. |
| API key que abasta diversos | absent | La crida falla abans d'executar cap tool, amb un error -32008 el data.code del qual és company_selection_required i el data.http_status del qual és 400. data.companies llista els NIF de l'àmbit amb el seu id i el seu name (els 20 primers, i el hint diu quants més). |
| API key | anomena un NIF del seu àmbit | La sessió treballa sobre aquest NIF. |
| API key | anomena un NIF fora del seu àmbit, un que no existeix o un de l'altre entorn | 404 profile_not_found, la mateixa resposta per als tres, així que mai no confirma que un NIF existeixi. |
| Connexió OAuth | absent, o anomena el NIF triat al consentiment | La sessió treballa sobre aquest NIF. |
| Connexió OAuth | anomena un altre NIF | 404 profile_not_found, amb una pista per autoritzar de nou triant aquest NIF. |
Un NIF de l'àmbit que està desactivat o arxivat respon
403 company_inactive, amb capçalera o sense. Tots són errors
-32008 (consulta Errors i límits de peticions): data.code porta el codi i
data.http_status l'status, i tots els codis llevat de company_selection_required són els
mateixos que a l'API REST.
El que la sessió pot fer sobre el NIF depèn del nivell que la teva credencial hi té. Amb
view, tota tool que escriu al NIF respon
403 company_read_only, i amb operate escriu, com a l'API REST
(nivells). El nivell és el menor entre el guardat a la clau
per a aquest NIF i el vigent de la persona que va emetre la clau; una connexió OAuth pren el
nivell de la persona.
Clients identificats per un document de metadades
Alguns clients, com ChatGPT o Claude, no es registren a /register: el seu client_id és una URL HTTPS que apunta a un document de metadades públic (CIMD). Aquests clients poden autenticar-se a /api/oauth/token, /api/oauth/revoke i /api/oauth/introspect amb private_key_jwt (RFC 7523): en lloc d’un secret, envien un JWT signat amb una clau publicada al jwks_uri del seu document.
curl -X POST https://mcp.factuarea.com/api/oauth/token \
-d grant_type=authorization_code \
-d code=<code> \
-d redirect_uri=https://myapp.example.com/callback \
-d client_id=https://myapp.example.com/oauth/client.json \
-d code_verifier=<verifier> \
-d client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
-d client_assertion=<JWT signat>L’asserció ha de complir aquestes condicions:
| Requisit | Detall |
|---|---|
| Algorisme | RS256 o ES256. |
iss i sub | Tots dos iguals al client_id. |
aud | La URL de l’endpoint de token (o l’issuer). |
exp | Com a màxim a 300 segons vista; admetem 60 segons de desfasament de rellotge. |
jti | Únic: cada valor s’accepta una sola vegada. |
Si el kid de l’asserció no és al JWKS en memòria cau, el tornem a carregar una vegada abans de rebutjar-la. Una petició no pot combinar client_secret amb client_assertion: es respon amb 400 invalid_request. Si el document declara un mètode que no admetem però també inclou none a token_endpoint_auth_methods_supported, el client es tracta com a públic i PKCE passa a ser obligatori.
/.well-known/oauth-authorization-server anuncia private_key_jwt a token_endpoint_auth_methods_supported, revocation_endpoint_auth_methods_supported i introspection_endpoint_auth_methods_supported (["none", "client_secret_basic", "private_key_jwt"]), i token_endpoint_auth_signing_alg_values_supported és ["RS256", "ES256"].
Quan /api/oauth/authorize no pot acceptar el document d’un client, respon 400 amb error: "invalid_client" i un error_reason llegible:
error_reason | Significat |
|---|---|
client_metadata_unsupported | El document no és compatible amb el que admet el servidor. |
client_metadata_unavailable | No hem pogut descarregar el document. |
client_metadata_disabled | Els clients amb document de metadades estan desactivats. |
En un navegador, l’usuari és redirigit en lloc d’això a la nostra pròpia pantalla, /oauth/authorize?authorize_error=<motiu>&client_id=…, que explica el problema en castellà, anglès i català.
Mode de prova
El servidor MCP funciona contra els mateixos dos entorns que l'API REST — live (la teva empresa real) i test (un sandbox aïllat) — perquè puguis construir i validar una integració d'agent sense tocar dades de producció, l' AEAT ni les safates d'entrada dels teus clients.
Com selecciones el mode de prova depèn del canal:
| Canal | Com fer servir el mode de prova |
|---|---|
| API key | Autentica't amb una clau fact_test_. El prefix és la font de veritat — un token fact_test_ sempre opera sobre el sandbox. |
| OAuth 2.1 | A la pantalla de consentiment, tria l'entorn Proves (test, a l'estil Stripe). Si és absent ⇒ live. El token emès queda vinculat a aquest entorn. |
Una credencial de test opera sobre una empresa sandbox dedicada — un bessó tècnic de la teva empresa real, aprovisionat automàticament i que hereta el seu pla, perquè el gating de mòdul/pla es comporti fidelment. L'aïllament és estructural (les dades de test i live viuen en empreses separades), i els efectes externs estan desactivats:
| Efecte | A live | A test |
|---|---|---|
| VeriFactu | El registre d'Alta es crea i es transmet a l'AEAT. | Es crea localment, però mai es transmet a l'AEAT. |
| Els emails de documents arriben als destinataris reals. | No s'entreguen als destinataris reals. | |
| Webhooks | Els esdeveniments subscrits s'entreguen als teus endpoints. | Es registren amb livemode: false, però no s'entreguen. |
| FACe (FacturaE) | Els enviaments es presenten al web service real de FACe. | Simulats — cap crida SOAP surt de Factuarea; el número de registre és sintètic (FACE-SANDBOX-*). |
Una sessió de prova només abasta el seu sandbox. Una clau fact_test_, o una connexió que va
triar l'entorn Test, no pot anomenar un NIF real amb X-Company-Id, i una
live no pot anomenar un sandbox: totes dues responen 404 profile_not_found.
Tota la resta es comporta exactament igual que en producció, i el conjunt complet de 668 tools
està disponible en tots dos entorns (subjecte als teus scopes i pla), amb una excepció: les
tools que escriuen al compte mateix —equip, titularitat, traspassos de NIF, cartera, claus i
webhooks— responen 403 live_credential_required quan una clau de proves les crida sobre un
compte live. Provar comptes gestionats amb clau fact_test_
mostra què fa una clau de proves amb els comptes. Quan el teu flux funcioni d'extrem a extrem,
canvia a live: crea una clau fact_live_, o torna a executar el flux de consentiment i
selecciona l'entorn Producció (live).
Aquest és el mateix mecanisme de sandbox que l'API REST. Consulta la guia canònica Mode de prova & sandbox per saber com s'aprovisiona i es consulta l'empresa sandbox.