MCP App Store
by KeenEthics

Overview

Connect your Bloom account with browser OAuth, inspect canvas work, make changes, and collaborate through comments. Bloom requires an account with early access.

Tools

begin_canvas_work

ChatGPT
Declare intended frame creations or updates so collaborators see progress on the canvas. Returns canvasActivityId and the resolved page ID/name. The activity ID associates later frame writes with this presentation state. Activities expire after inactivity and do not grant write permission. Scope: canvas:write.

begin_file_upload

ChatGPT
Start putting a file from the user's machine into Bloom Files. Bytes never go through MCP: this returns uploadId and a signed upload { url, headers, expiresAt } valid for 15 minutes. PUT the file's exact bytes there with every listed header (for example curl -X PUT --data-binary @file with each header), then call commit_file_upload. Storage refuses bytes whose SHA-256 or size differ from what you declared. Scope: project:write.

browse_frame

ChatGPT
Inspect a Bloom canvas frame or interact with its private browser. Without commands/time, returns the current shared capture's status and, when ready, a one-hour image URL, dimensions and source contentHash. pending includes retryAfterMs; failed includes failure.code/message. render_content identifies defective frame code; infrastructure and timeout failures identify incomplete observations. One-shot capture has a 1500ms browser budget. retry requests another failed observation. With commands/time, clicks, typing and playhead state persist in a private session; screenshots return images. Source changes return stale with state reapplied/dropped and skip acting commands; browser restoration is reported. Command output distinguishes ran, failed and skipped operations. runtimeCost reports measured DOM, long-task and React rendering findings, or explicit measurement failures. The anchor command returns a rendered element/quote target; record enables mp4 recording. Live browsers close when the canvas activity finishes. The shared capture also returns runtimeCost for its source: over-budget findings earlier live calls recorded, or unavailable. Scope: project:read.

check_definition

ChatGPT
Compile one Branch's Project Definition at bloom:def/ with Bloom's authoritative compiler and return { branchId, ok, frontier, diagnostics, summary }. Read-only: it never accepts a version or changes infrastructure. Diagnostics name bloom:def/ paths; the summary lists Environment, Check and Publishing keys. Bloom's own agent edits bloom:def/ with its file tools. Scope: project:read.

commit_file_upload

ChatGPT
Finish an upload begun with begin_file_upload: Bloom re-hashes the stored bytes, then creates the file, or replaces it when expectedBasis matches what the path holds. Returns status "committed" with contentHash (the basis for your next replace), or status "conflict" with currentBasis when someone changed the path first; a conflict overwrites nothing. Scope: project:write.

copy_files

ChatGPT
Copy a Bloom sandbox file onto the canvas as an import wrapper. This does NOT copy implementation source into a frame; it creates a canvas artboard that imports the sandbox file and materializes the codebase-component bridge. The direction is always sandbox → canvas and the mode is always an import wrapper, so each entry is just { path, displayName }. Scope: canvas:write.

create_canvas_page

ChatGPT
Create a root page or, with parentCanvasPageId, a subpage in the branch's project when no page exists or another page is requested. Returns the new canvasPageId. New frame authoring in multi-page projects requires explicit page identity. Scope: canvas:write.

create_thread

ChatGPT
Create a canvas comment thread when target is present, or post to the branch Bloom chat and start an asynchronous agent run when target is omitted. Chat results include agentRun.editId. Mentions may tag Bloom or frames; mentioning Bloom in a comment requests agent work. Rendered element/code-span targets must resolve or return MCP_COMMENT_TARGET_UNRESOLVED. Pin a comment about one thing to it: browse_frame, anchor @eN, then pass the printed target with state "browser"; a target without spot sits on the frame as a whole and returns a nextStep. Browser-backed targets preserve the selected element/quote and runtime context. Returns resolved anchor, captureKey and app link. Author identity comes from the MCP client. Scope: comments:write for comments; project:write for chat and supplied live context IDs.

delete_files

