Documentazione

Documentazione TeamOnly

La CLI, l’SDK che usa la tua app e il file della skill che insegna alla tua AI cosa scrivere. Tecnica, e breve. Gli agenti di programmazione possono leggere questa pagina in Markdown su /docs.md.

Guida rapida

Ti serve Node.js 20 o successivo. Non hai ancora un piano? La prima volta che accedi puoi iniziare una prova gratuita di 14 giorni senza carta, oppure abbonarti. Puoi anche abbonarti qui. In una nuova cartella, o in un progetto che hai già:

  1. npx teamonly init aggiunge un’app di partenza e le istruzioni che il tuo strumento AI segue.
  2. npx teamonly login una volta per computer. Scrivi la tua email aziendale e il codice di 6 cifre che ti mandiamo per email. Se la tua azienda non ha ancora un piano, ti offre la prova gratuita di 14 giorni, che parte subito, oppure un piano con una pagina di pagamento. Premi Invio invece di scrivere l’email per accedere dal browser.
  3. npx teamonly deploy mette l’app online su https://<app>.<company>.teamonly.app.

Ecco come appare:

Terminal~/expenses
npx teamonly initAdded the TeamOnly skill, Cursor rules and SDKCrea uno strumento di approvazione spese(la tua AI crea l’app)npx teamonly loginSigned in as dana@acme.comnpx teamonly deployLive at https://expenses.acme.teamonly.appOnly @acme.com accounts can sign in

La prima pubblicazione crea l’app, il suo database e la sua archiviazione file. Le pubblicazioni successive aggiornano la stessa app allo stesso indirizzo.

Comandi della CLI

npx teamonly login
Accedi a TeamOnly da questo computer, una volta per computer. Scrivi la tua email aziendale e il codice di 6 cifre che ti mandiamo, oppure premi Invio per accedere dal browser. --email e --code fanno lo stesso senza domande, per strumenti di AI e script.
npx teamonly trial --company "Acme"
Avvia la prova gratuita di 14 giorni per la tua azienda, senza carta. Usalo dopo login quando la tua azienda non ha ancora un piano. Una prova per ogni dominio email aziendale.
npx teamonly subscribe --plan builder
Abbonati, o riattiva le app dopo la prova. Scegli builder, team o business. Apre una pagina di pagamento e ti fa accedere qui appena hai pagato.
npx teamonly init
Prepara questa cartella: un’app di partenza, oppure le istruzioni di TeamOnly per il tuo strumento AI (skill di Claude Code, regole di Cursor, AGENTS.md) e l’SDK in un progetto esistente.
npx teamonly deploy
Compila l’app e la mette online. Alla prima pubblicazione crea il database e l’archiviazione file. Mostra l’indirizzo dell’app.
npx teamonly access
Mostra chi può aprire l’app. Aggiungi only, add o remove con degli indirizzi email per usare una lista, o everyone per tutta l’azienda.
npx teamonly roles
Assegna alle persone dei ruoli dentro l’app, come approvatore o amministrazione. roles add approver dana@acme.com ne assegna uno, roles remove lo toglie, e roles da solo mostra chi ha quale ruolo. Solo indirizzi aziendali.
npx teamonly secrets set NAME
Salva un segreto per questa app. Il valore ti viene chiesto a parte, così non finisce mai nella cronologia della shell.
npx teamonly logs
Segui in tempo reale le richieste dell’app online, l’output di console.log e gli errori, mentre succedono. Premi Ctrl+C per fermarti.
npx teamonly whoami
Mostra con chi hai fatto l’accesso, il tuo piano e le tue app.
npx teamonly delete
Elimina l’app online con il suo database e i suoi file. Prima ti chiede di scrivere il nome dell’app.
npx teamonly logout
Esci da TeamOnly su questo computer.

SDK

La tua API è un’app Hono. Il middleware dell’SDK dà a ogni richiesta un contesto in c.var.ctx:

ctx.user
La persona che ha fatto l’accesso: email, name, isOwner per chi ha pubblicato l’app per primo, e roles, i suoi ruoli in questa app. Verificata da TeamOnly prima che giri il tuo codice. Non leggere mai l’identità dagli header da solo.
ctx.db
Il database SQL di questa app (SQLite, su Cloudflare D1). Creato alla prima pubblicazione.
ctx.files
L’archiviazione file di questa app: put, get, list, delete.
ctx.secrets
Valori impostati con npx teamonly secrets set. Si leggono con ctx.secrets.get(name).
ctx.email
Invia email ai colleghi: send({ to, subject, text, html?, replyTo? }). Vedi Email.
ctx.schedule
Il nome del job quando TeamOnly esegue un job pianificato, altrimenti undefined. Vedi Job pianificati.

