Skip to content

Serveur MCP Scell.io -- 54 Outils

Version: 1.2.0 Protocole: MCP 2024-11-05 Transport: HTTP Streamable + SSE


Table des matieres

  1. Introduction
  2. Installation et Configuration
  3. Outils Disponibles (54)
  4. Exemples d'Integration
  5. Architecture Technique

1. Introduction

Qu'est-ce que MCP (Model Context Protocol) ?

Le Model Context Protocol (MCP) est un standard ouvert initie par Anthropic permettant aux modeles de langage (LLM) d'interagir avec des services externes de maniere structuree. Le protocole definit un format JSON-RPC 2.0 pour decouvrir et appeler des outils mis a disposition par un serveur.

Un serveur MCP expose :

  • Des outils (tools) : fonctions que le LLM peut appeler avec des parametres JSON Schema
  • Des ressources (resources) : donnees contextuelles accessibles en lecture
  • Des prompts (prompts) : templates de conversation preconfigures

Pourquoi un serveur MCP pour la facturation ?

Scell.io integre un serveur MCP natif permettant aux agents IA de :

  • Creer des factures conformes Factur-X/UBL/CII par simple instruction en langage naturel
  • Gerer les signatures electroniques (eIDAS EU-SES) via conversation
  • Consulter la conformite fiscale NF525/ISCA en temps reel
  • Administrer les tenants et sous-tenants sans interface graphique
  • Exporter les donnees fiscales (FEC, forensic) a la demande

Cas d'usage typique : un comptable demande a Claude "Cree une facture de 500 EUR HT pour ACME SAS" et le LLM appelle directement create_invoice via MCP.

Compatibilite

Le serveur MCP Scell.io est compatible avec :

  • Claude Desktop (via claude_desktop_config.json)
  • Claude Code (connexion directe)
  • Tout client MCP implementant le protocole 2024-11-05
  • Agents IA custom via appels HTTP JSON-RPC

2. Installation et Configuration

Endpoint

Le serveur MCP est accessible a l'adresse :

POST https://api.scell.io/mcp/

Endpoints disponibles :

MethodeURLDescription
GET/mcp/Informations serveur (public)
POST/mcp/Handler JSON-RPC (authentifie)
GET/mcp/streamFlux SSE (optionnel)

Authentification

Le serveur accepte deux types de cles API via le header X-Scell-API-Key :

Type de cleFormatOutils accessibles
Cle utilisateursk_live_xxx / sk_test_xxxFactures, Signatures, Systeme, Validation, Compte, Audit
Cle tenantsk_live_xxx / sk_test_xxxTous les 54 outils (incluant Fiscal, Tenant, Billing, Sub-Tenant)
bash
# Exemple avec cle utilisateur
curl -X POST https://api.scell.io/mcp/ \
  -H "X-Scell-API-Key: sk_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'

Configuration backend

Le fichier config/mcp.php controle le comportement du serveur :

php
return [
    'enabled' => env('MCP_ENABLED', true),
    'version' => '2024-11-05',        // Version du protocole MCP
    'server' => [
        'name' => 'scell-mcp-server',
        'version' => '1.2.0',
    ],
    'session' => [
        'ttl' => env('MCP_SESSION_TTL', 3600),    // Duree de session : 1h
        'driver' => env('MCP_SESSION_DRIVER', 'redis'),
    ],
    'rate_limit' => [
        'requests_per_minute' => env('MCP_RATE_LIMIT', 60),
    ],
];

Variables d'environnement :

VariableDescriptionDefaut
MCP_ENABLEDActive/desactive le serveur MCPtrue
MCP_SESSION_TTLDuree de vie des sessions (secondes)3600
MCP_SESSION_DRIVERDriver de stockage des sessionsredis
MCP_RATE_LIMITRequetes par minute par cle API60

Flux d'initialisation

Avant d'utiliser les outils, le client doit initialiser une session :

Client                          Serveur MCP
  |                                  |
  |-- POST /mcp/ (initialize) ----->|
  |<---- session-id + capabilities --|
  |                                  |
  |-- POST /mcp/ (tools/list) ----->|
  |<---- liste des 54 outils -------|
  |                                  |
  |-- POST /mcp/ (tools/call) ----->|
  |<---- resultat de l'outil -------|