ChatGPT
Delete canvas frames by canonical bloom:frame/pages/<Page>/<Frame>.tsx path, or files in bloom:devbox/. Frames with importers return delete_has_importers and importerFrameIds without deletion. Successful entries include previously openCommentThreads affected by deletion. Scope: canvas:write.

delete_message

ChatGPT
Delete a comment-thread message your integration wrote. Deleting a thread's last message deletes the thread too (the result says so via threadDeleted). Someone else's message is refused with MCP_COMMENT_NOT_OWNED; Bloom chat messages cannot be deleted. Scope: comments:write.

delete_thread

ChatGPT
Permanently delete a canvas comment thread, all replies and captured runtime state, regardless of author. This operation is destructive; resolving a thread retains its history. Bloom chat threads cannot be deleted. Scope: comments:write and project:write.

edit_files

ChatGPT
Edit existing files by exact text replacement: files: [{ path, edits: [{ old, new, replaceAll?, startLine?, endLine? }] }]. Each old must be copied from the file and match exactly once (line-ending, trailing-whitespace and curly-quote differences still match and are reported in matchedWith). Use read_files find to locate the text first. Pass intent (one sentence) on each entry: if an old text does not match, Bloom asks a merge model to apply the change from your intent, checks the result, and returns the diff with appliedVia: intent_fallback. Re-read the diff. When it cannot, the original error carries errorDetail.fallback.outcome. Accepts canonical bloom:frame/pages/<Page>/<Frame>.tsx and bloom:devbox/<checkout-path> paths. All files are resolved before any is written: a missing (EDIT_TARGET_NOT_FOUND, with nearest lines; newTextAt means it was probably already applied), ambiguous (EDIT_TARGET_AMBIGUOUS) or overlapping edit writes nothing. The edit applies against the text the server read, so a person typing elsewhere in the file is kept; if they changed the text you replaced, the result is EDIT_CONFLICT with observedText (re-read and retry). EDIT_CONTENDED and FILE_BUSY carry retryAfterMs. Write-time failures (EDIT_CONFLICT, EDIT_CONTENDED, FILE_DELETED, EDIT_INVALID_RESULT) are per file. idempotencyKey makes a resend replay (replayed: true). Use write_files basis to replace a whole file. returnDiff adds a canonical path-scoped unified diff. Existing dependency pins are retained; packageVersions covers newly introduced unresolved dependencies. Returns post-edit contentHash, current rect, openCommentThreads and page identity. This operation preserves frame kind and does not promote components. Committed bloom:repo/ paths reject mutations. Verification is asynchronous: entries return typeStatus pending, and the envelope's verification reports checksInFlight plus frames[] with type errors, lint and perf findings and counts {type, lint, perf} equal to the canvas frame label. Runtime cost (perf) is measured by browse_frame commands, not by edits. Scope: canvas:write.

edit_message

ChatGPT
Replace a comment-thread message authored by this integration. Other authors' messages return MCP_COMMENT_NOT_OWNED. Bloom chat history cannot be edited. Scope: comments:write.

finish_canvas_work

ChatGPT
End a canvas activity after reviewing the results, or abandon it when stopping. Retries are idempotent while the record is retained. This works even if canvas write access was revoked after begin.

get_profile

ChatGPT
Return the profile represented by this request's authenticated credentials. The opaque id is unique within Bloom and remains unchanged across token refresh, reconnection, scope upgrades and display-metadata changes. Display name and email identify the selected connection; workspace selection does not switch accounts. Scope: project:read.

get_user_selection

ChatGPT
Read the account's authorized live or recent Bloom canvas tabs, ranked by last focus. Returns source-backed selection anchors, selected comment-thread IDs, and page IDs/names without source text or comment bodies. Useful for user requests about selected objects or the current canvas. A headless account with no open tab returns items: []. Scope: project:read.

list_branches

