About Homespun
Homespun is an MCP server for deploying multi-user web apps and operating their data. It connects MCP clients to hosted app deployment, identity, shared database, permissions, notifications, and attachments.
Key features
- 01Deploy and update hosted web apps
- 02Manage collection rows and change feeds
- 03Configure members, roles, and grants
- 04Handle file attachments
- 05Manage apps, domains, and agent identity
Use cases
- 01Deploy a multi-user app from an agent
- 02Read and update app data after deployment
- 03Track changes made by app users
- 04Invite members and assign data permissions
MCP support
The stdio MCP server exposes the Homespun CLI's capabilities as tools to MCP clients. It shares configuration and agent identity with the CLI.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://homespun.dev/mcpclaude mcp add --transport http dev-homespun-homespun https://homespun.dev/mcp{"mcpServers":{"dev-homespun-homespun":{"type":"http","url":"https://homespun.dev/mcp"}}}Open in Cursor{"servers":{"dev-homespun-homespun":{"type":"http","url":"https://homespun.dev/mcp"}}}Open in VS Code{"mcpServers":{"dev-homespun-homespun":{"type":"http","url":"https://homespun.dev/mcp"}}}{"mcpServers":{"dev-homespun-homespun":{"serverUrl":"https://homespun.dev/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
Tools
27| Parameter | Type | Required | Description |
|---|---|---|---|
| size | integer | Yes | UTF-8 byte length of the HTML document. |
| app_id | string | No | Existing app id when this upload is for a redeploy; omit for a create. |
| sha256 | string | Yes | SHA-256 hex digest of the exact UTF-8 HTML bytes to upload. |
Details
From the project README@homespunapps/mcp
A thin stdio Model Context Protocol server for Homespun. It lets any MCP client (Claude Desktop, Cursor, Windsurf, Cline, your own host) deploy a real multi-user web app in one call and keep operating its data afterwards: hosting on its own URL, magic-link identity, a shared realtime database with per-role permissions, email notifications and file attachments, all included.
It is a wrapper, not a reimplementation: all relay I/O goes through @homespunapps/core, and config is shared with the homespun CLI (~/.config/homespun/config.json), so the CLI and this server use the same agent identity.
Runtime requirement: Node.js >= 20
The binary is homespun-mcp. It speaks MCP over stdio and is meant to be launched by an MCP host, not run interactively.
Quickstart
No global install needed: point your MCP client at npx @homespunapps/mcp. On first use, if no API key is configured, the server auto-registers a fresh agent against the hosted relay and saves the key to the shared CLI store; nothing else to set up.
Claude Desktop
Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"homespun": {
"command": "npx",
"args": ["-y", "@homespunapps/mcp"]
}
}
}
To pin an existing agent key instead of auto-registering, add an env block:
{
"mcpServers": {
"homespun": {
"command": "npx",
"args": ["-y", "@homespunapps/mcp"],
"env": { "HOMESPUN_API_KEY": "hs_..." }
}
}
}
Cursor
Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project):
{
"mcpServers": {
"homespun": {
"command": "npx",
"args": ["-y", "@homespunapps/mcp"],
"env": { "HOMESPUN_API_KEY": "hs_..." }
}
}
}
Generic MCP host
Any client that takes a command + args + env works the same way:
{
"mcpServers": {
"homespun": {
"command": "npx",
"args": ["-y", "@homespunapps/mcp"],
"env": {
"HOMESPUN_URL": "https://homespun.dev",
"HOMESPUN_API_KEY": "hs_..."
}
}
}
}
If you'd rather install it globally (npm i -g @homespunapps/mcp), use "command": "homespun-mcp" with no args.
Configuration
All environment variables are optional; the defaults target the hosted relay and auto-register on first use.
| Variable | Default | Purpose |
|---|---|---|
HOMESPUN_URL | https://homespun.dev | Relay base URL. Set to point at a different relay. |
HOMESPUN_API_KEY | (auto-registered) | Agent API key. If unset, the server registers an agent on first use and saves the key to ~/.config/homespun/config.json (shared with the CLI). |
HOMESPUN_TOKEN | (none) | Alias for HOMESPUN_API_KEY (for hosts that name secrets *_TOKEN). HOMESPUN_API_KEY wins if both are set. |
HOMESPUN_AGENT_NAME | homespun-mcp | Display name for the auto-registered agent. |
HOMESPUN_REGISTER_SECRET | (none) | Registration secret, only for relays running REGISTRATION_MODE=secret. |
Config precedence mirrors the CLI: env vars win over the saved profile, which falls back to the default relay URL.
Tools
This server has full parity with the homespun CLI: every capability the CLI exposes is reachable here.
MCP tools are request/response, so there is no long-lived "watch". To see what changed you poll get_feed_events with the cursor from the previous call (pass wait to long-poll, 0 to 30 seconds); to watch one collection, re-call list_rows with the prior next_cursor as since. Each tool description spells out the pattern for the model.
To keep the tool list compact (a flat 50+ tools would bloat client context and degrade selection), hot-path nouns stay discrete tools while multi-verb management nouns collapse into one tool each with a required action enum.
Hot-path (discrete) tools
| Tool | What it does |
|---|---|
deploy_app | Deploy a v2 app: an HTML document plus a capability manifest, hosted at its own URL. Omit app_id to create, pass it to redeploy in place (same URL, same data, same members). Takes html or html_path, optional assets, visibility, slug, dry_run, force. |
list_rows | List rows in a collection. Doubles as the poll for a collection's current state: pass the prior next_cursor as since. |
get_row | Fetch one row by key (a dedicated relay route, not a client-side scan). |
add_row | Create a row, or return the existing one if key is already present (deduped: true), or row_not_found when the collection's read list does not reach that row for you. The only create-shaped verb. |
update_row | Replace an existing row's data. Optional if_match optimistic lock. |
delete_row | Soft-delete a row. Optional if_match. |
get_feed_events | Poll the app's change feed for row creates/updates/deletes from any writer, human or agent. Optional wait (0-30s) long-poll. |
Consolidated tools (one tool, required action)
| Tool | Actions |
|---|---|
apps | list · show · update · share_link_rotate · delete · wake · domain_set · domain_status · domain_remove |
members | add · list · set_role · remove · roles |
grants | mint · list · revoke |
ingest | list · rotate · set_signing_secret · clear_signing_secret |
attachments | upload · fetch · presign · finalize · download · show · list · delete · mint_token · revoke_token · list_tokens |
taste | get · set · clear |
key | list · mint · revoke |
feedback | create · list |
agent | whoami · claim · logout |
community | publish · unpublish · get_config_contract · install · list_pending · get_submission · approve · reject · set_trust_level |
publisher | claim · get · update |
review | create · respond · report · remove · unhold |
Single-purpose tools
| Tool | What it does |
|---|---|
get_skill | Fetch the relay's auto-updating guide (unauthenticated) to self-teach the workflow. |
Attachments take and return file paths: upload reads an absolute file_path; download writes to an absolute out_path (or returns base64 when omitted). For real media, presign then PUT then finalize avoids moving bytes through the tool call.
One data primitive. Everything an app stores is a collection: a named, mutable, queryable set of rows, each with a key, a data payload, an optimistic-lock version and an author. Every write also lands on the app's ordered change feed. Declare a collection appendOnly: true in the manifest when you want a journal (an audit trail, a submission log) rather than mutable state.
Not exposed (and why)
- The CLI's
config showis replaced byagent→whoami(resolved relay URL, active profile, and whether a key is set; no secrets). agent registeris not a tool. The server auto-registers on first use and shares the CLI's key store;agent→claimbinds it to a human afterwards.demo(the interactive terminal tour) and the CLI self-updater are terminal concerns with no agent use; omitted.
Typical flow
deploy_appwith your HTML plus anx-homespun-manifestdeclaring the app's collections and which roles may read, write and delete each. Returns{ app_id, url, ... }.- Give the
urlto the owner, and invite anyone else withmembers(action: add). get_feed_eventswithwait: 25in a loop, passing the priorcursorassince, to see what people do.- Read and write the same data with
list_rows/add_row/update_row, and ship changes withdeploy_appagain, passingapp_id.
MCP registry
server.json (in this package) carries the metadata for the official MCP registry. Publishing there is a follow-up step for the maintainer.
License
MIT, see LICENSE.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.