Requete initialize :

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "clientInfo": {
      "name": "mon-agent",
      "version": "1.0.0"
    }
  }
}

Reponse :

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": { "listChanged": true }
    },
    "serverInfo": {
      "name": "scell-mcp-server",
      "version": "1.2.0"
    }
  }
}

Le header de reponse mcp-session-id contient l'identifiant de session a renvoyer dans les requetes suivantes.


3. Outils Disponibles (54)

3.1 Factures (4 outils)

create_invoice

Cree une facture electronique conforme Factur-X/UBL/CII.

Parametres :

json
{
  "type": "object",
  "required": ["invoice_number", "issue_date", "due_date", "seller", "buyer", "lines"],
  "properties": {
    "invoice_number": { "type": "string", "description": "Numero de facture unique" },
    "issue_date": { "type": "string", "format": "date", "description": "Date d'emission (YYYY-MM-DD)" },
    "due_date": { "type": "string", "format": "date", "description": "Date d'echeance (YYYY-MM-DD)" },
    "seller": {
      "type": "object",
      "required": ["name", "address", "city", "postal_code"],
      "properties": {
        "name": { "type": "string" },
        "siret": { "type": "string" },
        "vat_number": { "type": "string" },
        "address": { "type": "string" },
        "city": { "type": "string" },
        "postal_code": { "type": "string" },
        "country": { "type": "string", "default": "FR" }
      }
    },
    "buyer": {
      "type": "object",
      "required": ["name", "address", "city", "postal_code"],
      "properties": {
        "name": { "type": "string" },
        "siret": { "type": "string" },
        "vat_number": { "type": "string" },
        "address": { "type": "string" },
        "city": { "type": "string" },
        "postal_code": { "type": "string" },
        "country": { "type": "string", "default": "FR" }
      }
    },
    "lines": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["description", "quantity", "unit_price"],
        "properties": {
          "description": { "type": "string" },
          "quantity": { "type": "number" },
          "unit_price": { "type": "number" },
          "vat_rate": { "type": "number", "default": 20 }
        }
      }
    },
    "format": { "type": "string", "enum": ["facturx", "ubl", "cii"], "default": "facturx" },
    "profile": { "type": "string", "enum": ["minimum", "basicwl", "basic", "en16931", "extended"], "default": "en16931" }
  }
}

Exemple d'appel :

json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "create_invoice",
    "arguments": {
      "invoice_number": "FA-2026-001",
      "issue_date": "2026-03-03",
      "due_date": "2026-04-02",
      "seller": {
        "name": "Ma Societe SAS",
        "siret": "12345678900001",
        "address": "10 rue de la Paix",
        "city": "Paris",
        "postal_code": "75002"
      },
      "buyer": {
        "name": "ACME SAS",
        "siret": "98765432100001",
        "address": "5 avenue des Champs",
        "city": "Lyon",
        "postal_code": "69001"
      },
      "lines": [
        { "description": "Prestation de conseil", "quantity": 5, "unit_price": 100, "vat_rate": 20 }
      ],
      "format": "facturx",
      "profile": "en16931"
    }
  }
}

Reponse type :

json
{
  "content": [{
    "type": "text",
    "text": {
      "id": "9f3a1b2c-...",
      "invoice_number": "FA-2026-001",
      "status": "draft",
      "total_ht": 500.0,
      "total_tax": 100.0,
      "total_ttc": 600.0,
      "download_url": "https://api.scell.io/api/v1/invoices/9f3a1b2c-.../download/pdf",
      "xml_url": "https://api.scell.io/api/v1/invoices/9f3a1b2c-.../download/xml"
    }
  }]
}

Cout : 0.04 EUR par facture (gratuit en sandbox).


get_invoice

Recupere les details d'une facture par son ID.

Parametres : { "invoice_id": "string (UUID, requis)" }

Reponse : Objet facture complet (numero, montants, statut, lignes, URLs de telechargement).


list_invoices

Liste les factures avec filtrage et pagination.

Parametres :