ChatGPT
List branches, with the project they belong to on every row: { branches: [{ branchId, name, isMain, status, projectId, projectName, workspaceName?, devDeploymentId?, parentBranchId? }] }. devDeploymentId is the deploymentId run_one_off takes; parentBranchId is the branch frames are inherited from (copy-on-write). projectId is optional — omit it to span every project you can read. This is the one discovery call for picking a branch; there is no separate project-listing tool. Scope: project:read.

list_canvas_frames

ChatGPT
Inventory active frames visible on one page/branch. Rows include name, kind, componentName, render status/error, board rect/renderSize/order, contentHash, import relationships, originating comment thread, originKind, own/parent/unprojected provenance, lastEdit and openCommentThreads. Default sorting is newest edit first; layout sorting follows z-order. Deleted frames are absent. There is no separate server-side hidden/collapsed frame state. Scope: project:read.

list_canvas_pages

ChatGPT
List pages in the branch's project, including subpages via parentCanvasPageId, with active frameCount and lastChangedAt for changes by any actor. Returns page identity and distinguishes empty pages from populated ones. Existing frame-addressed operations resolve their page automatically; ambiguous page errors enumerate candidates. Scope: project:read.

list_recent_canvas_changes

ChatGPT
List recent semantic canvas changes with actor, scope, targets, timestamps, and exact/inferred grouping evidence. Each item names its page (canvasPageName) and its frame targets by name, kind and state (active, or gone when the frame no longer resolves). A frame delete, move or create arrives as operationKind: 'layout' with a page-root target (frameId: null), because it is one opaque update to the page's layout doc; detail: 'patch' attaches a layout delta that names the frames added and removed. Defaults to this credential's OWN changes — the result echoes actors so an empty page-scoped read is legible as 'none of yours', not 'nothing happened' — and actors: 'all' (with scope: { branchId }; projectId is derived) is how to see the human's edits. Scope: project:read.

list_threads

ChatGPT
Read a branch's canvas comment threads and Bloom chat, newest message first. Filters support kind, frame/thread IDs, status, text query, involving "me" and since (new since your last read). Rows include threadId, messageId, author/body; comments include status/page/target, while chat includes role and agent editId. complete, matched and returned counts distinguish complete results from bounded prefixes. Runtime evidence is descriptor-only with captureKey and source/payload hashes; placement uses path/spot/routePath. Scope: project:read.

move_files

ChatGPT
Move or rename canonical Canvas Frame or devbox files within one authority. Every source import is rewritten in the same fenced publication. Frame identity, source CRDT, placement, comments and historical snapshots remain stable. basis is the source contentHash returned by read_files. Committed bloom:repo paths reject mutations. Scope:canvas:write.

move_frames

ChatGPT
Reposition existing canvas frames to absolute coordinates in one layout update. Source, size and screenshots are unchanged. Each success returns x/y/width/height. Unknown frames return not_found and are not created. This operation does not resize frames. Scope: canvas:write.

react_message

ChatGPT
Add or remove your emoji reaction on a V2 Thread Message. Adding returns alreadyReacted: everyone who already reacted with the same emoji (who and when), read in the same transaction as your add, so you can see work someone already took before duplicating it. status is added, already_reacted (yours existed; nothing written) or removed. One reaction per reactor per emoji; you and the person you act for are separate reactors. Bloom attaches no meaning to any emoji. Scope: comments:write.

read_files

ChatGPT
Read canonical TSX and full-file SHA-256 contentHash for canvas frames, or read-only files in the Bloom project sandbox. Canvas entries include stable JSX sourcePath locators (50 per page; continue with elementsCursor and the same query), truncatedElementsCount, kind, importedFrameIds, openCommentThreads, and page ID/name. Batches may span pages. Sandbox reads address the Bloom project, not the client's local repository. Direct sandbox mutation is unavailable through this operation. Canvas entries also carry the checks on exactly that source: typeStatus, typeCheck with lint, and runtimeCost, which is ran with over-budget rules, values and budgets, or unavailable when no browse_frame call recorded one. Each entry may take startLine/endLine (1-based, inclusive) or find (only the lines containing that text, as matches); every success reports totalLines for the whole file. A find or line-range read leaves out element locators (elementsOmitted; pass query to get them). The envelope's verification lists the batch's own frames; otherFilesWithErrors counts the rest of the branch's failing files. Arguments take the shape { files: [{ path }] }. Scope: project:read.

