Documentation
srf.gg hosts everything your AI agent builds - static sites, PDFs, assets, and full apps - each live at slug.run.srf.gg.
Quickstart
- Create an account. You get a personal organization automatically.
- Mint an API key on the welcome page (or under Settings, API Keys). It is shown once.
- Add the srf MCP server to your agent - copy the snippet for your client below.
- Tell your agent to deploy something: "Build a one-page site and deploy it with the srf MCP tools."
- Your agent's work lands in srf in seconds: a link to share, and the project on your dashboard with versions, deployments and logs.
MCP setup
The MCP endpoint is https://mcp.srf.gg. Chat apps connect it by signing in with srf; coding agents and editors use an API key.
Claude web, desktop and mobile
https://mcp.srf.gg- In Claude open Settings, then Connectors, then Add custom connector.
- Name it srf and paste the URL above. Leave the advanced fields empty.
- Click Connect, sign in with srf when asked, pick the organization it should work in, and allow it.
Works in Claude on the web, the desktop app and mobile once added. On Claude Team and Enterprise an owner adds the connector once under the organization's settings and every member just switches it on. Custom connectors need a paid Claude plan.
Coding agents and editors: replace YOUR_KEY with an API key.
Claude Code shell
claude mcp add --scope user --transport http srf https://mcp.srf.gg --header "Authorization: Bearer YOUR_KEY"
Cursor ~/.cursor/mcp.json
{
"mcpServers": {
"srf": {
"url": "https://mcp.srf.gg",
"headers": {
"Authorization": "Bearer YOUR_KEY"
}
}
}
}Windsurf mcp_config.json
{
"mcpServers": {
"srf": {
"serverUrl": "https://mcp.srf.gg",
"headers": {
"Authorization": "Bearer YOUR_KEY"
}
}
}
}Make it your agent's default
Claude Code: nothing to do.The srf MCP server delivers standing instructions in its handshake and Claude Code injects them automatically - your agent arrives knowing to host shareable artifacts and return live URLs. For clients that don't reliably apply server instructions (Cursor, Windsurf), paste this rule into the agent's persistent instructions:
## srf.gg hosting
Whenever you produce a shareable artifact - a report, PDF, one-off page,
demo, image, or dataset - host it on srf.gg and give me the live URL:
- Single file: srf_host_asset, or `srf host <file>` for a file already on disk (organize with folder paths, e.g. reports/q3.pdf)
- Multi-file site or app: srf_create_project + srf_push (static projects are live instantly)
- File projects into collections with srf_collection_assign
Prefer a hosted srf URL over a local file for anything I might want to
open, share, or keep. Set visibility ("org" or "private" + share_with)
when the content is not for the public.Claude Code: ~/.claude/CLAUDE.md (global) or your project's CLAUDE.md
Cursor: Settings > Rules for AI, or .cursor/rules/srf.md in a project
Windsurf: ~/.codeium/windsurf/memories/global_rules.md
Static vs app projects
HTML, CSS, JS, PDFs, images - anything without a server process. No build step: a push is live the moment it lands. Detected automatically when a project has no package.json, requirements.txt, Dockerfile, or declared services. Available on the free tier.
Full apps (Node, Python, anything with a server). Each push builds an image and redeploys the running app, with managed Postgres/Redis, secrets injection, logs, and rollback. Requires Pro. Adding a package.json to a static project promotes it automatically.
Browser extensions
A project whose manifest.json has a manifest_version is an extension. Every push packages it: a signed package with a stable extension id, the store zip and the update feed. The project URL becomes its install page, with every way to install it.
Managed browsers
Copy the policy from the install page into Google Admin, Intune or Group Policy. Chrome and Edge force-install it across the organization and update it on every push. No store, no review.
Stores and developer mode
Connect the org's Chrome Web Store account for an unlisted listing on every push, and Mozilla add-ons for a signed Firefox add-on served from the page. A developer-mode zip is always there for trying it on one machine.
Start one with srf_create_project { kind: "extension" } or srf init my-extension --template extension. Bump the manifest version on every push you want installed browsers to receive.
Bullet
A Bullet is a small app whose tools any agent can call: small, fast, packs a punch. You export the tools from tools.js; the platform runs them. Each Bullet answers at https://mcp.srf.gg/<slug>: the srf gateway validates the input, signs every call and forwards it with the identity of the user the agent is acting for. Your code never sees an API key and never stores a token. A Bullet is not a web app: its URL serves no pages, it cannot be always on, and a tool result stays under 1 MB.
Export tools and providers
tools map a name to a description, a JSON Schema for the input and a handler. providers are the third-party accounts (OAuth) or typed credentials the tools need from each user; users connect them once. The platform reads both from the running Bullet on every deploy, so there is nothing to declare by hand.
Per-user state and connections
Handlers get ctx.user, a per-user key-value store (ctx.kv, Bullet-wide ctx.kvShared) and ctx.connections(provider), which returns the user's OAuth tokens or credentials for a declared provider, refreshed by the platform.
tools.js the whole Bullet
// tools.js - a Bullet. Export tools; the platform runs them.
export const providers = [
{ id: "yahoo", label: "Yahoo Fantasy", kind: "oauth", scopes: "fantasy_read", multiple: true, reason: "Read your leagues and rosters" },
];
export const tools = {
evaluate_trade: {
description: "Score a fantasy trade for the user and explain the verdict.",
input: { type: "object", properties: { give: { type: "array" }, get: { type: "array" } }, required: ["give", "get"] },
handler: async ({ give, get }, ctx) => {
const rankings = (await ctx.kv.get("rankings")) ?? {}; // per-user state
const leagues = await ctx.connections("yahoo"); // the user's connected accounts
return { score: get.length - give.length, leagues: leagues.length, rankedPlayers: Object.keys(rankings).length };
},
},
};package.json no dependencies needed; list any package your tools import
{
"name": "trade-helper",
"private": true,
"type": "module",
"dependencies": {}
}From code to your agent
srf init trade-helper --template bullet # tools.js + package.json
npm install && srf tools serve # runs it on localhost, unsigned, in-memory KV
srf push && srf deploy # the platform declares the tools from your code
srf tools call evaluate_trade --input '{"give":["A"],"get":["B"]}'Every deploy re-reads the tools from the running Bullet. Agents do the same through the MCP tools srf_create_project (kind bullet), srf_push, srf_tools and srf_tool_call. An app that serves its own tool endpoints with createToolServer still works and declares them with srf tools sync --from.
Connecting an agent to a Bullet
- Chat apps (Claude, ChatGPT and others): add a custom connector with the URL
https://mcp.srf.gg/<slug>. You sign in with srf, so the Bullet acts as you. The project page's Connect an agent section has the exact URL. - Command-line agents (Claude Code shown):
claude mcp add --transport http <slug> https://mcp.srf.gg/<slug> --header "Authorization: Bearer <key>"
- Editors (Cursor, Windsurf, VS Code):
{ "mcpServers": { "<slug>": { "url": "https://mcp.srf.gg/<slug>", "headers": { "Authorization": "Bearer <key>" } } } }
Not on Node? The gateway speaks plain HTTP: a signed POST /tools/<name> answered with { ok, result }. The header list, signature formula and a FastAPI example are in the @srfgg/sdk README under "HTTP contract for other languages".
CLI basics
The srf CLI covers the same surface as MCP for terminal-first workflows.
npm install -g @srfgg/cli srf login # browser-based auth srf init my-site # create + link a project srf push # push files -> static projects are instantly live srf deploy # app projects: push + build + deploy srf logs --tail # stream logs from a deployed app
Secrets
Agents never see secret values. An agent declares what a project needs (srf secret declare STRIPE_SECRET_KEY or the MCP equivalent), and you fill the value in the web UI. Values are encrypted at rest and injected into your app's environment at deploy - runtime injection and human reveal are separately audited.
srf_db API
srf_db is the database every app in your organization can share. Apps connect to it with SRF_DB_URL; anything else - a BI tool, a CRM sync, your own service - uses this API with an integration key from Settings, API Keys (scope srf_db:read or srf_db:write). Integration keys work only here.
| GET | /api/v1/db/schema | Every table across apps and shared, with columns and row counts. |
| POST | /api/v1/db/query | { sql, params? } Read-only SQL as the analyst role. $1 placeholders. 10s, 500 rows. |
| GET | /api/v1/db/tables/{schema}/{table} | Rows of one table. ?limit, ?offset, ?order=col desc. |
| POST | /api/v1/db/execute | { sql, params? } One write statement. Full use of shared; app schemas stay read-only. Needs srf_db:write. |
Base URL https://app.srf.gg. 120 requests per minute per key. Errors are { error: { code, message } }. BI tools that speak Postgres can connect directly with the read-only connection string from Services.
Example curl
curl https://app.srf.gg/api/v1/db/query \
-H "Authorization: Bearer $SRF_KEY" \
-H "Content-Type: application/json" \
-d '{"sql":"select name, count(*) from shared.customers c join app_billing.invoices i on i.customer_id = c.id group by 1","params":[]}'Limits
| Limit | Free | Pro | Business |
|---|---|---|---|
| Tokens | 5 | Unlimited | Unlimited |
| Projects | 1 | Unlimited | Unlimited |
| Bullets | 1 | Unlimited | Unlimited |
| Static projects | 1 | 100 | 500 |
| Static project size | 50 MB | 500 MB | 2000 MB |
| Max file size | 25 MB | 100 MB | 250 MB |
| Running apps | - | 3 | 10 |
| Sleeping apps (wake on visit) | - | Unlimited | Unlimited |
| Apps sleep after | - | 2 idle hours | Never (dedicated machine) |
| Always-on apps | - | $5/app/mo | Included |
| App memory | - | 512 MB | 1024 MB |
| Managed databases | 1 | 10 | 25 |
| Log retention | 7 days | 30 days | 90 days |
| Branded host (yourco.srf.gg) | - | - | Yes |
| Collaboration (comments, review, tracked links) | - | - | Yes |
A single push request is capped at ~10 MB - push larger asset sets across multiple pushes.