ParametreTypeDescription
statusstringFiltrer par statut : draft, submitted, paid
date_fromstring (date)Date de debut
date_tostring (date)Date de fin
pageintegerPage (defaut: 1)
per_pageintegerElements par page (defaut: 15, max: 100)

download_invoice

Telecharge une facture dans le format souhaite.

Parametres :

ParametreTypeDescription
invoice_idstringUUID de la facture (requis)
formatstringFormat : pdf, xml, facturx, ubl, cii (defaut: pdf)

Reponse : URL de telechargement temporaire ou contenu encode en base64.


3.2 Signatures (6 outils)

create_signature

Cree une demande de signature electronique simple (eIDAS EU-SES).

Parametres :

json
{
  "type": "object",
  "required": ["document_name", "signer"],
  "properties": {
    "document_name": { "type": "string", "description": "Nom du document a signer" },
    "document_url": { "type": "string", "format": "uri", "description": "URL du PDF (accessible publiquement)" },
    "document_base64": { "type": "string", "description": "PDF encode en base64 (alternative a document_url)" },
    "signer": {
      "type": "object",
      "required": ["first_name", "last_name", "email"],
      "properties": {
        "first_name": { "type": "string" },
        "last_name": { "type": "string" },
        "email": { "type": "string", "format": "email" },
        "phone": { "type": "string", "description": "Telephone pour OTP SMS (format E.164)" }
      }
    },
    "otp_method": { "type": "string", "enum": ["sms", "email"], "default": "email" },
    "webhook_url": { "type": "string", "format": "uri" },
    "redirect_url": { "type": "string", "format": "uri" }
  }
}

Reponse type :

json
{
  "id": "a1b2c3d4-...",
  "status": "pending",
  "signing_url": "https://api.scell.io/sign/a1b2c3d4-...",
  "expires_at": "2026-04-02T00:00:00+00:00",
  "signer": {
    "email": "jean.dupont@example.com",
    "otp_method": "email"
  }
}

Cout : 1.20 EUR par signature (gratuit en sandbox).


get_signature

Recupere les details d'une signature. Parametres : { "signature_id": "string (UUID)" }

list_signatures

Liste les signatures avec filtrage. Parametres : status, date_from, date_to, page, per_page.

download_signed

Telecharge le document signe. Parametres : { "signature_id": "string (UUID)" }. Disponible uniquement apres completion.

cancel_signature

Annule une demande de signature en cours. Parametres : { "signature_id": "string (UUID)" }. Seules les signatures au statut pending peuvent etre annulees.

send_reminder

Envoie un rappel au signataire. Parametres : { "signature_id": "string (UUID)" }. Un rappel par heure maximum.


3.3 Avoirs (7 outils) -- Tenant uniquement

Ces outils necessitent une cle tenant (tk_*).

create_credit_note

Cree un avoir lie a une facture existante.

Parametres :

ParametreTypeDescription
invoice_idstringUUID de la facture d'origine (requis)
reasonstringMotif de l'avoir (requis)
linesarrayLignes de l'avoir (description, quantity, unit_price, vat_rate)

get_credit_note

Recupere un avoir par son ID. Parametres : { "credit_note_id": "string" }

list_credit_notes

Liste les avoirs avec pagination. Parametres : status, page, per_page.

download_credit_note

Telecharge l'avoir en PDF. Parametres : { "credit_note_id": "string" }

send_credit_note

Envoie l'avoir (change le statut de draft a sent). Parametres : { "credit_note_id": "string" }

delete_credit_note

Supprime un avoir (uniquement au statut draft). Parametres : { "credit_note_id": "string" }

get_remaining_creditable

Retourne le montant restant creditable sur une facture. Parametres : { "invoice_id": "string" }


3.4 Fiscal (12 outils) -- Tenant uniquement

get_fiscal_compliance

Retourne le statut de conformite fiscale NF525/ISCA du tenant.

Parametres : aucun.

Reponse type :

json
{
  "compliant": true,
  "last_closing": "2026-03-02",
  "chain_integrity": "valid",
  "entries_count": 1247,
  "last_attestation_year": 2025,
  "kill_switch_status": "inactive"
}

check_fiscal_integrity

