mcp

mcp is an agent for coding agents from markpasternak/canvas-drop. It costs 0 tokens per session (4,124 once invoked), scanned A, original, MIT.

An account-level connection for Model Context Protocol (MCP), a standard that lets AI assistants use external tools. It lets an MCP-capable assistant sign in and work with canvases on a canvas-drop instance.

In plain words
What is it for?
Use it to connect an AI assistant to canvas-drop, then create, deploy, and manage canvases and verify deployments.
Why use it?
It removes the need to paste an API key or manage a separate account. The assistant can use your signed-in identity across the canvases you own.

Agent

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add agents/markpasternak/canvas-drop/mcp
Clone the repo
git clone --depth 1 https://github.com/markpasternak/canvas-drop

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for mcp

README.md
[![agentmods](https://agentmods.dev/badge/agents/markpasternak/canvas-drop/mcp.svg)](https://agentmods.dev/agents/markpasternak/canvas-drop/mcp)
Your own site
<a href="https://agentmods.dev/agents/markpasternak/canvas-drop/mcp"><img src="https://agentmods.dev/badge/agents/markpasternak/canvas-drop/mcp.svg" alt="Measured on agentmods" height="20"></a>
Per session 0 Only the description is in the session, so the agent can decide to use it. The body loads when it is invoked.
When invoked 4,124 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 1 finding. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00000 $0.04124
Opus 5 $0.00000 $0.02062
Sonnet 5 $0.00000 $0.00825
Haiku 4.5 $0.00000 $0.00412

Measured 3d ago against content hash c42000adaed5, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

mcp scanned grade A with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 3d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Makes network callslowCapability

Not a fault in itself. Listed so you know the mod talks to something, and to what.

| `create_canvas` | Create a canvas; returns its id, URL, a one-time deploy key, and a `deploy` block of ready-to-run curl endpoints (so you never probe for the API host). Optional `orgId` homes it in an org you belong t
docs/site/agents/mcp.md · 185 lines

How it starts

The opening of the file, as written. The whole thing — 185 lines — stays where its author put it; the contents beside it link to each section on GitHub.

MCP server

canvas-drop exposes a remote Model Context Protocol endpoint so an MCP-capable agent host (Claude, ChatGPT, …) can connect once and then create, deploy, and manage the canvases you own — with no API key to paste. It is the identity-scoped companion to the keyed Deploy API: the Deploy API acts on one canvas with its secret key; MCP acts across your whole account as you.

Connect

Add the instance's MCP endpoint to your client:

{base}/mcp

On first use the client runs an OAuth 2.1 sign-in: it discovers the authorization server (RFC 8414/9728 .well-known metadata), registers itself automatically (Dynamic Client Registration), and opens a browser to this instance's normal login (the same org sign-in you use for the dashboard). No second account, no secret to copy. canvas-drop is its own authorization server — it does not proxy your IdP. In oidc mode an unauthenticated agent is bounced through the usual login; in proxy/dev mode identity is already resolved. The client stores the resulting access token (1h TTL) and refreshes it automatically (refresh tokens rotate on use).

Identity always comes from that server-side sign-in — never from anything the client asserts. The email-domain allowlist is enforced before any token is issued, and every tool call re-checks that your account is still active, so a block or de-allowlist kills a live token on the next request.

Tools

Owner-management tools are scoped to your account. A canvas you don't own reads as not found — there is no cross-owner owner-surface access and no existence leak. Identity-scoped discovery tools are explicit exceptions: list_shared_canvases returns only non-owned canvases you can already open and whose owner made them discoverable in Shared.

Tool What it does
whoami The connected account (id, email, name). When an org boundary is configured, also orgs ([{id, name}] you're a member of), teams (the teams you belong to), and isGuest (true = signed in but in no org) — use an org id as create_canvas's orgId.
list_canvases The canvases you own. Optional query filter — a forgiving text search over title, description, tags, and slug (case/accent/whitespace-insensitive; multiple words are AND-ed) — an optional tags filter (any-match — canvases carrying any of the given tags), plus sort (updated default, or created/title/popular), and limit (1–100, default 50). sort=popular ranks by trending views (last 30 days); every item carries recentViews (that 30-day count) plus lifetime viewCount and lastViewedAt.
create_canvas Create a canvas; returns its id, URL, a one-time deploy key, and a deploy block of ready-to-run curl endpoints (so you never probe for the API host). Optional orgId homes it in an org you belong to (from whoami.orgs) so it can be shared org-wide; omit or null for a personal canvas. Only meaningful when an org boundary is configured.
get_canvas Current state of a canvas you own (includes lifetime viewCount + lastViewedAt; full stats via get_canvas_usage).
list_versions Version history of a canvas you own (number, source, status, createdAt, fileCount, totalBytes, current, downloadUrl).
delete_version Permanently delete one non-current ready version. The current version and disabled canvases are protected; shared draft/version blobs are retained.
deploy_canvas Publish static files directly to live in one call — pass either a base64-encoded ZIP (zipBase64) or a files array (text as UTF-8, binary as base64).
begin_deploy Open a staged upload from a file manifest (path, sha256, size); returns an uploadId and the subset of hashes you still need to send.
add_files Stage files into an open upload (text as UTF-8, binary as base64); call repeatedly to chunk a large set.
finalize_deploy Publish a new version from a staged upload. Single-use.
get_canvas_file Read back what's live: list the current version's files, or fetch one file's content. Use it to verify a deploy (the live URL is sign-in gated — see below).
rollback_canvas Point a canvas back at an earlier version number (must be a ready version).
unpublish_canvas Take a published canvas back to draft.
set_capabilities Toggle a canvas's backend capabilities — backendEnabled is the master switch; kv/files/ai/realtime are individual features (effective only when backend is on). Omitted fields are unchanged.
set_canvas_slug Change a canvas's URL slug (pass a custom one, or omit for a fresh random slug). The old URL stops working immediately.
regenerate_deploy_key Mint a new cd_… deploy key and invalidate the old one; the new key is returned once.
archive_canvas Archive a canvas (reversible) — takes its URL offline and revokes any retained legacy guest sessions for that canvas.
unarchive_canvas Restore an archived canvas back to active.
delete_canvas Soft-delete a canvas — it loses its URL and is purged after the retention window. Blocked if an admin has disabled the canvas. Not reversible from MCP.
update_canvas Update settings/sharing (Settings + Share tabs): title, description, access rung (private/specific_people/team/whole_org/public_link), discoverability (link_only or listed for Team / Whole-org shares; affects listing only, never URL access), password (or null to clear), sharedExpiresAt, spaFallback, previewMode (auto/off — the cover toggle; upload a custom image with set_canvas_preview), gallery listing/metadata, tags (the canvas's unified tag set — owner-list filtering and public gallery display; max 20, 50 chars each), and retained legacy guest-session AI settings where present. Setting galleryListed: true on a Whole-org canvas also sets discoverability: "listed", making it discoverable in Shared and in that organization’s gallery in one call. To share with teams, set access: "team" and teamIds (≥1 team you belong to — see list_teams; personal teams can be granted to any canvas you own, while org teams must match the canvas org); add discoverability: "listed" when team members should find it in Shared. Switching off team clears the grants. Server enforces the preconditions (sharing/listing need a published canvas; public_link needs the instance switch on and the owner account not revoked; a password un-lists).
set_canvas_preview Set or clear a canvas's custom cover image (the dashboard's preview upload). Pass image (base64 png/jpeg/webp) to pin it as the cover (previewMode becomes custom, so a publish never overwrites it); omit image to clear it back to auto.
list_access List active named people plus pending sign-in grants for a canvas you own (each with an id for revoke_access; legacy guest rows can still appear during migration).
search_people Search eligible people for the Add person picker, scoped to a canvas you own or a team you can see. This mirrors the dashboard autocomplete and does not expose the admin People directory.
grant_access Add a person by email. Existing users are granted now (status: granted); admissible new emails become pending auth-delegated grants (status: pending). No app-owned credential is created. Takes effect on the specific_people rung.
invite_to_canvas Compatibility alias for adding a person and sending the access email when email is enabled. Prefer grant_access for new agent flows; both use the same Add person service and statuses. A brand-new external email is refused for a non-admin (NOT_PERMITTED) unless the instance allows it; RATE_LIMITED past the cap.
revoke_access Remove an active person, pending sign-in grant, or legacy guest row. Legacy guest sessions are revoked when present.
clone_canvas Clone a canvas into a new one you own — any active canvas you own, or a gallery template someone shared. Starts as an unpublished draft with a fresh slug + key.
get_canvas_usage Usage stats: views + 30-day sparkline, and (backend-on) KV/file/AI/realtime op counts, storage, AI tokens/cost.
list_teams The teams you belong to, each with mine (you're a member) and canManage (you created it — so you can rename/delete it).
create_team Create a team. Omit orgId for a personal team (friends & family — add people by email when policy allows it); pass an orgId from whoami.orgs to attach it to that org. You become its first member and manager.
rename_team / delete_team Rename or delete a team you created. Deleting unshares every canvas shared with it (the canvases are untouched).
add_team_member / remove_team_member Add someone to a team you belong to by email, or remove a member (pass your own user id to leave). Returns status: granted (existing user joined now) or pending (a brand-new person joins on first sign-in). For an org team they must be a same-org member; a brand-new external email on a personal team is refused for a non-admin unless the instance allows it.
list_team_members The roster of a team you belong to: active members (userId, email, name) plus pending invite rows (id, email, invitedAt) for people who haven't signed in yet.
cancel_team_invite Cancel a pending invite on a team you belong to — the self-serve mirror of add_team_member (take back a typo'd email without an admin). Pass the pending row's id from list_team_members.
list_shared_canvases Non-owned canvases discoverable to you in Shared: direct Specific-people grants, listed Team shares, and listed Whole-org shares. Takes optional query, sort (updated/title/owner), limit, and offset. Display-only; open via the returned url.
get_draft The editor draft of a canvas you own — file list + state (dirty = differs from live). Creates it from the live version on first open.
read_draft_file Read one draft file's content (text UTF-8 / binary base64).
write_draft_file Write/replace a draft file (create: true refuses to overwrite).
delete_draft_file Delete a draft file.
rename_draft_file Rename/move a draft file.
publish_draft Publish the draft as a new live version (the editor's Publish).
restore_draft Reset the draft to a published version's files (the editor's Restore).

Read the full file on GitHub · 185 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 3d ago First seen · 185 lines · 0 tokens per session scan A c42000adaed5

Subscribe to this mod's changes

mcp is an agent published in the GitHub repository markpasternak/canvas-drop (7 stars, last pushed 21d ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 4,124 tokens. A static security scan graded it A with 1 finding (makes network calls). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.