このMCPでできること
Deploys and manages multi-user web applications with hosted HTML, capability manifests, databases, authentication, permissions, attachments, webhooks, credentials, and app data operations.
ツール
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action'], 'properties': {'code': {'type': 'string', 'description': 'The one-shot claim code (required for claim).'}, 'action': {'enum': ['whoami', 'claim', 'logout'], 'type': 'string', 'description': "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: clears the locally-saved key/profile; the key is not revoked on the relay, which is what the key tool's revoke action does."}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action'], 'properties': {'slug': {'type': 'string', 'description': 'list only. Exact-match slug filter.'}, 'limit': {'type': 'integer', 'maximum': 200, 'description': 'list only. Page size.', 'exclusiveMinimum': 0}, 'action': {'enum': ['list', 'show', 'audit', 'update', 'share_link_rotate', 'delete', 'list_deleted', 'restore', 'purge', 'wake', 'domain_set', 'domain_status', 'domain_remove'], 'type': 'string', 'description': "list: the caller's owning human's apps. show/update/delete/wake: act on one app (app_id). audit: read-only security review of every app the caller owns. 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. list_deleted: the apps in the trash, each with when it is purged for good. restore: bring a deleted app back with all its data (app_id). purge: destroy a deleted app forever, now (app_id). domain_set/domain_status/domain_remove: manage the app's custom domains (app_id; domain_set also needs domain)."}, 'app_id': {'type': 'string', 'description': 'Required for show/update/share_link_rotate/delete/restore/purge/wake/domain_set/domain_status/domain_remove.'}, 'cursor': {'type': 'string', 'description': 'list only. Opaque cursor from a previous next_cursor.'}, 'domain': {'type': 'string', 'description': "domain_set: 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. domain_remove: optional, the one domain to unbind - omit it to unbind them all."}, 'status': {'enum': ['active', 'dormant', 'archived', 'suspended', 'all'], 'type': 'string', 'description': "list only. Default: active. 'all' means every live status; deleted apps are never in this list, use action list_deleted for those."}, 'severity': {'enum': ['high', 'medium', 'low'], 'type': 'string', 'description': "audit only. Return findings of this severity only. The response's `counts` always describe the whole audit, so filtering never hides that other findings exist."}, 'timezone': {'type': 'string', 'description': "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': {'enum': ['private', 'link', 'public'], 'type': 'string', 'description': 'update only. The new visibility (slug is immutable).'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action'], 'properties': {'mime': {'type': 'string', 'description': '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': {'type': 'boolean', 'description': 'mint_token: token self-deletes on first GET.'}, 'size': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'presign: the exact byte length you will PUT. Committed at presign and re-verified against the uploaded bytes at finalize.', 'exclusiveMinimum': 0}, 'limit': {'type': 'integer', 'maximum': 100, 'description': 'list page size (1..100).', 'exclusiveMinimum': 0}, 'scope': {'enum': ['agent', 'app'], 'type': 'string', 'description': 'upload scope (default agent).'}, 'action': {'enum': ['upload', 'fetch', 'presign', 'finalize', 'download', 'show', 'list', 'delete', 'mint_token', 'revoke_token', 'list_tokens'], 'type': 'string', 'description': "Binary attachment operations. The upload path affects token cost: `fetch` and presign plus finalize keep the bytes out of the model context entirely, while upload with `content_base64` carries them in the tool-call arguments at a cost proportional to file size, paid again on every retry. fetch takes { source_url, scope } and the relay downloads the bytes itself (https only, SSRF-guarded), running the same sniff, allowlist, size, quota and scan checks as any upload. upload takes `content_base64` (base64 bytes, no filesystem) or `file_path` (absolute, read on the relay host), scoped agent or app. presign plus finalize is three steps: presign with { mime, size, sha256, scope }, PUT the bytes to put_url out of band, then finalize, which re-sniffs and re-checks them. download fetches bytes by attachment_id to an absolute out_path or returns base64. show returns metadata only. list returns the agent's attachments. delete is a soft-delete. mint_token mints a /b/<token> capability URL, returned once. revoke_token and list_tokens manage those tokens."}, 'app_id': {'type': 'string', 'description': 'Required when scope=app.'}, 'cursor': {'type': 'string', 'description': 'list pagination cursor.'}, 'sha256': {'type': 'string', 'description': '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': {'type': 'string', 'description': "upload: display filename (defaults to the file's basename)."}, 'out_path': {'type': 'string', 'description': 'download: absolute path to write the bytes to. If omitted, the bytes are returned base64-encoded in the result.'}, 'token_id': {'type': 'string', 'description': 'revoke_token: the token id to revoke.'}, 'file_path': {'type': 'string', 'description': "upload: absolute path to a file read on the server host running this MCP connector (the relay), not the calling agent's machine. It resolves only when the file is local to the relay (e.g. a locally-run CLI); a hosted or remote agent supplies the bytes as `content_base64` instead."}, 'source_url': {'type': 'string', 'description': 'fetch: an https URL the relay downloads server-side, so the bytes do not enter the model context and cost no tokens. SSRF-guarded: https only, no private, loopback, link-local or metadata hosts, DNS pinned, redirects refused, size-capped and timed out. The downloaded bytes run the same byte-sniff, allowlist, size, quota and scan checks as any upload. This and presign plus finalize are the zero-context paths for real images and media.'}, 'ttl_seconds': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'mint_token: per-token TTL (clamped by scope default).', 'exclusiveMinimum': 0}, 'attachment_id': {'type': 'string', 'description': 'Attachment id. Required for download/show/delete/mint_token/revoke_token/list_tokens.'}, 'content_base64': {'type': 'string', 'description': 'upload: the file bytes as base64, sent inline with no filesystem access. 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 expensive, and the cost repeats on every retry. presign plus finalize avoids that for any real image or media whenever the client can do an out-of-band HTTP PUT, which leaves `content_base64` suited to small assets such as a tiny icon, and to 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 and quota checks as a file upload.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action'], 'properties': {'ref': {'type': 'string', 'description': "get_config_contract/install only. The template to read or install: a namespaced '<handle>/<slug>' or a community snapshot id."}, 'note': {'type': 'string', 'description': 'reject only. The required rejection note shown to the publisher (delivered to their app feed).'}, 'slug': {'type': 'string', 'description': 'publish only. Optional per-publisher slug (lowercase, 3 to 48 chars, hyphens). Gives the template a namespaced id <handle>/<slug>; a republish reuses the slug and must bump the version. If omitted, a slug is derived from the title instead of leaving the template unnamed, so this field matters only when a specific url is wanted. Slugs are immutable: renaming the template later does not move its url, so the slug chosen here is permanent.'}, 'tags': {'type': 'array', 'items': {'type': 'string'}, 'description': 'publish only. Up to 6 curation tags.'}, 'limit': {'type': 'integer', 'maximum': 200, 'description': 'list_pending only. Page size (1..200).', 'exclusiveMinimum': 0}, 'title': {'type': 'string', 'description': "publish only. Listing title (1 to 80 chars). Defaults to the app's manifest name."}, 'action': {'enum': ['publish', 'unpublish', 'get_config_contract', 'install', 'upgrade_check', 'upgrade', 'revert', 'list_pending', 'get_submission', 'approve', 'reject', 'set_trust_level'], 'type': 'string', 'description': "publish: publishes one of the caller's apps as a community template (app_id; optional title/description/category/tags). Privacy consequence: 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, so an app whose seedOnInstall collections hold real personal data (names, emails, addresses, messages, anything private) is not safe to publish: seed data must be example-only. attest_example_only:true records that this was checked. 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, and the response's expedited/auto_approved fields report which path it took. unpublish: takes one of the caller's own published templates back down (snapshot_id). It removes the listing from the public gallery, from search, and from the direct snapshot install link. Existing installs keep working untouched, because an install is a fresh private copy rather than a live reference. It is idempotent (unpublishing an already-unpublished template is a no-op), and a snapshot that does not exist or belongs to someone else reads as not found either way. Publishing a new version is what puts the listing back. 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-uploaded with the attachments tool (scope agent) and passed as its attachment id. A template installed with connect_steps provisions hook URLs, which the `ingest` tool's list action returns for the new app_id, ready to wire into the external service. install: installs a template by `ref` for the caller, whose owning human becomes the owner. `config` is { stepKey: value } from the contract: a 'config' step's value is a string, an 'upload' step's value is a pre-uploaded attachment id. An omitted required step 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').\n\nupgrade_check / upgrade / revert keep an already-installed app current with its source template (app_id). An install is a one-shot fork, so nothing updates on its own and there is no follow/pin: you have to ask. upgrade_check reports whether a newer live version of that app's template line exists, whether it would apply cleanly, and what it would newly be allowed to reach. upgrade applies it in place, keeping the app's address, collections and rows, and landing as a new version you can undo. It refuses outright, with no override, when the new version would strand rows the app already holds; when the new version merely asks for more than the installed one, pass accept_permissions:true, but only after showing the owner what `permission_lines` says. revert puts the app back on the version it ran before the last update, and refuses when rows written since would have nowhere to live under the older one."}, 'app_id': {'type': 'string', 'description': 'publish / upgrade_check / upgrade / revert. For publish, the app to publish. For the three upgrade actions, the installed app to act on: an installed template is a fork, so the question is whether a newer version of the template that app came from exists, which only the app can answer.'}, 'config': {'type': 'object', 'description': "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.", 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'cursor': {'type': 'string', 'description': 'list_pending only. Opaque cursor from a prior next_cursor.'}, 'handle': {'type': 'string', 'description': 'set_trust_level only. The @-handle of the publisher to promote or demote.'}, 'version': {'type': 'string', 'description': "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': {'type': 'string', 'description': "publish only. Optional single-word category (e.g. 'household')."}, 'description': {'type': 'string', 'description': 'publish only. Listing blurb (up to 200 chars). Defaults to the manifest description.'}, 'setup_steps': {'type': 'array', 'items': {'type': 'object', 'required': ['kind', 'label'], 'properties': {'key': {'type': 'string', 'description': "The settings-collection field this answer is written into (letters, digits, '_', up to 64 chars). Required for an 'upload' step, optional for a 'config' step, not allowed on the others. Must name a declared top-level field of the manifest's x-homespun-manifest.settingsCollection; an 'upload' target must be a string-typed field."}, 'kind': {'enum': ['config', 'seed-data', 'connect', 'note', 'upload'], 'type': 'string', 'description': 'config = set a value; upload = an install-time file/image the app stores as an attachment id; connect = wire up an external data source; seed-data = review/replace captured starter data; note = a plain instruction.'}, 'label': {'type': 'string', 'description': 'Short step label (<= 80 chars).'}, 'secret': {'type': 'boolean', 'description': 'Mark a step whose value is sensitive (an API key/token). Its default is MASKED on the public detail page; publish only your own example default, never a real secret.'}, 'choices': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional list of allowed values (up to 12).'}, 'default': {'type': 'string', 'description': 'Optional example/default value (<= 200 chars).'}, 'required': {'type': 'boolean', 'description': 'Whether this step is required (default false).'}, 'valueHint': {'type': 'string', 'description': 'Optional format hint (<= 120 chars).'}, 'ingestRule': {'type': 'string', 'description': "The manifest `ingest` rule this step wires up. Allowed only on a 'connect' step, and optional there; publish rejects a name that x-homespun-manifest.ingest does not declare. Each install mints that rule its own hook URL, which the installer pastes into the external service."}, 'description': {'type': 'string', 'description': 'Optional longer instruction (<= 300 chars).'}}}, 'description': "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': {'type': 'string', 'description': "Required for get_submission/unpublish/approve/reject. The submission's snapshot id (from publish's response or list_pending)."}, 'trust_level': {'enum': ['new', 'established'], 'type': 'string', 'description': "set_trust_level only. 'established' fast-tracks the publisher's future submissions through review; 'new' reverts to full review."}, 'changelog_note': {'type': 'string', 'description': "publish only. A short note recorded in this version's changelog."}, 'expect_version': {'type': 'string', 'description': 'upgrade only. The version upgrade_check reported. When given, the upgrade is refused if the offer has moved since, so a publisher shipping again mid-flight cannot slip a version past you that you never showed anyone.'}, 'long_description': {'type': 'string', 'description': '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.'}, 'accept_permissions': {'type': 'boolean', 'description': 'upgrade only. Required when upgrade_check reports a non-empty `permissions` diff, meaning the new version asks for more than the installed one (new hosts it can send data to, new device capabilities, a service worker, CDN scripts). Never assume it: show the owner `permission_lines` and set this only once they have agreed. It does not clear a version that would strand rows, which nothing can.'}, 'attest_example_only': {'type': 'boolean', 'description': "publish only. True attests 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 the app's 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': {'type': 'string', 'description': 'publish only. Optional remix/fork lineage: the snapshot id this template was derived from.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action', 'app_id'], 'properties': {'kind': {'enum': ['static', 'oauth2'], 'type': 'string', 'description': 'create only. Defaults to `static`.'}, 'name': {'type': 'string', 'description': "create / delete / consent_url. The connection name (lowercase, starting alphanumeric, up to 64 chars) that a manifest webhook rule's `connection` field references."}, 'label': {'type': 'string', 'description': 'create only. Optional owner-facing label.'}, 'action': {'enum': ['create', 'list', 'delete', 'consent_url'], 'type': 'string', 'description': "create: store a webhook connection, a stored credential (static header token or a full generic OAuth2 client) a manifest webhook rule authenticates its target with (app_id+name+allowed_host, plus kind-specific fields). list: the app's connections as metadata plus a non-reversible fingerprint, never any secret (app_id). delete: idempotent (app_id+name). consent_url: build (never fetch) the browser URL that completes an oauth2 connection's owner consent (app_id+name); hand it to the signed-in owner to open, since an agent key cannot complete OAuth consent itself."}, 'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'scopes': {'type': 'string', 'description': 'create only (oauth2). Space-delimited scopes for the authorize request.'}, 'provider': {'type': 'string', 'description': 'create only. Freeform display label only, e.g. "hubspot"; not validated against any allowlist.'}, 'client_id': {'type': 'string', 'description': "create only, required for kind=oauth2. Your OAuth2 app's client id."}, 'auth_params': {'type': 'object', 'description': 'create only (oauth2). Extra key/values merged into the authorize redirect (e.g. to request offline access).', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'auth_scheme': {'type': 'string', 'description': 'create only (oauth2). The scheme the access token is sent under. Defaults to "Bearer"; set e.g. "Zoho-oauthtoken" for a non-Bearer provider.'}, 'header_name': {'type': 'string', 'description': 'create only (static). The header the credential rides in. Defaults to "Authorization".'}, 'allowed_host': {'type': 'string', 'description': 'create only, required for both kinds. The host-binding exfiltration defence: an exact DNS host ("api.hubapi.com") or a single leftmost wildcard ("*.zohoapis.com"). The stored credential is attached to a delivery only when its url host matches; a rule later repointed elsewhere fails delivery rather than sending the secret to the wrong host.'}, 'header_value': {'type': 'string', 'description': 'create only, required for kind=static. The header value to send, e.g. "Bearer sk_live_...". Encrypted at rest and never returned by any call.'}, 'token_params': {'type': 'object', 'description': 'create only (oauth2). Extra key/values merged into the token POST.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'authorize_url': {'type': 'string', 'description': "create only, required for kind=oauth2. The provider's OAuth2 authorize endpoint (https; rejected if it resolves to a private/loopback/metadata address)."}, 'client_secret': {'type': 'string', 'description': "create only, required for kind=oauth2. Your OAuth2 app's client secret. Encrypted at rest and never returned by any call."}, 'instance_field': {'type': 'string', 'description': 'create only (oauth2). The name of a token-response JSON field holding the API base URL (e.g. "instance_url"). When set, the relay re-binds allowed_host to that host after consent and resolves relative rule urls against it.'}, 'token_endpoint': {'type': 'string', 'description': "create only, required for kind=oauth2. The provider's OAuth2 token endpoint (same https + SSRF rules as authorize_url)."}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['app_id', 'collection'], 'properties': {'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'collection': {'type': 'string', 'minLength': 1, 'description': "The collection name declared in the app's manifest."}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action', 'app_id'], 'properties': {'mode': {'enum': ['explicit', 'following'], 'type': 'string', 'description': "mint only. Defaults to explicit: an unnamed collection is denied, so the credential can never reach anything it was not handed (the shape for a contractor's backend). following: an unnamed collection falls through to the owner's own authority, so the credential tracks the app as it grows and each `grants` entry only narrows one collection (the shape for the owner's own backend). Neither mode can ever exceed what the app's owner could do; the effective permission is always the intersection."}, 'label': {'type': 'string', 'description': 'mint only. Optional owner-facing label shown in the credential list.'}, 'action': {'enum': ['mint', 'list', 'pause', 'resume', 'rotate', 'revoke'], 'type': 'string', 'description': "mint: create a scoped service credential, the bearer token an app owner points a backend they host themselves at (app_id; optional mode/grants/members/label/ttl_seconds). list: the app's credentials, their allowlist and status, never a token (app_id). pause: reversibly stop one, in force on its very next request (app_id+credential_id). resume: undo a pause; never undoes a revoke, which is permanent (app_id+credential_id). rotate: issue a fresh token and keep the old one working for an overlap window so a running backend picks it up without a gap (app_id+credential_id; optional overlap_seconds). revoke: kill one permanently and idempotently (app_id+credential_id)."}, 'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'grants': {'type': 'array', 'items': {'type': 'object', 'required': ['collection', 'ops'], 'properties': {'ops': {'type': 'array', 'items': {'enum': ['read', 'create', 'update', 'delete'], 'type': 'string'}}, 'scope': {'type': 'string', 'const': 'own', 'description': 'Narrows every row-addressed op to rows this credential itself wrote last. Inert for create.'}, 'collection': {'type': 'string', 'minLength': 1}}}, 'description': 'mint only. The allowlist: one entry per collection naming which of read/create/update/delete this credential may attempt there (an entry may name zero ops, which under `following` is how one collection is carved out of an otherwise app-wide credential). A collection named here must be a real declared collection on the app; a typo is rejected with a 400 rather than silently doing nothing.'}, 'members': {'type': 'boolean', 'description': "mint only. Opt in to the app's member directory appearing in this credential's boot/hello payloads. Defaults to false: a credential that never learns a member id cannot stamp one into a relation field."}, 'ttl_seconds': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}, {'type': 'null'}], 'description': "mint only. Omit for the server's bounded default (365 days, clamped to a server maximum). null means no expiry, the explicit opt-in a long-running backend asks for; it is never the default."}, 'credential_id': {'type': 'string', 'description': "pause / resume / rotate / revoke. The credential id (see list's `id` field)."}, 'overlap_seconds': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'rotate only. How long the superseded token keeps resolving, so a running backend can pick up the new one with no gap. Defaults to the server default (1 day); 0 kills the old token immediately, the "this leaked" case.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['app_id', 'collection', 'key'], 'properties': {'key': {'type': 'string', 'minLength': 1, 'description': 'The key of the row to delete.'}, 'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'if_match': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Optional optimistic-lock version.'}, 'collection': {'type': 'string', 'minLength': 1, 'description': 'The collection name.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'properties': {'html': {'type': 'string', 'minLength': 1, 'description': "The app's UI as a complete HTML document (single file, with CSS and JS inline), sent inline. Capped at 2 MB of UTF-8; over that the deploy is refused with 413 document_size_exceeded. A document near the cap is almost always carrying a file inlined as a data: URI; the same file in `assets[]` is served from the app's own origin, cached separately, and does not count toward this cap. The document comes from this field, `html_path`, or `document_id`. Inline is the only form a hosted or remote connector can use unless it uploads through `document_upload`; when no `document_id` is given and both `html` and `html_path` are present, inline `html` wins. On a redeploy an omitted `html` keeps the live document, so a manifest-only change (adding a collection, widening externalHosts) costs nothing in HTML."}, 'slug': {'type': 'string', 'description': "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': {'type': 'boolean', 'description': 'Alias for `dry_run`.'}, 'force': {'type': 'boolean', 'description': 'Redeploy only. Bypasses the compat gate, whether it fired on a stranded-rows narrowing or on a widening of what the install screen discloses (a removed collection is detached, never deleted).'}, 'app_id': {'type': 'string', 'description': "Omit to create a new app; pass an existing app's id to redeploy it (a new version, compat-gated unless force:true)."}, 'assets': {'type': 'array', 'items': {'anyOf': [{'type': 'object', 'required': ['path', 'content_base64'], 'properties': {'mime': {'type': 'string', 'description': "Advisory content-type. The relay sniffs the REAL type from the bytes and enforces the attachment allowlist; omit it (or set application/octet-stream) for data files like CSV that don't magic-byte-sniff, so they are stored + served as an inert download."}, 'path': {'type': 'string', 'description': "App-relative, same-origin reference the HTML uses, for example 'frames/000.jpg' or 'media/intro.mp4'. Must be relative: no leading '/', no '..' segment, no backslash, charset [A-Za-z0-9._/-], and not under a reserved prefix (_hs, b)."}, 'content_base64': {'type': 'string', 'description': "Standard base64 of the asset's raw bytes."}}}, {'type': 'object', 'required': ['path', 'attachment_id'], 'properties': {'path': {'type': 'string', 'description': 'App-relative, same-origin reference the HTML uses (same rules as the inline form).'}, 'attachment_id': {'type': 'string', 'description': 'Id of an ALREADY-uploaded attachment to bind at this path, instead of carrying base64. Use with `attachments fetch` (URL, zero model-context cost) or presign + finalize: the attachment must be owned by YOU, app-scoped to THIS app (upload it with scope=app, app_id=this app), and ready. Skips decode/upload; the deploy just maps path -> attachment_id.'}}}]}, 'description': '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`; the reference form suits real images and media, where the file is uploaded once via `attachments fetch` or presign and then bound 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. On a redeploy, sent assets replace the previous version\'s set, an omitted `assets` keeps the live set (no re-upload, no re-encoding), and `assets: []` is the explicit way to clear it. Bounded by the relay\'s per-deploy asset-count cap; total bytes by the per-app blob quota.'}, 'dry_run': {'type': 'boolean', 'description': '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 redeploy the compat gate would refuse reports the break instead of applying it. `check` is an accepted alias.'}, 'manifest': {'type': 'object', 'description': "The x-homespun-manifest capability document (a JSON object). Required to create; on a redeploy an omitted `manifest` keeps the live one, which fits most redeploys (the manifest was byte-identical to the previous version in 71% of real redeploys). The extension keys used most often: app metadata; collections (+ per-collection write/update/read/delete role lists, where write gates creates and also updates unless the optional update list is declared); 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); agentTasks (queue work for an agent on the owner's own machine, described as a prompt). The full grammar is documented in the Homespun guide that get_skill returns.", 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'html_path': {'type': 'string', 'description': "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 the CLI host for a locally-run one), not on the remote agent's machine. An alternative to inline `html` that avoids retransmitting a large HTML file on every deploy. It resolves only when the file is local to the MCP server, so it serves a locally-run connector rather than a hosted or remote one, where the path does not exist and the call returns a clean error; inline `html` is the form that works there. If both `html` and `html_path` are given, inline `html` wins."}, 'visibility': {'enum': ['private', 'link', 'public'], 'type': 'string', 'description': "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`."}, 'document_id': {'type': 'string', 'description': 'Reference returned by `document_upload` after you PUT the exact UTF-8 HTML bytes to its upload_url with `Authorization: Bearer <upload_token>`. Mutually exclusive with `html` and `html_path`. Use this for sandbox-authored files when the shell can reach the upload URL; the scoped upload token is not a Homespun account key.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['size', 'sha256'], 'properties': {'size': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'UTF-8 byte length of the HTML document.', 'exclusiveMinimum': 0}, 'app_id': {'type': 'string', 'description': 'Existing app id when this upload is for a redeploy; omit for a create.'}, 'sha256': {'type': 'string', 'pattern': '^[a-fA-F0-9]{64}$', 'description': 'SHA-256 hex digest of the exact UTF-8 HTML bytes to upload.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action'], 'properties': {'type': {'enum': ['bug', 'feature', 'note'], 'type': 'string', 'description': 'Feedback category (required for create).'}, 'limit': {'type': 'integer', 'maximum': 100, 'description': 'list page size (default 50, max 100).', 'exclusiveMinimum': 0}, 'action': {'enum': ['create', 'list'], 'type': 'string', 'description': "Reports a problem with homespun itself to the relay operator. create: files one bug|feature|note with a message and an optional app_id. list: this agent's own submissions, newest first, which is what distinguishes a new failure from one already reported."}, 'app_id': {'type': 'string', 'description': 'Optional app this feedback relates to (create).'}, 'before': {'type': 'string', 'description': "list cursor from a prior page's next_before."}, 'message': {'type': 'string', 'description': 'Message body (required for create).'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['app_id'], 'properties': {'wait': {'type': 'integer', 'maximum': 30, 'minimum': 0, 'description': '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': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'Max entries per page (capped server-side by FEED_PAGE_MAX).', 'exclusiveMinimum': 0}, 'since': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': "Opaque numeric cursor from a previous call's cursor. Omit (or 0) to read from the beginning."}, 'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['app_id', 'collection', 'key'], 'properties': {'key': {'type': 'string', 'minLength': 1, 'description': 'The key of the row to fetch.'}, 'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'collection': {'type': 'string', 'minLength': 1, 'description': 'The collection name.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'properties': {'version_only': {'type': 'boolean', 'description': "If true, return only the relay's current skill version string instead of the full SKILL.md markdown."}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action', 'app_id'], 'properties': {'mode': {'enum': ['once', 'multi'], 'type': 'string', 'description': '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': {'type': 'string', 'description': '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': {'type': 'string', 'description': 'mint only. Optional owner label shown in the grant list.'}, 'action': {'enum': ['mint', 'list', 'revoke'], 'type': 'string', 'description': "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': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'grant_id': {'type': 'string', 'description': "revoke only. The grant link id (see list's `id` field)."}, 'max_uses': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'mint only (multi mode). Cap total claims; omit for unlimited within expiry. Ignored for once (forced to 1).', 'exclusiveMinimum': 0}, 'pin_where': {'type': 'array', 'items': {}, 'description': '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': {'type': 'string', 'description': 'mint only. Optional narrowing pin to a single row key. Narrows within the role (never widens). Mutually exclusive with pin_where.'}, 'ttl_seconds': {'type': 'integer', 'maximum': 9007199254740991, 'description': 'mint only. Grant lifetime in seconds; defaults to the server default (30 days) and is clamped to the server max.', 'exclusiveMinimum': 0}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action', 'app_id'], 'properties': {'name': {'type': 'string', 'description': "rotate / set_signing_secret / clear_signing_secret. The manifest ingest hook name (an x-homespun-manifest.ingest[].name). See list's `name` field."}, 'action': {'enum': ['list', 'rotate', 'set_signing_secret', 'clear_signing_secret'], 'type': 'string', 'description': "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': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'secret': {'type': 'string', 'description': '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': {'type': 'number', 'description': '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).'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action'], 'properties': {'action': {'enum': ['list', 'revoke', 'mint'], 'type': 'string', 'description': "The calling agent's API key. list: key info (agent_id, key_prefix, timestamps). mint: mints a sibling API key for the calling agent's own identity (same scope/ownership) and returns its raw value once, which is what hands 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-destructs the agent's own key, which stops working immediately and is irreversible (requires confirm:true)."}, 'confirm': {'type': 'boolean', 'description': 'Required (true) for revoke.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['app_id', 'collection'], 'properties': {'limit': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Max rows to return (default 100).'}, 'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'before': {'type': 'string', 'description': "Cursor for the next page: pass back the previous page's next_before."}, 'collection': {'type': 'string', 'minLength': 1, 'description': 'The collection name.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['app_id', 'collection'], 'properties': {'limit': {'type': 'integer', 'maximum': 1000, 'description': 'Page size.', 'exclusiveMinimum': 0}, 'since': {'type': 'string', 'description': "Opaque cursor from a previous call's next_cursor. Also the poll handle: pass it back to fetch only newer/changed rows."}, 'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'collection': {'type': 'string', 'minLength': 1, 'description': "The collection name declared in the app's manifest."}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action', 'app_id'], 'properties': {'role': {'enum': ['member'], 'type': 'string', 'description': "add only. Defaults to 'member' server-side â\x80\x94 no other role is assignable via this API (ownership transfer is not available here)."}, 'email': {'type': 'string', 'description': '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': {'enum': ['add', 'list', 'set_role', 'remove', 'roles'], 'type': 'string', 'description': "add: invite-or-attach a member by email (app_id+email; optional custom_roles). list: the app's owner + members (app_id). set_role: replace an existing member's declared roles in place without signing them out (app_id+human_id+custom_roles, an empty list to clear). remove: drop a member (app_id+human_id). roles: the app's declared roles with what each one includes and, 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': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'human_id': {'type': 'string', 'description': "remove and set_role. The Human id to target â\x80\x94 see list's `humanId` field. The app owner can be neither removed nor re-roled."}, 'custom_roles': {'type': 'array', 'items': {'type': 'string'}, 'description': 'add (optional) and set_role (required). The declared roles (x-homespun-manifest.roles keys) attached to the member alongside their base member powers. A member may hold several and holds the union of what each grants, plus everything those roles `includes`. A built-in/reserved role or an undeclared role is rejected. Omit on add for an ordinary member; pass [] on set_role to clear the roles back to a plain member.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action'], 'properties': {'bio': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'description': 'update only. Short public bio (up to 500 chars); null clears it.'}, 'url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'description': 'update only. Public http(s) URL (up to 200 chars); null clears it.'}, 'action': {'enum': ['claim', 'get', 'update'], 'type': 'string', 'description': "get: returns the caller's publisher profile (handle, tenure, counters). claim: sets the caller's @-handle, once (handle arg; lowercase, 3 to 32 chars, permanent after claiming; needs a verified email). update: changes the caller's public display_name/bio/url (any of them; needs a verified email)."}, 'handle': {'type': 'string', 'description': 'claim only. The lowercase @-handle to claim (^[a-z0-9](?:[a-z0-9-]{1,30}[a-z0-9])$). Permanent once claimed.'}, 'display_name': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'description': 'update only. Public display name (up to 80 chars); null clears it.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['app_id', 'collection', 'key'], 'properties': {'key': {'type': 'string', 'minLength': 1, 'description': 'The key of the deleted row to restore.'}, 'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'collection': {'type': 'string', 'minLength': 1, 'description': 'The collection name.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action'], 'properties': {'body': {'type': 'string', 'description': 'create only. Optional written review (up to 2000 chars).'}, 'slug': {'type': 'string', 'description': 'create only. Per-publisher slug (with `handle`).'}, 'stars': {'type': 'integer', 'maximum': 5, 'minimum': 1, 'description': 'create only. Star rating, an integer 1 to 5.'}, 'action': {'enum': ['create', 'respond', 'report', 'remove', 'unhold'], 'type': 'string', 'description': 'create: leaves a star rating (1..5) and optional body on a community template the caller has installed (identified 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: replies to a review of one of the caller\'s own templates (review_id + response; null clears it). report: flags 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': {'type': 'string', 'description': 'create only. Publisher handle (with `slug`), an alternative to `template`.'}, 'reason': {'type': 'string', 'description': 'report only. Why you are reporting this review (up to 500 chars).'}, 'response': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'description': "respond only. The publisher's public response (up to 2000 chars); null clears it."}, 'template': {'type': 'string', 'description': 'create only. The namespaced template id <handle>/<slug> to review.'}, 'review_id': {'type': 'string', 'description': "Required for respond/report/remove/unhold. The review's id."}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action'], 'properties': {'taste': {'type': 'string', 'description': 'The full markdown notes (required for set; whole-document replace, not append).'}, 'action': {'enum': ['get', 'set', 'clear'], 'type': 'string', 'description': "The agent's freeform UI taste notes (markdown) â\x80\x94 presentation preferences learned from human feedback. get: read them before generating an app. set: whole-document replace (taste, non-empty). clear: delete them."}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['action', 'app_id'], 'properties': {'email': {'type': 'string', 'description': 'start only. The email to offer ownership to. The relay sends that address an accept link; ownership moves only when they open it and accept, never at start itself. 409s if a transfer is already pending for this app, or if the email already owns it.'}, 'action': {'enum': ['start', 'status', 'cancel'], 'type': 'string', 'description': "A v2 app's ownership transfer (issue #1847). start does not move ownership: it only mints a pending offer and emails the named person an accept link, and the app stays owned here until they open it and accept (app_id+email; optional keep_as_member). status: the app's pending transfer, or null if none is pending (app_id). cancel: withdraw a pending transfer; idempotent, so cancelling with none pending is still a success (app_id)."}, 'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'keep_as_member': {'type': 'boolean', 'description': 'start only. Whether the current owner stays on as an ordinary member once the transfer is accepted, losing owner powers but keeping app access. Defaults to true. Has no effect unless and until the transfer is actually accepted.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['app_id', 'collection', 'key', 'data'], 'properties': {'key': {'type': 'string', 'minLength': 1, 'description': 'The key of the row to update.'}, 'data': {'anyOf': [{'type': 'object', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, {'type': 'array', 'items': {}}, {'type': 'string'}, {'type': 'number'}, {'type': 'boolean'}, {'type': 'null'}], 'description': "The new row body (replaces the row's data) - any JSON value valid against the collection's row schema."}, 'app_id': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'if_match': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Optional optimistic-lock version. On mismatch the update is rejected with the current row in details.current.'}, 'collection': {'type': 'string', 'minLength': 1, 'description': 'The collection name.'}}}
入力スキーマ
{'type': 'object', '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['app_id', 'collection', 'data'], 'properties': {'key': {'type': 'string', 'description': "Optional stable key. Reusing an existing key returns the existing row (deduped:true), or row_not_found when the collection's read list does not reach that row for the caller."}, 'data': {'anyOf': [{'type': 'object', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, {'type': 'array', 'items': {}}, {'type': 'string'}, {'type': 'number'}, {'type': 'boolean'}, {'type': 'null'}], 'description': "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': {'type': 'string', 'minLength': 1, 'description': 'The app id.'}, 'collection': {'type': 'string', 'minLength': 1, 'description': 'The collection name.'}}}
最近のツール変更
類似のMCPサーバー
shiply
Publishes and manages web applications with SQL databases, serverless functions, domains, email tests, client intake, contracts, …
Fine Structure
Builds and hosts full-stack applications from prompts and supports agent communication through WhatsApp and email.
mcp
Provisions and manages cloud instances, networks, storage, databases, backups, VPNs, application deployments, and autocoding-agen…
EchoRelay
Manages a hosted API relay runtime, including projects, endpoints, credentials, publishing, keys, delivery logs, and dead-letter …
Supero
Builds, validates, publishes, tests, and deploys multi-tenant applications with schemas, CRUD operations, external data connector…
Replicate
Provides access to Replicate models, versions, collections, hardware, predictions, and deployments for running and managing hoste…
Relin
Configures webhook sources and destinations, monitors delivery health, investigates failures, manages retries, and replays events.
Scalix Cloud
Provides managed databases, SQL tools, container builds, persistent Linux machines, domains, scheduled functions, storage, and pr…