> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.userbot.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.userbot.ai/_mcp/server.

# Funzioni server e dati

Quasi tutte le Mini App lavorano solo nel browser: ricevono dei valori, calcolano,
mostrano il risultato. Le **funzioni server** servono quando non basta: la Mini
App deve leggere dati da un servizio web, ricordare qualcosa fra un uso e
l'altro (un elenco di richieste, le bozze di un modulo) o farsi chiamare da un
agente senza aprire l'interfaccia.

Non serve scriverle a mano. Chiedilo in chat (*«salva ogni richiesta in un
elenco che posso rivedere»*, *«prendi il cambio del giorno da questo
servizio»*) e l'AI aggiunge la funzione. Nel riquadro delle azioni compare
«Aggiungo funzione server» seguito dal nome. Questa pagina serve a capire cosa
ha fatto e quali sono i confini.

## Dove stanno

Ogni funzione server è un file nella cartella `server/` del progetto, per esempio
`server/salvaRichiesta.ts`, ed è dichiarata in `miniapp.config.json`:

```json
{
  "serverFunctions": [{ "name": "salvaRichiesta", "file": "server/salvaRichiesta.ts" }],
  "allowedFetchDomains": ["api.esempio.it"],
  "toolEntrypoint": null
}
```

La funzione riceve i dati che le passa l'interfaccia e un oggetto `ctx` con
quello che può usare:

```ts
export default async (input, ctx) => {
  const elenco = (await ctx.kv.get("richieste")) ?? [];
  elenco.push({ ...input, quando: ctx.now() });
  await ctx.kv.set("richieste", elenco);
  return { totale: elenco.length };
};
```

L'interfaccia la chiama con `callServer("salvaRichiesta", dati)`, già pronta in
`src/lib/userbot.ts`. Le funzioni girano sui server di Userbot, in un ambiente
isolato: non vedono i file del computer, le variabili d'ambiente né le
credenziali dell'area di lavoro.

| In `ctx`                                                   | Cosa fa                                                |
| ---------------------------------------------------------- | ------------------------------------------------------ |
| `ctx.kv.get`, `ctx.kv.set`, `ctx.kv.delete`, `ctx.kv.list` | Leggono e scrivono nell'archivio dati della Mini App   |
| `ctx.fetch`                                                | Chiama un servizio web, solo verso i domini consentiti |
| `ctx.log`                                                  | Scrive un messaggio di diagnostica                     |
| `ctx.now`                                                  | Restituisce l'ora attuale                              |

## L'archivio dati

Ogni Mini App ha un archivio chiave-valore, con un limite di spazio. È unico per
la Mini App, non per persona: tutti quelli che la usano leggono e scrivono gli
stessi dati. Se ti servono dati separati per ciascuno, va detto in chat quando
descrivi la Mini App.

La bozza e la versione pubblicata hanno archivi separati, e ogni pubblicazione
parte con un archivio vuoto: i dati che provi nel costruttore non finiscono fra
quelli veri, ma nemmeno quelli raccolti con una versione passano alla
successiva. → [Pubblicare una Mini App](/pubblicare-miniapp)

## Chiamare un servizio web

`ctx.fetch` raggiunge solo i domini elencati in `allowedFetchDomains`. Un dominio
vale anche per i suoi sottodomini; `*.esempio.it` vale per tutti i sottodomini
ma non per `esempio.it`. Con l'elenco vuoto la Mini App non esce su internet.

Non c'è un posto dove conservare chiavi o password per questi servizi, e una
chiave scritta in chiaro nel codice blocca la pubblicazione. In pratica si
possono chiamare i servizi che rispondono senza autenticazione.

## Farla usare a un agente senza aprirla

Di solito, quando un agente usa una Mini App, l'interfaccia si apre in chat e
aspetta che una persona confermi. Se in `miniapp.config.json` il campo
`toolEntrypoint` contiene il nome di una funzione server, l'agente esegue quella
funzione direttamente, sulla versione pubblicata, e prosegue la risposta senza
fermarsi. → [Come l'AI usa una Mini App](/miniapp-come-tool)

Va bene per operazioni che non hanno bisogno di un controllo umano, come
registrare un dato o leggerne uno. Se il risultato va controllato prima di
usarlo, lascia `toolEntrypoint` vuoto.

## I limiti

| Cosa                                                 | Limite                          |
| ---------------------------------------------------- | ------------------------------- |
| Durata di una chiamata                               | 8 secondi                       |
| Memoria                                              | 64 MB                           |
| Dimensione del risultato                             | 64 KB                           |
| Operazioni su archivio e servizi web in una chiamata | 20                              |
| Chiamate per persona                                 | 30 al minuto, per ogni Mini App |
| Chiavi nell'archivio                                 | 200                             |
| Dimensione di un valore                              | 32 KB                           |
| Spazio totale dell'archivio                          | 256 KB                          |
| Lunghezza di una chiave                              | 80 caratteri                    |

## I messaggi di errore

Gli errori delle funzioni server, mentre provi la Mini App, compaiono nel pannello
**Problemi** dell'anteprima, da cui puoi chiedere **Correggi con l'AI**.

| Messaggio                                                                               | Cosa significa                                                             |
| --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| «Nessun dominio è consentito: aggiungilo in miniapp.config.json (allowedFetchDomains).» | La funzione ha provato a chiamare internet, ma l'elenco dei domini è vuoto |
| «"dominio" non è in allowedFetchDomains.»                                               | Il dominio chiamato non è fra quelli consentiti                            |
| «Troppe chiavi KV (massimo 200).» oppure «Storage KV pieno (massimo 256000 byte).»      | L'archivio ha raggiunto uno dei suoi limiti: vanno cancellati dati vecchi  |
| «Troppe chiamate alle server function. Riprova tra poco.»                               | Superate le 30 chiamate al minuto                                          |
| «Runtime delle server function saturo. Riprova tra poco.»                               | Il servizio che esegue le funzioni è occupato in quel momento              |