Verifie l'integrite de la chaine de hachage fiscale.

Parametres :

ParametreTypeDescription
date_fromstring (date)Date de debut (optionnel, verification complete si omis)
date_tostring (date)Date de fin (optionnel)

Reponse type :

json
{
  "result": "valid",
  "entries_checked": 1247,
  "first_sequence": 1,
  "last_sequence": 1247,
  "discrepancies_count": 0,
  "discrepancies": [],
  "duration_ms": 342,
  "verified_at": "2026-03-03T14:30:00+00:00"
}

list_fiscal_entries

Liste les ecritures du grand livre fiscal. Parametres : entry_type, date_from, date_to, page, per_page.

list_fiscal_closings

Liste les clotures fiscales (journalieres/mensuelles). Parametres : closing_type, page, per_page.

get_fiscal_attestation

Recupere l'attestation de conformite annuelle. Parametres : { "year": "integer (requis)" }

get_kill_switch_status

Retourne l'etat du kill switch fiscal. Parametres : aucun.

list_fiscal_rules

Liste les regles fiscales configurees pour le tenant. Parametres : page, per_page.

export_fec

Exporte le Fichier des Ecritures Comptables (FEC) conforme DGFIP. Parametres : year (requis), format (pipe ou tab, defaut: pipe).

perform_daily_closing

Declenche une cloture journaliere manuelle. Parametres : aucun. Normalement automatique a 00:05 UTC.

activate_kill_switch

Active le kill switch fiscal (arret d'urgence). Parametres : { "reason": "string (requis)" }. Necessite le scope fiscal:admin.

deactivate_kill_switch

Desactive le kill switch fiscal. Parametres : { "reason": "string (requis)" }. Necessite le scope fiscal:admin.

export_forensic

Exporte l'ensemble des donnees fiscales pour audit forensique. Parametres : date_from, date_to.


3.5 Systeme (2 outils)

health_check

Verifie l'etat de sante de l'API et de ses services.

Parametres : aucun.

Reponse type :

json
{
  "status": "healthy",
  "services": {
    "database": "healthy",
    "cache": "healthy"
  },
  "version": "1.2.0",
  "environment": "production",
  "timestamp": "2026-03-03T14:30:00+00:00"
}

validate_api_key

Verifie la validite d'une cle API et retourne ses informations (scopes, environnement, entreprise associee).

Parametres : aucun (utilise la cle de la session courante).


3.6 Validation (2 outils)

validate_siret

Verifie un numero SIRET aupres de l'API INSEE Sirene.

Parametres : { "siret": "string (14 chiffres, requis)" }

Reponse : Informations de l'etablissement (raison sociale, adresse, code NAF, etat administratif).

validate_vat

Verifie un numero de TVA intracommunautaire via VIES.

Parametres : { "vat_number": "string (format EU, requis)" }

Reponse : Validite du numero, raison sociale, adresse.


3.7 Compte (1 outil)

get_balance

Retourne le solde du compte (credits disponibles, reserves, total).

Parametres : aucun.

Reponse type :

json
{
  "available_balance": 45.60,
  "reserved_balance": 2.40,
  "total_balance": 48.00,
  "currency": "EUR"
}

3.8 Audit (1 outil)

get_audit_trail

Recupere la piste d'audit d'une entite (facture, signature, avoir).

Parametres :

ParametreTypeDescription
entity_typestringType : invoice, signature, credit_note (requis)
entity_idstringUUID de l'entite (requis)

3.9 Tenant (3 outils) -- Tenant uniquement

get_tenant_profile

Retourne le profil du tenant (nom, SIRET, TVA, statut KYB, solde).

update_tenant_profile

Met a jour le profil du tenant. Parametres : name, billing_email, technical_email, webhook_url.

get_tenant_stats

Retourne les statistiques globales du tenant (factures, signatures, avoirs, consommation).


3.10 Billing (3 outils) -- Tenant uniquement

list_billing_invoices

Liste les factures de facturation du tenant. Parametres : status, page, per_page.

get_billing_usage

Retourne la consommation du mois en cours (nombre de factures, signatures, avoirs, montant).

list_billing_transactions

Liste les transactions de credit/debit du tenant. Parametres : page, per_page.


3.11 Statistiques (2 outils) -- Tenant uniquement

get_stats_overview

Vue d'ensemble du dashboard : totaux factures/signatures/avoirs, evolution, repartition.

get_stats_monthly

Statistiques mensuelles detaillees. Parametres : year, month.


3.12 Sous-tenants (6 outils) -- Tenant uniquement

list_sub_tenants

Liste les sous-tenants du tenant. Parametres : status, page, per_page.

create_sub_tenant

Cree un sous-tenant.

Parametres :

ParametreTypeDescription
external_idstringID externe dans le systeme du tenant (requis)
namestringNom de l'entreprise (requis)
emailstringEmail de contact
siretstringSIRET
vat_numberstringNumero TVA

get_sub_tenant

Recupere un sous-tenant par ID. Parametres : { "sub_tenant_id": "string" }

update_sub_tenant

Met a jour un sous-tenant. Parametres : sub_tenant_id + champs a modifier.

delete_sub_tenant

Supprime un sous-tenant. Parametres : { "sub_tenant_id": "string" }

find_sub_tenant_by_external_id

Recherche un sous-tenant par son ID externe. Parametres : { "external_id": "string" }


3.13 Factures entrantes (5 outils) -- Tenant uniquement

list_incoming_invoices

Liste les factures recues des fournisseurs via SuperPDP.

get_incoming_invoice

Recupere le detail d'une facture entrante. Parametres : { "invoice_id": "string" }

accept_incoming_invoice

Accepte une facture entrante. Parametres : { "invoice_id": "string" }

reject_incoming_invoice

Rejette une facture entrante. Parametres : { "invoice_id": "string", "reason": "string" }

mark_incoming_invoice_paid

Marque une facture entrante comme payee. Parametres : { "invoice_id": "string", "payment_reference": "string" }


Recapitulatif des 54 outils par categorie

CategorieOutilsAuth requise
Factures4sk_* ou tk_*
Signatures6sk_* ou tk_*
Avoirs7tk_* uniquement
Fiscal12tk_* uniquement
Systeme2sk_* ou tk_*
Validation2sk_* ou tk_*
Compte1sk_* ou tk_*
Audit1sk_* ou tk_*
Tenant3tk_* uniquement
Billing3tk_* uniquement
Statistiques2tk_* uniquement
Sous-tenants6tk_* uniquement
Factures entrantes5tk_* uniquement
Total54

4. Exemples d'Integration

4.1 Integration avec Claude Desktop

Ajouter la configuration dans ~/.claude/claude_desktop_config.json :

json
{
  "mcpServers": {
    "scell-io": {
      "transport": "http",
      "url": "https://api.scell.io/mcp/",
      "headers": {
        "X-Scell-API-Key": "sk_live_votre_cle_api_ici"
      }
    }
  }
}

Apres redemarrage de Claude Desktop, les 54 outils Scell.io sont disponibles. Exemples de prompts :

  • "Cree une facture de 1500 EUR HT pour ACME SAS, SIRET 12345678900001, pour une prestation de conseil"
  • "Montre-moi le statut de conformite fiscale de mon tenant"
  • "Liste les 5 dernieres factures au statut draft"

4.2 Agent IA custom (Node.js)

javascript
const MCP_URL = 'https://api.scell.io/mcp/';
const API_KEY = 'sk_live_votre_cle_api';

// 1. Initialiser la session
const initResponse = await fetch(MCP_URL, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Scell-API-Key': API_KEY,
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'initialize',
    params: { protocolVersion: '2024-11-05' },
  }),
});

const initResult = await initResponse.json();
const sessionId = initResponse.headers.get('mcp-session-id');

// 2. Lister les outils disponibles
const toolsResponse = await fetch(MCP_URL, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Scell-API-Key': API_KEY,
    'mcp-session-id': sessionId,
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 2,
    method: 'tools/list',
    params: {},
  }),
});

const tools = await toolsResponse.json();
console.log(`${tools.result.tools.length} outils disponibles`);

