Skip to main content
Glama

Share a saved canvas by link

well_share_canvas

Freeze one of the workspace's saved canvases WITH its figures and return a link that opens it outside Well, with no Well account.

Use it when someone asks to send a board to an investor, an accountant, a bank or anyone else who cannot sign in. The link is the whole credential: whoever holds it can read those figures until it is stopped.

WORKFLOW — the same measuring as well_render_canvas, then BOTH calls:

  1. well_show_canvas({ canvas_view_id }) → the board's version, and its blocks, each with the feed it reads and the window it asks for.

  2. For EVERY block that names a feed, run that feed's own skill over that block's window, and call its render tool (well_render_cash_position, well_render_burn, well_render_mrr, well_render_runway, well_render_cost_structure, well_render_cash_forecast, well_render_cash_flow_bridge). A logged-time block has no board skill: the logged-time skill reads one project and does not measure this block. Call well_render_logged_time with no arguments.

  3. well_render_canvas({ canvas_view_id, version, blocks }) → the board, drawn for the person you are talking to.

  4. well_share_canvas({ canvas_view_id, version, blocks }) → the link, from the same readings.

Both, and in that order. The person who asked to send a board wants to see what they are sending; a link on its own asks them to open it themselves to find out.

Forward each reading as it came back, and send nothing beside it. A reading that is not its block's own render tool output, that covers a different window than its block asks for, or whose figure cannot be drawn is refused, and every feed block needs an entry: a board shared with one block missing reads as a board whose missing figure is zero. A board that holds one widget is shared with well_share_widget, not this tool.

What the reader sees is frozen at the moment you share it, and dated with that moment, private data included. It does not follow the board afterwards: editing the canvas, or measuring it again, changes nothing on a link already sent. To send newer figures on the SAME link, measure the board again and call well_refresh_share_link; to send a separate link, share again.

THE LIFETIME: the link has no expiry, whatever the size of the board. It opens until the person stops it with well_revoke_share_links, and a refresh does not change that. When the person wants the link to stop at a date, say it opens until they stop it, and offer to stop it when they ask.

Give the link to the person who asked in the same reply. Say with it that it opens until they stop it, that anyone holding the link can open the board, so it should go to the people they meant and no further, and that you can stop it at any time with well_revoke_share_links.

What the reader sees is each block's figure, its currency and the words that block draws. Not the accounts behind a cash position, not the bank or the account number, not the feed each block reads or the window it asked for. A slice of a cost structure is named the way the board names it, which on a chart of accounts can be a person, so say what the board is about rather than promising it names nobody.

Do NOT use it in place of well_render_canvas. That one draws and stores nothing, and it is what answers "show me the board". This one is only for the reader who cannot sign in.

Input Schema

NameRequiredDescriptionDefault
blocksYesOne entry per block on the canvas that names a feed. A note takes none.
versionYesThe canvas version well_show_canvas returned. The readings were measured against that version's blocks.
workspace_idNoTarget workspace. Omit when the token authorizes one workspace. Required when it authorizes several — a write lands in exactly one workspace and this call would not say which.
canvas_view_idYesThe canvas to share. Read it first with well_show_canvas.
conversation_idNoThe conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation.
idempotency_keyNoOptional client-supplied key. A retried write with the same key returns the original result instead of re-applying the operation.
workspace_scopeNoRestrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace.

Output Schema