Nel browser, useUser() da teamonly/react restituisce { email, name, roles }.

api/index.tsesempio
import { Hono } from 'hono'
import { teamonly, type TeamOnly } from 'teamonly/server'

const app = new Hono<TeamOnly>()
app.use('*', teamonly())

// Who is signed in. Verified before your code runs.
app.get('/api/me', (c) => {
  return c.json(c.var.ctx.user) // { email: 'dana@acme.com', name: 'Dana Okafor', isOwner: false, roles: ['approver'] }
})

// Save to this app's own database.
app.post('/api/expenses', async (c) => {
  const { db, user } = c.var.ctx
  const { amount, reason } = await c.req.json()
  await db
    .prepare('INSERT INTO expenses (amount, reason, submitted_by) VALUES (?, ?, ?)')
    .bind(amount, reason, user.email)
    .run()
  return c.json({ ok: true })
})

// Store an uploaded receipt in this app's file storage.
app.put('/api/receipts/:id', async (c) => {
  await c.var.ctx.files.put(`receipts/${c.req.param('id')}`, c.req.raw.body)
  return c.json({ ok: true })
})

// Read a secret set with: npx teamonly secrets set QUICKBOOKS_KEY
app.get('/api/sync', async (c) => {
  const key = c.var.ctx.secrets.get('QUICKBOOKS_KEY')
  // ...
})

export default app

Email

Un’app può inviare email alle persone della tua azienda con ctx.email.send(), per esempio per avvisare un approvatore che una spesa è in attesa.

api/index.tsesempio
// Tell the approver an expense is waiting.
await c.var.ctx.email.send({
  to: 'priya@acme.com',   // one address or a list, up to 50
  subject: 'An expense is waiting for you',
  text: 'Dana sent a $42 expense. Review it: https://expenses.acme.teamonly.app',
})
  • Solo a indirizzi sui domini email della tua azienda, cioè le stesse persone che possono accedere. Qualsiasi altro indirizzo viene rifiutato e non parte niente.
  • Inviate da notify@teamonly.app a nome dell’app nella tua azienda, come “Expenses at Acme”. Le risposte vanno al responsabile dell’app, a meno che tu non imposti replyTo (anche questo un indirizzo aziendale).
  • Ogni email contiene una riga che dice quale app l’ha inviata.
  • Limiti per app: 100 destinatari all’ora e 500 al giorno, e fino a 50 destinatari per email.
  • La pagina dell’app nella dashboard mostra quante email ha inviato negli ultimi 30 giorni.
  • In locale, con npm run dev, le email vengono stampate nel terminale, non inviate.
  • Le email a persone fuori dalla tua azienda non sono supportate.

Job pianificati

Per riepiloghi giornalieri, promemoria e report di fine mese, elenca i job in teamonly.json. TeamOnly chiama ogni route a quegli orari.

teamonly.jsonesempio
{
  "name": "expenses",
  "timezone": "America/New_York",
  "schedules": [
    { "name": "daily-digest", "cron": "0 9 * * 1-5", "path": "/api/cron/daily-digest" }
  ]
}
api/index.tsesempio
import { scheduled } from 'teamonly/server'

// Runs at 9am New York time, Monday to Friday.
app.post('/api/cron/daily-digest', scheduled(async (c) => {
  const { db, email } = c.var.ctx
  // ...find what is waiting, then email each approver
  return c.json({ ok: true })
}))
  • cron ha cinque campi: minuto, ora, giorno del mese, mese, giorno della settimana. I job partono ogni 5 minuti esatti, quindi i minuti devono essere multipli di 5.
  • timezone è facoltativo e di default è UTC.
  • Avvolgi la route in scheduled(...) da teamonly/server. Chi apre l’URL riceve un 404.
  • La pagina dell’app nella dashboard mostra l’ultima esecuzione di ogni job e se è andata a buon fine.
  • I job vengono sospesi quando una prova gratuita è finita.

Ruoli

Ruoli come approvatore, amministrazione o admin restano in TeamOnly, non nel tuo codice. Il responsabile dell’app o un admin li assegna dalla pagina dell’app nella dashboard, o con npx teamonly roles. Solo indirizzi aziendali.