read_frame_state

ChatGPT
Read frontend hooks, stores or storage from an authorized private frame-browser session, live Bloom tab, or comment capture. Overview returns a bounded map; storageKey/valuePath and cursors select detailed values. Truncated strings include prefix and omittedCharacters. Results include payloadHash. Scope: project:read.

reply_thread

ChatGPT
Reply to a canvas comment thread or the branch Bloom chat. Chat replies start asynchronous Bloom agent runs; comment replies reopen resolved threads and return threadStatus. The author comes from the MCP client identity. Mentions may tag Bloom or frames. Replies do not replace captured runtime state. Scope: comments:write for comments; project:write for chat.

request_access

ChatGPT
Request browser review of this connection, including additional projects or OAuth scopes. Returns an approval URL and reconnect instructions; never grants access itself. Open the URL for the user, then use the plugin or MCP host's reconnect/reauthenticate action after approval. Hosts supporting OAuth step-up may do this automatically. API-key connections return key-management instructions. Cancel leaves existing access unchanged.

run_one_off

ChatGPT
Run temporary TypeScript against one exact Bloom deployment. Every mode requires live deployment:admin permission. Queries execute immediately. Mutation, read_action, and action calls require a personal approval unless the same Bloom user already allowed this exact deployment + mode. The preference follows the user across Bloom Agent and MCP clients; it is never shared with another workspace member.

send_feedback

ChatGPT
Submit user-requested feedback to Bloom engineering. Supports feedback categories including praise and reports deduplicated/rate-limited outcomes. Client identity and server version are attached automatically. No additional project scope is required.

skills

ChatGPT
Read Bloom authoring documentation requested by the user. Without name, returns an index of names/descriptions; with name, returns the selected documentation as markdown. This operation provides reference material and does not change account, project or canvas state.

update_thread

ChatGPT
Update a canvas comment thread's target, captured runtime state, or open/resolved status. At least one of target, state or status is required. Moving a target retains replies; moving without state drops the old placement's runtime evidence. State may reference an authorized private browser session or live canvas context. Bloom chat threads have no placement/status and are rejected. Message text and deletion are outside this operation. Scope: comments:write; supplied live context IDs also require project:write.

whoami

ChatGPT
Read the authenticated principal, credential narrowing, accessible project count, serverVersion and toolCount. Unambiguous defaultContext includes project/branch/page IDs and their names, matching calls without explicit IDs. ambiguousAt identifies branch/page ambiguity. Version and toolCount provide evidence of stale client discovery caches.

write_files

ChatGPT
Create or overwrite Bloom canvas frames from TSX, or write files in the live devbox checkout. Paths use bloom:frame/pages/<Page>/<Frame>.tsx or bloom:devbox/<checkout-path>. A missing frame requires basis:null. Frames become components when another frame imports them. The authored Frame kind is artboard. Device previews are metadata, not source files. React DOM, React Native, and Tailwind are supported. packageVersions pins otherwise unresolved npm dependencies. basis is the canonical source hash for conflict checking. Successful entries return contentHash, board rect, and openCommentThreads and the envelope identifies the page. Committed bloom:repo/ paths reject mutations. Verification is asynchronous: entries return typeStatus pending, and the envelope's verification reports checksInFlight plus frames[] with type errors, lint and perf findings and counts {type, lint, perf} equal to the canvas frame label. Runtime cost (perf) is measured by browse_frame commands, not by writes. Scope: canvas:write.

Capabilities

Writes

Example Prompts

Click any prompt to copy it.

App Stats

37

Tools

3

Prompts

ChatGPT

Platforms

Works with

ChatGPT

Data refreshed daily