NameRequiredDescriptionDefault
urlNoThe link to give the person who asked. Later, well_list_share_links gives it back to them only.
nameNo
errorNo
successYes
expires_atNoNull: the link opens until it is stopped.
resolved_atNo
share_link_idNoNames this link for well_refresh_share_link and well_revoke_share_links. Not something to give the reader.
conversation_idNoThe conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.
newly_connectedNoTools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: "<name> is connected.". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later.
resolved_workspaceNoThe workspace that answered, when the caller named none and the token authorizes several.
conversation_id_noteNoPresent only when the server opened a fresh lane, stating that no choice recorded earlier was read.
conversation_id_sourceNoWhere the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • removedOutput schema / properties / resolved_workspace / properties / name / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / resolved_workspace / properties / name / type
      Added value: +[
      +  "string",
      +  "null"
      +]
  2. Changed1 schema field changed
    • changedOutput schema / properties / url / description
      Previous value: -"The link to give the person who asked. Returned once and never again."New value: +"The link to give the person who asked. Later, well_list_share_links gives it back to them only."
  3. Changed3 schema fields changed
    • removedInput schema / properties / expires_in_days
      Removed value: -{
      -  "description": "Days until the link stops opening, only when the person states a limit. At most 365 for a board of several blocks, 30 for one block.",
      -  "maximum": 365,
      -  "minimum": 1,
      -  "type": "integer"
      -}
    • changedOutput schema / properties / expires_at / description
      Previous value: -"When the link stops opening."New value: +"Null: the link opens until it is stopped."
    • changedOutput schema / properties / expires_at / type
      Previous value: -"string"New value: +"null"
  4. Changed4 schema fields changed
    • addedInput schema / properties / expires_in_days
      Added value: +{
      +  "description": "Days until the link stops opening, only when the person states a limit. At most 365 for a board of several blocks, 30 for one block.",
      +  "maximum": 365,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • removedOutput schema / properties / canvas_share_id
      Removed value: -{
      -  "description": "Names this link in the workspace's own records. Not something to give the reader.",
      -  "type": "string"
      -}
    • addedOutput schema / properties / expires_at
      Added value: +{
      +  "description": "When the link stops opening.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / share_link_id
      Added value: +{
      +  "description": "Names this link for well_refresh_share_link and well_revoke_share_links. Not something to give the reader.",
      +  "type": "string"
      +}
  5. Changed1 schema field changed
    • changedOutput schema / properties / newly_connected / description
      Previous value: -"Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. Start the reply with one line per entry, in the person's language: \"<name> is connected.\". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later."New value: +"Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: \"<name> is connected.\". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later."
  6. Changed1 schema field changed
    • addedInput schema / properties / workspace_scope
      Added value: +{
      +  "description": "Restrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace.",
      +  "enum": [
      +    "family"
      +  ],
      +  "type": "string"
      +}
  7. Changed1 schema field changed
    • addedOutput schema / properties / newly_connected
      Added value: +{
      +  "description": "Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. Start the reply with one line per entry, in the person's language: \"<name> is connected.\". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "name": {
      +        "type": "string"
      +      },
      +      "service_id": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "service_id"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  8. Added

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=false and destructiveHint=false, so the description carries the real disclosure burden and does: the link has no expiry, the content is frozen at share time and does not follow later edits, refresh vs. re-share vs. revoke are separated, and rejection conditions (wrong window, rebuilt figure, missing feed block) are stated. It also enumerates exactly what the reader does and does not see, which is privacy context no annotation could convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Given a four-call workflow and lifetime/revocation semantics, the length is largely earned, and it is front-loaded with purpose then workflow then lifetime. Some redundancy remains — reader-visibility is covered both in the freezing paragraph and again in the later 'what the reader sees' paragraph, and the reply-wording instructions are restated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return shape needn't be described, and everything else an agent needs — prerequisite calls, per-block sourcing, what is frozen, how to refresh, how to revoke, what to tell the requester — is present. Nothing material is left to inference for a mutation tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes further by explaining that each block entry must forward its own render tool's structuredContent whole, unmodified, covering the block's window, with an entry required for every feed block. That meaningfully constrains how `blocks` must be populated beyond the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opening sentence states a specific verb and resource (freeze a saved canvas with its figures) plus the outcome (a link that opens outside Well with no account). It explicitly distinguishes itself from well_render_canvas and well_share_widget, so the agent can route between the three without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States exactly when to use it ('when someone asks to send a board to an investor, an accountant, a bank or anyone else who cannot sign in'), spells out the mandatory 4-step sequence and prerequisite measuring calls, and gives an explicit exclusion ('Do NOT use it in place of well_render_canvas... it is what answers "show me the board"').

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources