Homespun
Server Details
Deploy a multi-user web app from your agent: hosting, auth, database, and permissions.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
- Repository
- homespunapps/homespun
- GitHub Stars
- 0
- Server Listing
- Homespun
Glama MCP Gateway
Connect through Glama MCP Gateway for full control over tool access and complete visibility into every call.
Full call logging
Every tool call is logged with complete inputs and outputs, so you can debug issues and audit what your agents are doing.
Tool access control
Enable or disable individual tools per connector, so you decide what your agents can and cannot do.
Managed credentials
Glama handles OAuth flows, token storage, and automatic rotation, so credentials never expire on your clients.
Usage analytics
See which tools your agents call, how often, and when, so you can understand usage patterns and catch anomalies.
Tool Definition Quality
Score is being calculated. Check back soon.
Available Tools
20 toolsagentManage Agent IdentityDestructiveInspect
Agent identity + binding. ONE tool with an action enum: whoami (the resolved relay URL, active profile, whether a key is configured — no network, no secrets) | claim (bind this agent to a human via a one-shot claim code from their Settings UI; one-way) | logout (clear the locally-saved key/profile; does NOT revoke it on the relay — use the key tool's revoke for that).
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | The one-shot claim code (required for claim). | |
| action | Yes | Agent identity. whoami: show the resolved relay URL, active profile, and whether a key is configured (no network, no secrets). claim: bind this agent to a human via a one-shot claim code the human generated in their Settings UI (one-way). logout: clear the locally-saved key/profile (does NOT revoke it on the relay — use the key tool's revoke for that). |
appsManage AppsDestructiveIdempotentInspect
Manage v2 app lifecycle (deploy_app creates/redeploys; this tool covers the rest). ONE tool with an action enum: list (YOUR owning human's apps) | show (full detail incl. manifest, timezone, has_share_token) | update (visibility and/or timezone - slug is immutable; switching TO 'link' returns a share_url once) | share_link_rotate (rotate a 'link' app's share token, returning a new share_url and revoking the old link; also generates one if the app has none) | delete (soft-delete, idempotent) | wake (a dormant app; a no-op reporting the actual status otherwise) | domain_set (bind ONE custom domain; returns the DNS records the domain owner must publish) | domain_status (the domain record, live-refreshed against Cloudflare when enabled; inspect last_error when it is not activating) | domain_remove (unbind the domain, idempotent).
| Name | Required | Description | Default |
|---|---|---|---|
| slug | No | list only. Exact-match slug filter. | |
| limit | No | list only. Page size. | |
| action | Yes | list: YOUR owning human's apps. show/update/delete/wake: act on one app (app_id). share_link_rotate: rotate a 'link' app's share token, returning a new share_url (the old link stops working); also generates one if the app has none yet. domain_set/domain_status/domain_remove: manage the app's ONE custom domain (app_id; domain_set also needs domain). | |
| app_id | No | Required for show/update/share_link_rotate/delete/wake/domain_set/domain_status/domain_remove. | |
| cursor | No | list only. Opaque cursor from a previous next_cursor. | |
| domain | No | domain_set only. The bare custom domain to bind (e.g. app.example.com). The response's dns_records lists the DNS entries the domain owner must publish. | |
| status | No | list only. Default: active. | |
| timezone | No | update only. The app's IANA timezone for `schedules` reminders (e.g. Europe/Berlin). An app that declares schedules with no timezone fires reminders at 08:00 UTC. | |
| visibility | No | update only. The new visibility (slug is immutable). |
attachmentsManage AttachmentsDestructiveInspect
Binary attachments (images, PDFs, audio, video) referenced from event payloads / input_data via format: homespun-attachment-id. ONE tool with an action enum: upload | fetch | presign | finalize | download | show | list | delete | mint_token | revoke_token | list_tokens. TOKEN COST, READ FIRST: an inline upload with content_base64 carries the bytes in the tool-call arguments, so they enter the MODEL CONTEXT and cost tokens PROPORTIONAL TO FILE SIZE (a few-hundred-KB image is already very costly, worse on every retry). For ANY real image or media (anything beyond a tiny icon) use a ZERO-CONTEXT path instead: fetch when you have a URL (the relay downloads it server-side, you send only the URL string), or presign + finalize when the client can PUT the raw bytes out-of-band. fetch: { source_url (https), scope } — the relay downloads the URL itself behind an SSRF guard (https only, no private/loopback/metadata hosts, DNS pinned, redirects refused, size-capped, timed out) and runs the same byte-sniff + allowlist + size + quota + scan checks as any upload; works on any storage backend. upload (inline) takes EITHER content_base64 (base64 bytes, no filesystem; last-resort for small assets or clients with neither a URL nor an out-of-band PUT) OR file_path (ABSOLUTE path read on the RELAY host, only usable when the file is local to the relay). presign + finalize (token-free, for images/video/big audio): (1) presign with { mime, size, sha256, scope } returns { put_url, attachment_id }; (2) YOU PUT the raw bytes to put_url over plain HTTP out-of-band; (3) finalize with the attachment_id. At finalize the relay re-reads the stored bytes, BYTE-SNIFFS the real type, and enforces the same allowlist + size + sha256 + quota + scan checks as any upload, so a presign that lies about its mime is caught and never served inline. The presigned path requires the Azure storage backend; a filesystem self-host returns a clear not-supported error (use fetch or inline upload there). download writes to an ABSOLUTE out_path (or returns base64). Scope an upload to agent (default, reusable) or app. mint_token returns a /b/ capability URL (ONCE) a browser can GET without your API key.
| Name | Required | Description | Default |
|---|---|---|---|
| mime | No | upload/presign: advisory Content-Type. The relay BYTE-SNIFFS the actual bytes and stores/serves that sniffed type regardless (a lying mime is caught, never served inline). Required for presign (scopes the upload URL + fails fast against the allowlist). | |
| once | No | mint_token: token self-deletes on first GET. | |
| size | No | presign: the exact byte length you will PUT. Committed at presign and re-verified against the uploaded bytes at finalize. | |
| limit | No | list page size (1..100). | |
| scope | No | upload scope (default agent). | |
| action | Yes | Binary attachment operations. For ANY real image or media (anything beyond a tiny icon) PREFER a ZERO-CONTEXT path so the bytes never enter the model context and cost NO tokens: `fetch` when you have a URL (the relay downloads it server-side; you send only the URL string), or presign + finalize when the client can PUT the raw bytes out-of-band. upload with `content_base64` sends the bytes INLINE in the tool-call arguments, loading them into the model context at a token cost PROPORTIONAL TO FILE SIZE (even a few-hundred-KB image is very costly, worse on every retry); use it only as a last-resort fallback for small assets or clients that have neither a URL nor an out-of-band PUT. fetch: pass { source_url, scope } and the relay fetches the bytes itself (https only, SSRF-guarded) and runs the same sniff/allowlist/size/quota/scan checks as any upload. upload: `content_base64` (base64 bytes, no filesystem) or `file_path` (absolute, read on the RELAY host); scope agent|app. presign + finalize: (1) presign with { mime, size, sha256, scope }, (2) PUT the bytes to put_url out-of-band, (3) finalize confirms it (re-sniffs + re-checks the bytes). download: fetch bytes by attachment_id to out_path (absolute) or return base64. show: metadata only. list: the agent's attachments. delete: soft-delete. mint_token: mint a /b/<token> capability URL (returned ONCE). revoke_token / list_tokens: manage those tokens. | |
| app_id | No | Required when scope=app. | |
| cursor | No | list pagination cursor. | |
| sha256 | No | presign: the hex SHA-256 (64 chars) of the exact bytes you will PUT. Committed at presign and re-verified against the uploaded bytes at finalize. | |
| filename | No | upload: display filename (defaults to the file's basename). | |
| out_path | No | download: ABSOLUTE path to write the bytes to. If omitted, the bytes are returned base64-encoded in the result. | |
| token_id | No | revoke_token: the token id to revoke. | |
| file_path | No | upload: ABSOLUTE path to a file read on the SERVER host running this MCP connector (the relay), NOT your machine. Only works when the file is local to the relay (e.g. a locally-run CLI). For a hosted or remote agent, use `content_base64` instead. | |
| source_url | No | fetch: an https URL the RELAY downloads server-side, so the bytes NEVER enter the model context (zero token cost). SSRF-guarded: https only, no private/loopback/link-local/metadata hosts, DNS pinned, redirects refused, size-capped, timed out. The downloaded bytes run the same byte-sniff/allowlist/size/quota/scan checks as any upload. Prefer this (or presign+finalize) over `content_base64` for real images/media. | |
| ttl_seconds | No | mint_token: per-token TTL (clamped by scope default). | |
| attachment_id | No | Attachment id. Required for download/show/delete/mint_token/revoke_token/list_tokens. | |
| content_base64 | No | upload: the file bytes as base64, sent INLINE with no filesystem access. WARNING: the base64 rides in the tool-call arguments and enters the MODEL CONTEXT, costing tokens PROPORTIONAL TO FILE SIZE (a few-hundred-KB image is already very costly, and it compounds on every retry). PREFER presign + finalize for any real image or media whenever the client can do an out-of-band HTTP PUT; reserve `content_base64` for small assets (a tiny icon) or clients that cannot PUT out-of-band. If both `content_base64` and `file_path` are given, `content_base64` wins. The relay sniffs the real type and enforces the same size/allowlist/quota checks as a file upload. |
communityCommunity TemplatesDestructiveInspect
Publish an app you own as a COMMUNITY TEMPLATE, install a template into your own account, and (relay operators only) review submissions. ONE tool with an action enum: publish | get_config_contract | install | list_pending | get_submission | approve | reject | set_trust_level. publish captures your live app (html + manifest + the seed rows of its seedOnInstall collections + listing metadata) into a PENDING template - installable by the returned direct link but NOT listed in the public gallery until an operator approves it; you must have a verified email and at most a few pending submissions at once. PRIVACY: an approved template's content AND its captured seed rows become PUBLIC to every platform user, so never publish an app whose seedOnInstall collections hold real personal data - seed data must be example-only. Pass attest_example_only:true to attest you checked this. Optionally give the template a per-publisher slug (namespaced id /) and a semver version (default 1.0.0): a republish under the same slug must bump the version. get_config_contract reads what a template needs at install (its settings collection + ordered config/upload steps) by ref; install creates a fresh PRIVATE copy of a template for YOUR owning human, passing the answers as config (a 'config' value is a string, an 'upload' value is a pre-uploaded attachment id from the attachments tool). The review actions are limited to the relay's configured community reviewers: list_pending (the queue), get_submission (a submission's full content by snapshot_id), approve (list it in the gallery; a re-publish supersedes your app's prior approved version), reject (with a required note that lands in the publisher's app feed).
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | get_config_contract/install only. The template to read or install: a namespaced '<handle>/<slug>' or a community snapshot id. | |
| note | No | reject only. The required rejection note shown to the publisher (delivered to their app feed). | |
| slug | No | publish only. Optional per-publisher slug (lowercase, 3 to 48 chars, hyphens). Gives the template a namespaced id <your-handle>/<slug>; a republish reuses the slug and must bump the version. | |
| tags | No | publish only. Up to 6 curation tags. | |
| limit | No | list_pending only. Page size (1..200). | |
| title | No | publish only. Listing title (1 to 80 chars). Defaults to the app's manifest name. | |
| action | Yes | publish: publish one of YOUR apps as a community template (app_id; optional title/description/category/tags). PRIVACY: publishing makes the template content AND the captured seed rows (the LIVE rows of every seedOnInstall collection, captured at publish time) PUBLIC to every platform user once approved. Do NOT publish an app whose seedOnInstall collections hold real personal data (names, emails, addresses, messages, anything private): seed data must be example-only. Pass attest_example_only:true to attest you have checked this. The capture (html + manifest + seed rows) lands PENDING review, installable by its returned direct link but not listed until approved; an ESTABLISHED publisher is fast-tracked (the response's expedited/auto_approved tell you which). get_config_contract: read a template's install-time config contract by `ref` (a namespaced '<handle>/<slug>' or a snapshot id): its settings_collection, ordered config_steps (each with key/kind/required/secret/choices/default), and connect_steps (inbound hooks the app receives on). An 'upload' step wants a file; pre-upload it with the attachments tool (scope agent) and pass its attachment id. After installing a template with connect_steps, run the `ingest` tool's list action on the new app_id to read its freshly provisioned hook URLs, and wire each into the external service. install: install a template by `ref` for YOU (your owning human becomes the owner). Pass `config` as { stepKey: value } from the contract: a 'config' step's value is a string, an 'upload' step's value is a pre-uploaded attachment id. A required step you omit is rejected. Returns the new app's id, slug, and url; installs always create a fresh private copy. list_pending / get_submission / approve / reject / set_trust_level are RELAY-OPERATOR-only review actions: list_pending (the review queue, expedited submissions first), get_submission (a submission's full html+manifest+seedRows plus external_destinations, the hosts it can send data to or pull data from, by snapshot_id), approve (snapshot_id, lists it in the gallery + supersedes the app's prior approved version), reject (snapshot_id + a required note that lands in the publisher's app feed), set_trust_level (promote/demote a publisher by handle: handle + trust_level 'new'|'established'). | |
| app_id | No | publish only. The id of an app YOU own to publish. | |
| config | No | install only. The install-time answers as { stepKey: value } from the config contract: a 'config' step's value is a string, an 'upload' step's value is a pre-uploaded attachment id. Omit for a template with no config steps. | |
| cursor | No | list_pending only. Opaque cursor from a prior next_cursor. | |
| handle | No | set_trust_level only. The @-handle of the publisher to promote or demote. | |
| version | No | publish only. Semver MAJOR.MINOR.PATCH (default '1.0.0'). A republish under the same slug must be strictly greater than the current version. | |
| category | No | publish only. Optional single-word category (e.g. 'household'). | |
| description | No | publish only. Listing blurb (up to 200 chars). Defaults to the manifest description. | |
| setup_steps | No | publish only. Ordered typed setup steps an installing agent follows after install (up to 20). A 'config'/'upload' step may carry a `key` naming a field of the manifest's settingsCollection that its install-time answer is written into; a 'connect' step may carry an `ingestRule` naming a manifest ingest rule it wires up. Read back via get_submission and rendered on the template detail page. | |
| snapshot_id | No | Required for get_submission/approve/reject. The submission's snapshot id (from publish's response or list_pending). | |
| trust_level | No | set_trust_level only. 'established' fast-tracks the publisher's future submissions through review; 'new' reverts to full review. | |
| changelog_note | No | publish only. A short note recorded in this version's changelog. | |
| long_description | No | publish only. Optional long-form description (up to 4000 chars) shown on the template detail page below the short blurb, for readers and search ranking. Plain text: blank lines become paragraphs, and it is escaped (never rendered as raw HTML), so write prose, not markup. | |
| attest_example_only | No | publish only. Set true to attest that the template content AND the captured seed rows contain NO real personal data. Publishing makes both PUBLIC to every platform user, so seed data (the live rows of your seedOnInstall collections) must be example-only, never real names/emails/addresses/private messages. Recorded and shown to the reviewer; omitting it still publishes but is flagged to the operator as not attested. | |
| derived_from_snapshot_id | No | publish only. Optional remix/fork lineage: the snapshot id this template was derived from. |
delete_rowDelete RowDestructiveIdempotentInspect
Soft-delete a row from a v2 app's collection. A watcher sees the deletion live (op:delete on the change feed). Pass if_match for an optimistic-locked delete. Returns { deleted: true }.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | The key of the row to delete. | |
| app_id | Yes | The app id. | |
| if_match | No | Optional optimistic-lock version. | |
| collection | Yes | The collection name. |
deploy_appDeploy AppDestructiveInspect
Deploy a v2 app: an HTML document + a capability manifest, hosted at its own URL. The manifest has eight extension keys: app metadata; collections (+ per-collection write/read/delete role lists); externalHosts (fetch allowlist); cdn (allow CDN scripts/styles); capabilities (Permissions-Policy opt-ins); embeds (iframe frame-src allowlist); notify (email-on-row rules); webhooks (signed HTTP POST on-row rules). Pass EITHER no app_id (create, mints a slug + URL) OR app_id (redeploy an existing app with new content). Supply the HTML as INLINE html OR as html_path (an absolute path read on the MCP-SERVER host, which is the relay for a hosted connector or your CLI host for a locally-run one, NOT the remote agent's machine; use it to avoid retransmitting a large HTML file every deploy, but only a locally-run connector can read it, and if both are given inline html wins). Pass dry_run:true (alias check) to VALIDATE ONLY: it runs the full manifest + asset-shape validation, the redeploy compat gate, and the schedule-timezone advisory, then returns { ok, warnings, compat?, breaks? } WITHOUT creating a version or mutating anything. A redeploy that NARROWS the manifest (drops a collection, tightens a schema, revokes a role) is refused with manifest_incompatible_redeploy unless force:true; a narrowed collection is then detached, never deleted. Ship images/fonts/audio/video/data FILES with the app in the SAME call via assets[]: each is validated + stored app-scoped and served at its path on the app's own origin, so the HTML references it by a stable same-origin path (<img src="frames/000.jpg">, <video src="media/clip.mp4">), media and font paths support HTTP Range for seeking. A redeploy's assets replace the previous version's set. BEFORE authoring: call get_skill for the manifest grammar. Returns { app_id, slug, url, version, visibility, created } (create) or { app_id, version, compat, breaks? } (redeploy).
| Name | Required | Description | Default |
|---|---|---|---|
| html | No | The app's UI as a complete HTML document (single file, up to the relay's size cap), sent INLINE. Provide EITHER this or `html_path`. Inline is required for a hosted/remote connector that has no filesystem. If both are given, inline `html` wins. | |
| slug | No | CREATE only. Accepted with visibility private or public, including the private default; rejected with explicit visibility 'link', where the slug is always server-generated. | |
| check | No | Alias for `dry_run`. | |
| force | No | REDEPLOY only. Bypass the compat gate on a narrowing manifest change (a removed/narrowed collection is detached, never deleted). | |
| app_id | No | Omit to CREATE a new app; pass an existing app's id to REDEPLOY it (a new version, compat-gated unless force:true). | |
| assets | No | Optional bundle of files shipped WITH the app in ONE deploy: images, fonts, audio/video, data. Each asset either carries its bytes inline as `content_base64` OR references an already-uploaded attachment by `attachment_id` (prefer the reference form for real images/media: upload once via `attachments fetch` or presign, then bind it here with NO base64 in the deploy body). Each asset is validated + stored app-scoped exactly like a normal attachment (byte-sniff, allowlist, size cap, quota, scan) and served at its `path` on the app's OWN origin, so the page references it by a stable same-origin path (`<img src="frames/000.jpg">`, `<video src="media/intro.mp4">`; media/font paths support HTTP Range). The whole deploy is rejected atomically if any asset fails validation. A redeploy's assets REPLACE the previous version's set. Bounded by the relay's per-deploy asset-count cap; total bytes by the per-app blob quota. | |
| dry_run | No | Validate only: run the full manifest + asset-shape validation, the compat gate (for a redeploy), and the schedule-timezone advisory, then return { ok, warnings, compat?, breaks? } WITHOUT creating a version or mutating anything. An invalid manifest returns the SAME error a real deploy would; a narrowing redeploy reports the compat break instead of applying it. `check` is an accepted alias. | |
| manifest | Yes | The x-homespun-manifest capability document (a JSON object). Eight extension keys: app metadata; collections (+ per-collection write/read/delete role lists); externalHosts (fetch allowlist); cdn (allow CDN scripts/styles); capabilities (Permissions-Policy opt-ins); embeds (iframe frame-src allowlist); notify (email-on-row rules); webhooks (signed HTTP POST on-row rules). Call get_skill for the full grammar before authoring one from scratch. | |
| html_path | No | ABSOLUTE path to the app's HTML document, read on the MCP-SERVER host (the machine running this connector: the relay for a hosted connector, or your CLI host for a locally-run one), NOT on the remote agent's machine. Alternative to inline `html` that avoids retransmitting a large HTML file on every deploy. Only works when the file is local to the MCP server, so it helps a locally-run connector, not a hosted/remote one (where the path will not exist and you get a clean error, so pass inline `html` there). If both `html` and `html_path` are given, inline `html` wins. | |
| visibility | No | CREATE only. Default 'private' (owner plus invited members, sign-in gated). 'link' shares with anyone holding the returned share_url, whose #k= fragment carries a secret key that can be reset (rotate it via the apps tool, action share_link_rotate) to cut off everyone with the old link; a 'link' app always gets a server-generated unguessable slug. 'private' and 'public' accept an owner-chosen `slug`. |
feedbackManage FeedbackDestructiveInspect
Send or list feedback to the relay operator. ONE tool with an action enum: create (a bug|feature|note with a message, optional app_id) | list (the agent's own submissions, newest first, paginated by before).
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Feedback category (required for create). | |
| limit | No | list page size (default 50, max 100). | |
| action | Yes | Feedback to the relay operator. create: submit a bug|feature|note with a message (optional app_id). list: the agent's own submissions, newest first. | |
| app_id | No | Optional app this feedback relates to (create). | |
| before | No | list cursor from a prior page's next_before. | |
| message | No | Message body (required for create). |
get_feed_eventsGet App Feed EventsRead-onlyInspect
Poll a v2 app's change feed for what happened (row creates/updates/deletes, from any writer — agent or human). This is the long-poll analogue of homespun apps watch — there is no streaming in MCP. Poll loop: call with no since first; process the returned entries; remember cursor; call again passing it as since to get only newer entries. To WAIT for activity, pass wait (~25) so the relay holds the request open until an entry arrives or it times out. A since older than the retention floor returns resync_required — re-list the collection(s) with list_rows instead. Returns { entries, cursor, truncated }.
| Name | Required | Description | Default |
|---|---|---|---|
| wait | No | Optional long-poll: how long the relay holds the request open waiting for a new entry (0-30s). Use ~25 when waiting for activity, then call again with the same cursor. | |
| limit | No | Max entries per page (capped server-side by FEED_PAGE_MAX). | |
| since | No | Opaque numeric cursor from a previous call's cursor. Omit (or 0) to read from the beginning. | |
| app_id | Yes | The app id. |
get_rowGet RowRead-onlyInspect
Fetch a single row by its key from a v2 app collection (a dedicated relay route — not a client-side scan). Returns { row } or an isError row_not_found.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | The key of the row to fetch. | |
| app_id | Yes | The app id. | |
| collection | Yes | The collection name. |
get_skillGet Skill GuideRead-onlyInspect
Fetch the relay's auto-updating SKILL.md (the full Homespun usage guide) — UNAUTHENTICATED, needs no API key. Call this to self-teach the Homespun workflow (events vs records, schema grammars, the poll loop) before driving the other tools. Pass version_only:true to get just the relay's skill version string (to check if a cached copy is stale).
| Name | Required | Description | Default |
|---|---|---|---|
| version_only | No | If true, return only the relay's current skill version string instead of the full SKILL.md markdown. |
grantsManage App Grant LinksDestructiveIdempotentInspect
Manage a v2 app's grant links (M5). A grant link is a capability URL that confers a DECLARED custom role (x-homespun-manifest.roles) on a stable, per-holder anonymous identity, so the holder's own rows are isolated by author/:own scoping. A grant NEVER escalates to owner/member/agent. ONE tool with an action enum: mint (create a link; returns a grant_url carrying the token in its #g= fragment, shown ONCE, never recoverable) | list (the app's links, never any token) | revoke (idempotent). mode once = one-time (first-browser-claims), multi = shared (capped by max_uses within expiry). An optional pin (pin_row_key OR pin_where) NARROWS the holder to specific rows, never widens. Note: a write-only grant pinned to a single row key can still read that row's existing data back via create dedup, so a 'write-only to slot X' grant exposes slot X's current contents to the holder.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | mint only. once: one-time link, claimed by the first browser that opens it (a real per-person link; later opens by others are inert). multi (default): a shared link, capped by max_uses within expiry. | |
| role | No | mint only. A DECLARED custom role for the app (an x-homespun-manifest.roles key). A built-in role (owner/member/agent/anyone) is rejected: a grant can never escalate. | |
| label | No | mint only. Optional owner label shown in the grant list. | |
| action | Yes | mint: create a grant link carrying a declared custom role (app_id+role). list: the app's grant links (app_id). revoke: revoke one link (app_id+grant_id). | |
| app_id | Yes | The app id. | |
| grant_id | No | revoke only. The grant link id (see list's `id` field). | |
| max_uses | No | mint only (multi mode). Cap total claims; omit for unlimited within expiry. Ignored for once (forced to 1). | |
| pin_where | No | mint only. Optional narrowing pin as Wave C2 where conditions ({field, op, value}[]). NARROWS within the role (never widens). Mutually exclusive with pin_row_key. | |
| pin_row_key | No | mint only. Optional narrowing pin to a single row key. NARROWS within the role (never widens). Mutually exclusive with pin_where. | |
| ttl_seconds | No | mint only. Grant lifetime in seconds; defaults to the server default (30 days) and is clamped to the server max. |
ingestManage App Inbound HooksDestructiveInspect
Manage a v2 app's inbound catch-hooks (inbound-webhooks). A catch-hook lets an EXTERNAL system (Stripe, Zapier, Make, Home Assistant, an email router) POST JSON to a secret URL that writes into a declared collection, so the app receives data even with no agent online. Hooks are DECLARED IN THE MANIFEST (x-homespun-manifest.ingest) and materialized at deploy, so this tool has no create/delete: use it to READ BACK the URL, rotate a leaked one, and manage the opt-in signing secret. ONE tool with an action enum: list (the app's hooks, each with its full secret URL, current rule collection/mode/wake/handshake, per-status delivery counts, and signing-secret state) | rotate (mint a fresh URL secret for one hook by name and return its NEW url once; the old url stops working immediately, no redeploy needed) | set_signing_secret (provision/rotate a hook's signing secret, a DIFFERENT secret from the URL: what a provider HMACs the body with; omit secret to mint one returned ONCE, or pass secret to store a provider value verbatim, never echoed) | clear_signing_secret (remove it). Signature verification ships DARK for now: nothing verifies a signature yet. After deploying a manifest that declares a hook, run list and tell the owner the exact url to paste into the external system.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | rotate / set_signing_secret / clear_signing_secret. The manifest ingest hook name (an x-homespun-manifest.ingest[].name). See list's `name` field. | |
| action | Yes | list: the app's inbound catch-hooks, each with its full secret URL, current rule (collection/mode/wake/handshake), and per-status delivery counts (app_id). rotate: mint a fresh URL secret for one hook and return its new URL once, invalidating the old URL immediately (app_id+name). set_signing_secret: provision or rotate a hook's OPT-IN signing secret, distinct from the URL secret (it is what a provider HMACs the body with); omit `secret` to mint one (returned ONCE) or pass `secret` to store a provider-generated value verbatim (never echoed) (app_id+name). clear_signing_secret: remove a hook's signing secret (app_id+name). | |
| app_id | Yes | The app id. | |
| secret | No | set_signing_secret only. A provider-generated signing secret to store verbatim (the Stripe path). Omit to have the relay mint one (the GitHub path), returned ONCE in the response. | |
| grace_seconds | No | set_signing_secret only. On a rotation, how long the previous secret stays valid so deliveries verify while you update the provider (default 3600, max 86400). |
keyManage API KeyDestructiveInspect
Inspect, mint, or revoke the calling agent's API key. ONE tool with an action enum: list (key info: agent_id, key_prefix, timestamps) | mint (mint a NEW sibling API key for YOUR OWN agent identity, same scope/ownership, and return its raw value ONCE, the way an MCP-driven agent bootstraps a CLI/child-process credential; the raw key is never retrievable again, the sibling appears in a list made WITH it, and the owner can revoke it) | revoke (self-destruct the agent's OWN key; it stops working immediately and is irreversible, so pass confirm:true). The relay derives identity from the caller's token, so every action acts only on the caller's own agent, and mint can never target another agent's id.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | The calling agent's API key. list: key info (agent_id, key_prefix, timestamps). mint: mint a NEW sibling API key for YOUR OWN agent identity (same scope/ownership) and return its raw value ONCE, so use it to hand a CLI or child process a working credential; the sibling is a distinct key that shows up in a subsequent `list` made WITH it, the owner can revoke it, and the raw value is never retrievable again. mint always acts on the calling agent, never another agent's id. revoke: self-destruct the agent's OWN key, which stops working immediately and is irreversible (requires confirm:true). | |
| confirm | No | Required (true) for revoke. |
list_rowsList RowsRead-onlyInspect
List rows in a v2 app's mutable collection. This also doubles as the POLL for a collection's current state (no streaming in MCP): pass the prior next_cursor as since to fetch only newer/changed rows. Returns { rows, next_cursor, has_more }.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size. | |
| since | No | Opaque cursor from a previous call's next_cursor. Also the POLL handle: pass it back to fetch only newer/changed rows. | |
| app_id | Yes | The app id. | |
| collection | Yes | The collection name declared in the app's manifest. |
membersManage App MembersDestructiveIdempotentInspect
Manage a v2 app's membership (auth spec §6) — who besides the app's owner can sign in to a private app / write to member-scoped collections. ONE tool with an action enum: add (invite-or-attach a member by email — attaches immediately if the email already has a Human, otherwise the relay emails a magic-link invite) | list (the app's owner + members) | set_role (change an existing member's declared custom role in place, or null to clear it — does NOT revoke their sessions, so use this rather than remove-then-add to re-role someone) | remove (idempotent; also revokes the human's live sessions on this app — the app owner cannot be removed) | roles (the derived roles summary: per declared role and collection, the EFFECTIVE access a holder actually has, reported separately for signed-in members and for grant-link holders since their role floors differ, plus member and active-grant-link counts).
| Name | Required | Description | Default |
|---|---|---|---|
| role | No | add only. Defaults to 'member' server-side — no other role is assignable via this API (ownership transfer is not available here). | |
| No | add only. The email to invite/attach. If a Human already exists for it, the member row is attached immediately; otherwise the relay emails a magic-link invite. | ||
| action | Yes | add: invite-or-attach a member by email (app_id+email; optional custom_role). list: the app's owner + members (app_id). set_role: change an existing member's custom role in place without signing them out (app_id+human_id+custom_role, null to clear). remove: drop a member (app_id+human_id). roles: the app's declared roles with, per collection, the EFFECTIVE access a holder has (separately for members and grant-link holders, whose role floors differ) plus how many members and live grant links hold each role (app_id). | |
| app_id | Yes | The app id. | |
| human_id | No | remove and set_role. The Human id to target — see list's `humanId` field. The app owner can be neither removed nor re-roled. | |
| custom_role | No | add (optional) and set_role (required). A DECLARED custom role (an x-homespun-manifest.roles key) attached to the member ALONGSIDE their base member powers. A built-in/reserved role or an undeclared role is rejected. Omit on add for an ordinary member; pass null on set_role to clear the role back to a plain member. |
publisherPublisher ProfileDestructiveInspect
Manage YOUR community publisher identity: the @-handle and public profile you present in the template gallery. ONE tool with an action enum: claim | get | update. get returns your profile (handle, whether it is claimed yet, tenure, and the rating/template counters). claim sets your handle exactly ONCE (it is permanent afterwards) from a lowercase 3-to-32-char string; a handle that is reserved (platform or role words) or already taken is refused. update changes your public display_name, bio, or url at any time. claim and update require a verified email; an existing publisher may already have a provisional maker-... handle (auto-assigned) that claim renames the one allowed time.
| Name | Required | Description | Default |
|---|---|---|---|
| bio | No | update only. Short public bio (up to 500 chars); null clears it. | |
| url | No | update only. Public http(s) URL (up to 200 chars); null clears it. | |
| action | Yes | get: return YOUR publisher profile (handle, tenure, counters). claim: set your @-handle ONCE (handle arg; lowercase, 3 to 32 chars, permanent after claiming; needs a verified email). update: change your public display_name/bio/url (any of them; needs a verified email). | |
| handle | No | claim only. The lowercase @-handle to claim (^[a-z0-9](?:[a-z0-9-]{1,30}[a-z0-9])$). Permanent once claimed. | |
| display_name | No | update only. Public display name (up to 80 chars); null clears it. |
reviewCommunity ReviewsDestructiveInspect
Rate and review community templates you have USED, respond to reviews of your own templates, and (relay operators only) moderate. ONE tool with an action enum: create | respond | report | remove | unhold. create leaves a 1-to-5 star rating plus an optional written body on a template you have installed - identify the template by template ("/") or by handle+slug; you need a verified email, and each install yields exactly one review (the aggregate carries across template versions). A body that contains a link or a contact email is AUTO-HELD for a moderator before it appears. respond replies to a review of YOUR OWN template line (review_id + response; null clears it), one editable response per review. report flags a review for the relay's moderators (review_id + reason), deduped per account. remove and unhold are limited to the relay's configured community reviewers: remove takes a review down and adjusts the rating aggregate; unhold publishes a previously auto-held review into the aggregate.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | create only. Optional written review (up to 2000 chars). | |
| slug | No | create only. Per-publisher slug (with `handle`). | |
| stars | No | create only. Star rating, an integer 1 to 5. | |
| action | Yes | create: leave a star rating (1..5) and optional body on a community template YOU have installed (identify it by `template` "<handle>/<slug>" or by `handle`+`slug`); requires a verified email, and one review per install. A body containing a link or contact email is auto-held for a moderator before it shows. respond: reply to a review of one of YOUR OWN templates (review_id + response; null clears it). report: flag a review for the relay's moderators (review_id + reason; one report per account). remove / unhold are RELAY-OPERATOR-only moderation actions on a review_id: remove takes a review down (adjusting the aggregate), unhold publishes a previously auto-held review. | |
| handle | No | create only. Publisher handle (with `slug`), an alternative to `template`. | |
| reason | No | report only. Why you are reporting this review (up to 500 chars). | |
| response | No | respond only. The publisher's public response (up to 2000 chars); null clears it. | |
| template | No | create only. The namespaced template id <handle>/<slug> to review. | |
| review_id | No | Required for respond/report/remove/unhold. The review's id. |
tasteManage UI Taste NotesDestructiveInspect
Read / write / clear the agent's freeform UI taste notes (a small markdown document of presentation preferences learned from human feedback — 'denser layout', 'no rounded corners'). ONE tool with an action enum: get | set | clear. Call get BEFORE generating an app so prior feedback shapes the output; set does a whole-document replace (not append). Keep entries about UI/presentation only.
| Name | Required | Description | Default |
|---|---|---|---|
| taste | No | The full markdown notes (required for set; whole-document replace, not append). | |
| action | Yes | The agent's freeform UI taste notes (markdown) — presentation preferences learned from human feedback. get: read them before generating an app. set: whole-document replace (taste, non-empty). clear: delete them. |
update_rowUpdate RowDestructiveIdempotentInspect
Update an existing row in a v2 app's collection (replaces its data). Pass if_match with the row's current version for an optimistic-locked update — on a version mismatch the relay returns the current row so you can retry. Returns { row }.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | The key of the row to update. | |
| data | Yes | The new row body (replaces the row's data) - any JSON value valid against the collection's row schema. | |
| app_id | Yes | The app id. | |
| if_match | No | Optional optimistic-lock version. On mismatch the update is rejected with the current row in details.current. | |
| collection | Yes | The collection name. |
upsert_rowUpsert RowDestructiveIdempotentInspect
Create a row in a v2 app's collection, or return the existing row if key is already present (deduped:true) — the ONLY create-shaped verb for app rows (no separate strict create). Omit key to add a new row (server-generates one); pass key to ensure a row exists at that key. The collection must be declared in the app's manifest with 'agent' allowed to write. Returns { row, deduped? }.
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | Optional stable key. Reusing an existing key returns the existing row (deduped:true). | |
| data | Yes | The row body - any JSON value valid against the collection's row schema (an object, or any JSON value for a schemaless collection). | |
| app_id | Yes | The app id. | |
| collection | Yes | The collection name. |
Claim this connector by publishing a /.well-known/glama.json file on your server's domain with the following structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"maintainers": [{ "email": "your-email@example.com" }]
}The email address must match the email associated with your Glama account. Once published, Glama will automatically detect and verify the file within a few minutes.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
No comments yet. Be the first to start the discussion!
Your Connectors
Sign in to create a connector for this server.