Read, write, search, move. Path sandbox + size caps.
@tuttiai/filesystem 13 official voices ship today — 107 tools across filesystem, browser, code execution, GitHub, Postgres, Stripe, messaging, and more.
Need something else? Bridge any MCP server with the @tuttiai/mcp voice, or build and publish your own to npm.
Every voice is semver-versioned and declares its own permission scopes — the runtime enforces them.
Read, write, search, move. Path sandbox + size caps.
@tuttiai/filesystem Issues, PRs, code search, repos.
@tuttiai/github Headless browser — navigate, click, type, screenshot, eval.
@tuttiai/playwright Search, fetch URL, fetch sitemap. Citation metadata.
@tuttiai/web Run TypeScript, Python, Bash in an isolate. File I/O.
@tuttiai/sandbox Ingest, chunk, embed, retrieve. Postgres pgvector or local.
@tuttiai/rag Messages, channels, members, reactions, DMs. HITL on writes.
@tuttiai/discord Channels, threads, DMs, reactions. HITL on writes.
@tuttiai/slack Tweets, threads, mentions, timeline. HITL on writes.
@tuttiai/twitter Query, execute, schema introspection. Read-only by default.
@tuttiai/postgres Customers, payments, subs, invoices, balance. HITL on writes.
@tuttiai/stripe OpenAI Realtime API — voice in / voice out. HITL on every tool call.
@tuttiai/realtime Wrap any MCP server as a typed Tutti voice. Tools auto-discovered.
@tuttiai/mcp No voices match — try another filter.
Tutti is open source and the roster grows in two ways. Wrap any
MCP server
with @tuttiai/mcp and its tools become a typed Tutti voice instantly — no PR required.
For everything else, voices are plain TypeScript: implement the Voice interface,
publish to npm, and open an issue if you'd like it listed here. We review and welcome community voices.
Voices are plain TypeScript classes. Declare tool schemas with Zod, declare permissions, ship to npm. The runtime handles invocation, retries, redaction, and tracing.
import type { Voice, Tool } from '@tuttiai/types'
import { z } from 'zod'
const get_forecast: Tool = {
name: 'get_forecast',
description: 'Forecast for a city.',
parameters: z.object({ city: z.string() }),
execute: async ({ city }) => {
const r = await fetch(`https://api.weather.com/${city}`)
return { content: await r.text() }
},
}
export const WeatherVoice: Voice = {
name: 'weather',
required_permissions: ['network'],
tools: [get_forecast],
} One install. Your first agent running in 60 seconds. No signup. No telemetry.