// 3. Creer une facture
const invoiceResponse = await fetch(MCP_URL, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Scell-API-Key': API_KEY,
    'mcp-session-id': sessionId,
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 3,
    method: 'tools/call',
    params: {
      name: 'create_invoice',
      arguments: {
        invoice_number: 'FA-2026-042',
        issue_date: '2026-03-03',
        due_date: '2026-04-02',
        seller: {
          name: 'Ma Societe SAS',
          siret: '12345678900001',
          address: '10 rue de la Paix',
          city: 'Paris',
          postal_code: '75002',
        },
        buyer: {
          name: 'Client SARL',
          siret: '98765432100001',
          address: '5 avenue Victor Hugo',
          city: 'Lyon',
          postal_code: '69002',
        },
        lines: [
          { description: 'Developpement web', quantity: 10, unit_price: 800, vat_rate: 20 },
          { description: 'Hebergement annuel', quantity: 1, unit_price: 500, vat_rate: 20 },
        ],
      },
    },
  }),
});

const invoice = await invoiceResponse.json();
console.log('Facture creee:', invoice.result);

4.3 Agent IA custom (Python)

python
import requests
import json

MCP_URL = 'https://api.scell.io/mcp/'
API_KEY = 'sk_live_votre_cle_api'
HEADERS = {
    'Content-Type': 'application/json',
    'X-Scell-API-Key': API_KEY,
}

# 1. Initialiser
resp = requests.post(MCP_URL, headers=HEADERS, json={
    'jsonrpc': '2.0', 'id': 1,
    'method': 'initialize',
    'params': {'protocolVersion': '2024-11-05'},
})
session_id = resp.headers.get('mcp-session-id')
HEADERS['mcp-session-id'] = session_id

# 2. Verifier la conformite fiscale
resp = requests.post(MCP_URL, headers=HEADERS, json={
    'jsonrpc': '2.0', 'id': 2,
    'method': 'tools/call',
    'params': {
        'name': 'get_fiscal_compliance',
        'arguments': {},
    },
})
compliance = resp.json()
print(json.dumps(compliance['result'], indent=2))

# 3. Exporter le FEC
resp = requests.post(MCP_URL, headers=HEADERS, json={
    'jsonrpc': '2.0', 'id': 3,
    'method': 'tools/call',
    'params': {
        'name': 'export_fec',
        'arguments': {'year': 2025},
    },
})
fec = resp.json()
print('FEC exporte:', fec['result'])

4.4 Scenario complet : "Cree une facture pour client X"

Voici le flux complet lorsqu'un utilisateur demande a un LLM de creer une facture :

Utilisateur: "Cree une facture de 2000 EUR pour ACME"

LLM -> Reflexion:
  1. Je dois chercher les infos du client ACME
  2. Je dois connaitre les infos du vendeur (profil tenant)
  3. Je cree la facture

LLM -> tools/call: get_tenant_profile
  <- { name: "Ma Societe", siret: "123...", address: {...} }

LLM -> tools/call: validate_siret { siret: "987..." }
  <- { company_name: "ACME SAS", address: {...} }

LLM -> tools/call: create_invoice {
  invoice_number: "FA-2026-043",
  seller: { ... donnees du profil tenant ... },
  buyer: { ... donnees ACME ... },
  lines: [{ description: "Prestation", quantity: 1, unit_price: 2000 }]
}
  <- { id: "...", status: "draft", total_ttc: 2400.0, download_url: "..." }

LLM -> Utilisateur: "Facture FA-2026-043 creee pour ACME SAS.
  Montant: 2 000 EUR HT / 2 400 EUR TTC.
  Telechargement: [lien]"

5. Architecture Technique

5.1 Diagramme de composants

mermaid
graph TB
    Client["Client MCP<br/>(Claude, Agent IA)"]

    subgraph "Scell.io Backend"
        MC["McpController<br/>POST /mcp/"]
        SM["SessionManager<br/>(Redis)"]
        TR["HttpStreamableTransport<br/>(JSON-RPC 2.0)"]
        REG["ToolRegistry<br/>(54 outils)"]

        subgraph "Outils"
            BT["BaseTool<br/>(16 outils user)"]
            TAT["TenantAwareTool<br/>(38 outils tenant)"]
        end

        SRV["Services metier<br/>(Fiscal, Billing, etc.)"]
        DB[(PostgreSQL)]
        RD[(Redis)]
    end

    Client -->|"X-Scell-API-Key"| MC
    MC --> SM
    MC --> TR
    TR --> REG
    REG --> BT
    REG --> TAT
    BT --> SRV
    TAT --> SRV
    SRV --> DB
    SM --> RD