Terminal~/expenses
npx teamonly roles add approver dana@acme.comGave dana@acme.com the role approverapprover: dana@acme.com
api/index.tsesempio
// Only approvers can approve.
app.post('/api/expenses/:id/approve', async (c) => {
  const { user } = c.var.ctx
  if (!user.roles.includes('approver')) return c.json({ error: 'Approvers only' }, 403)
  // ...
})

L’app li legge come ctx.user.roles e decide cosa può fare ogni ruolo. Anche così, non c’è codice di login da scrivere.

Il file della skill

init aggiunge un file della skill per Claude Code e lo stesso contenuto come file di regole per Cursor. Il tuo strumento AI lo legge prima di scrivere codice. Gli insegna:

  • L’unica struttura di app supportata (qui sotto), e a restare dentro quella.
  • A usare ctx.user per l’identità e a non scrivere mai schermate proprie di login, registrazione o password.
  • A usare ctx.db e ctx.files invece di aggiungere un servizio di database, Express, Supabase o Firebase.
  • A tenere le chiavi API in ctx.secrets, mai nel codice.
  • A inviare email con ctx.email, a eseguire il lavoro a orari fissi come job pianificati, e a controllare ctx.user.roles sul server.
  • Come eseguire deploy e correggere ciò che segnala.

Lo scopo è che la prima pubblicazione funzioni. Se la tua AI continua a ricorrere a qualcosa che non usiamo, diccelo; è un bug del file della skill.

Server MCP

Il pacchetto teamonly avvia anche un server MCP, per gli strumenti di IA che preferiscono i tool ai comandi da terminale, come Claude Desktop o l’agente di Cursor senza terminale. Gira sul tuo computer, perché la pubblicazione legge i file del tuo progetto. Aggiungilo a Claude Code con:

Terminal~/expenses
claude mcp add teamonly -- npx -y teamonly mcp
  • Cursor, Claude Desktop e Windsurf: aggiungi { "mcpServers": { "teamonly": { "command": "npx", "args": ["-y", "teamonly", "mcp"] } } } alla loro configurazione MCP.
  • VS Code: in .vscode/mcp.json la chiave è servers, con "type": "stdio".
  • I suoi 12 tool: get_app_rules, init, deploy, status, logs, access, roles, set_secret, sign_in, start_trial, subscribe, delete_app.
  • Presente nel registro ufficiale MCP Registry come dev.teamonly/teamonly.

Il file della skill e le regole restano il modo principale con cui la tua IA impara lo stack, e la CLI funziona esattamente come prima. La configurazione per ogni strumento, con un pulsante per installarlo in Cursor con un clic: server MCP di TeamOnly.

Struttura dell’app supportata

  • Front end: React, compilato con Vite, servito come file statici.
  • API: un’app Hono in TypeScript o JavaScript, sotto /api, sullo stesso indirizzo.
  • Runtime: Cloudflare Workers. API web standard; quasi tutti i moduli integrati di Node tramite compatibilità, ma niente moduli nativi né processi di lunga durata.
  • Non supportati: Python, Ruby, PHP, container Docker, WebSocket e aggiornamenti in tempo reale, worker in background, email a persone fuori dalla tua azienda, collegamento a server sulla rete privata della tua azienda, domini personalizzati, app pubbliche.

Limiti

I limiti di oggi:

  • Builder: 1 creatore, 3 app. Team: creatori e app illimitati.
  • Database e archiviazione file di ogni app seguono i limiti di Cloudflare D1 e R2.
  • Le richieste girano entro i limiti di Cloudflare Workers per tempo di CPU e memoria.

Di più su come si incastra tutto: Come funziona e Sicurezza.

Accesso anticipato

Metti online il tuo primo strumento questa settimana.

TeamOnly è in accesso anticipato e tutti i piani sono già disponibili. Provalo gratis per 14 giorni senza carta, oppure abbonati. In entrambi i casi la tua azienda è pronta subito, e bastano tre comandi per mettere online la tua prima app.

Prova gratis per 14 giorniOppure abbonati subito

Nessuna carta per la prova. Poi da $19 al mese, disdici quando vuoi.

Non sei pronto? Ricevi aggiornamenti

Usa la tua email aziendale. Scriviamo di rado, e solo quando c’è una novità che vale la pena.

Le domande vanno a hello@teamonly.dev, e risponde una persona.