Like humans, your AI agents are limited by the quality of their tools. We're building a toolbox that lets them do their best work.
$ bash <(curl https://include.tools/install/<claude-code|claude|cursor|windsurf|pi>) ✓ toolbox installed $ toolbox install github.com/include-tools/google 🔐 Opening browser to authorize Google services… ✓ Connected as [email protected] (personal) $ // how it'll look when you're in. Get notified of our public launch →
== tool.name tool.count -- hacker_news 6 gmail 12 sharks_with_laser_beams 3 // use in presence of world leaders ==
toolbox install github.com/include-tools/google, follow the prompts, and you will have working Google integration — Gmail, Calendar, Drive, Contacts. Authorized,--- cell 1 > // alex emailed about a thursday demo — read details > const inbound = await gmail.read({ google_account: "personal", id: "..." }) < { from: "[email protected]", subject: "thursday demo", ... } --- cell 2 > // get work-calendar busy blocks over the next 3 days > const start = new Date(), end = new Date(Date.now() + 3 * 86400000) > await calendar.freebusy({ google_account: "work", timeMin: start, timeMax: end, calendars: ["[email protected]"] }) ! TypeError: timeMin must be an RFC3339 string. Got: object (Date). --- cell 3 > // right — calendar.freebusy wants RFC3339 strings, not Date objects > await calendar.freebusy({ google_account: "work", timeMin: start.toISOString(), timeMax: end.toISOString(), calendars: ["[email protected]"], }) < { results: [{ calendarId: "[email protected]", busy: [...] }] } --- cell 4 > // compute two free hour-long gaps from $last's busy blocks > const slots = findFreeHours($last.results[0].busy, start, end).slice(0, 2) > await gmail.send({ google_account: "work", to: inbound.from, subject: `Re: ${inbound.subject}`, body: `I have ${slots[0]} or ${slots[1]} open — which works?`, }) < { sent: true, messageId: "..." }
You don't need to launch multiple MCP servers or wire up multiple tools to reach multiple accounts. As soon as you've authorized a tool package with more than one account, an extra <provider>_account field is automatically added to the tool signatures — so agents can address them by name.
import { gmail } from "@toolbox/sdk"; const inbound = await gmail.read({ google_account: "personal", id: "..." }); await gmail.send({ google_account: "work", to: inbound.from, subject: `Re: ${inbound.subject}`, body: "Got it. Will do.", }); // No keys. No tokens. You authorized once with `toolbox auth google`.
Each tool exposes a typed TypeScript manifest. Multi-account is part of the call signature, not a side channel. Network and data-access rules are declared per-tool in the manifest and enforced at the runtime layer — not by hoping the agent behaves.
Packages are distributed on npm under @include-tools/* and installable via toolbox install github.com/include-tools/<name>. Lockfile-pinned, reproducible, check-into-git.
github.com/include-tools/google-workspacetoolset.json — like package.json, but for agents. (and better)Every project has a package.json that declares its dependencies, pins versions, and makes the build reproducible. Your agent needs the same.
A toolset.json pins which packages your agent can use and at which exact version, and lists the specific tools it exposes — with a companion lockfile that verifies every install. Check it into your repo. Share it with your team. Reproduce environments. Scope per project. Updates only happen when you run the package manager — never silently behind your back.
The toolset.json also configures how your tools work.
Want to limit a tool to just posting on two slack channels, easy. Ask for approval when sending external emails, but free range internally? easy.
{
"name": "my-app",
"dependencies": {
"react": "^18.2.0",
"lodash": "^4.17.0",
"zod": "^3.22.0"
}
}{
"packages": {
"github.com/include-tools/google-workspace": "1.2.0"
},
"tools": [
{ "tool": "github.com/include-tools/google-workspace/gmail" },
{ "tool": "github.com/include-tools/google-workspace/gcal" }
]
}The bytes you installed are the bytes that run — every time. Each tool package ships with a manifest that lists every tool's SHA-256 hash; Toolbox re-hashes the cached bytes on every tool load — not just at install — and refuses to run on mismatch. (Cryptographic signing is planned. Today's guarantee is reproducibility of bytes, not identity of authors.)
Your agent touches real data — real email, real calendar, real accounts. We designed the trust layer before the catalog, so every tool you install arrives with the same boundaries in place.
None of these are magic. Each one does one specific thing, and together they mean a compromised prompt can't quietly drain your inbox.
Authorize multiple accounts of the same service with toolbox auth. Your agent addresses them by name in code — gmail.send({ google_account: "work", … }) — so work and personal never get mixed up at the call site.
Every tool package ships with a manifest of SHA-256 hashes. Those hashes land in your *.toolset.lock on install, and Toolbox re-hashes the cached bytes on every tool load — not just install, every invocation — refusing to run on mismatch. The code you reviewed once is the code that runs every time, byte-for-byte.
Your credentials live in an age-encrypted store the Toolbox daemon opens once per daemon start. Unlock with a password or a single OS-level gesture; lock it again when you step away. While locked, no tool can reach your accounts — not your own, and not a compromised one. While unlocked, the daemon hands credentials to the transport layer per-tool — your agent and the notebook never see the raw secret.
Tools run in an isolated JavaScript runtime with no filesystem, process, or OS access by default. Credentials are attached at the network layer from an encrypted store outside the runtime — your tool code (and your agent) never sees the raw secret.
Every tool declares the hosts it's allowed to reach. Calls outside that allowlist are blocked at the runtime layer. This is the boundary that makes isolation meaningful — a rogue fetch to an attacker-controlled domain simply doesn't go through.
Every tool manifest declares whether it exposes your agent to untrusted input, private data, or exfiltration capacity. You see these flags before you install — so you know exactly what kind of trust you're extending, and to which tool.
include.tools plugs into the agent runtime you already use. One install command — no framework rewrite, no config file archaeology.
Works with OpenClaw via Pi-extension, direct integration coming. Works with any harness that can make MCP tool calls.
Toolbox is a local server that runs on your computer. Your API keys, OAuth credentials, your logs, and your sessions all stored locally. We don't host execution. We don't proxy your tool calls remotely. There is no middleman.
Here's the path every agent super-tool call takes.
When your agent harness launches, a toolbox session process starts (MCP / Pi-extension over stdio). The toolbox session provides the super-tool to your agent harness. When your agent makes a tool call, a persistent sandboxed TypeScript notebook executes it as a cell. Any tool calls invoked in that cell run in a separate sandbox. This ensures agents and tools can only communicate via serialized JS arguments, and lets us adjust the network and filesystem surface for each sandbox separately.
A separate toolbox server process holds your encrypted secrets, unlocking on start with a passphrase and surviving toolbox session process restarts. It attaches credentials at the transport layer, so neither the notebook nor any tool sandbox ever sees a credential. Every outbound tool request is checked against a per-tool deny-by-default host allowlist declared in the tool's manifest.