5.2 Transport HTTP Streamable

Le serveur utilise le transport HTTP Streamable du protocole MCP :

  • Requetes : POST /mcp/ avec body JSON-RPC 2.0
  • Sessions : Identifiees par le header mcp-session-id (format mcp_ + 32 caracteres aleatoires)
  • SSE : Endpoint optionnel GET /mcp/stream pour notifications en temps reel
  • Keepalive : Ping toutes les 30 secondes sur la connexion SSE

Methodes JSON-RPC supportees :

MethodeDescription
initializeInitialise la session, retourne les capacites serveur
tools/listListe les outils disponibles avec leurs schemas
tools/callExecute un outil avec des arguments
pingVerification de connectivite

5.3 Gestion des sessions

Les sessions MCP sont stockees en base de donnees (table mcp_sessions) avec cache Redis :

McpSession {
  session_id: "mcp_aB3cD4eF..."     // Identifiant unique
  api_key_id: UUID | null            // Si cle utilisateur (sk_*)
  tenant_id: UUID | null             // Si cle tenant (tk_*)
  tools_accessed: ["create_invoice", ...]  // Audit des outils utilises
  expires_at: "2026-03-03T15:30:00"  // Expiration (TTL configurable)
  metadata: { client_info: "...", auth_type: "tenant" }
}

Cycle de vie :

  1. Creation : lors du premier initialize (auto-detection sk_* vs tk_*)
  2. Validation : a chaque requete, le session_id est verifie et l'activite prolongee
  3. Expiration : apres le TTL (defaut : 1 heure sans activite)
  4. Nettoyage : les sessions expirees sont purgees automatiquement

5.4 Tenant-awareness

Le serveur detecte automatiquement le type de cle API :

  • Cle sk_* (utilisateur) : acces aux 16 outils de base (factures, signatures, validation, systeme, compte, audit)
  • Cle tk_* (tenant) : acces aux 54 outils (incluant fiscal, billing, sub-tenants, factures entrantes)

Les outils tenant heritent de TenantAwareTool qui :

  1. Verifie que la session est de type tenant
  2. Charge le tenant depuis la base
  3. Applique l'isolation des donnees (scoping automatique par tenant_id)
php
// Exemple : un outil tenant verifie automatiquement le contexte
abstract class TenantAwareTool extends BaseTool
{
    public function execute(array $arguments, McpSession $session): array
    {
        $tenant = $this->requireTenant($session);
        if (!$tenant) {
            return $this->error('Cle tenant (tk_*) requise.');
        }
        return $this->executeTenant($arguments, $session, $tenant);
    }
}

5.5 Gestion des erreurs

Les erreurs suivent le standard JSON-RPC 2.0 :

CodeSignification
-32700Erreur de parsing JSON
-32601Methode inconnue
-32001Cle API manquante ou invalide
-32002Session invalide ou expiree
-32603Erreur interne du serveur

Les outils retournent un champ isError: true en cas d'erreur metier :

json
{
  "content": [{ "type": "text", "text": "{\"error\": \"Solde insuffisant\"}" }],
  "isError": true
}

5.6 Rate limiting

Le serveur applique un rate limit de 60 requetes par minute par cle API (configurable via MCP_RATE_LIMIT). En cas de depassement, le serveur retourne une erreur JSON-RPC avec le code -32001.

5.7 Securite

  • Toutes les communications transitent en HTTPS
  • Les cles API sont hashees en base (seul le prefixe sk_live_, sk_test_ est stocke en clair)
  • Les sessions sont liees a la cle API d'origine
  • Chaque appel d'outil est trace dans tools_accessed de la session
  • Les outils fiscaux (fiscal:admin) necessitent des scopes explicites

Documentation Scell.io