AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Balise Affinity Mcp

skill-mrstev3n-balise-skills-balise-affinity-mcp · by mrstev3n

Automate Affinity by Canva through the Affinity MCP and JavaScript SDK for manipulating open documents, selected objects, layers/nodes, geometry, text, fills, line styles, document commands, exports, and visual verification. Use when an agent needs to test or use the Affinity MCP, edit the current Affinity file, inspect or modify objects or selections, create or adjust Affinity elements, automate…

No reviews yet
0 installs
4 views
0.0% view→install

Install

$ agentstack add skill-mrstev3n-balise-skills-balise-affinity-mcp

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-mrstev3n-balise-skills-balise-affinity-mcp)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
6d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Balise Affinity Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Affinity MCP Automation

Use the Affinity MCP as a live application-control surface. Work from the open document, inspect before editing, prefer small reversible commands, and verify visual results.

Standard Workflow

  1. Load Affinity tools if they are not already present.
  2. Read SDK documentation in this order:
  • Always read preamble first.
  • Call list_sdk_documentation.
  • Read only the topics needed for the task, such as application.js, document.js, nodes.js, commands.js, geometry.js, colours.js, fills.js, linestyle.js, storybuilder.js, glyphatts.js, paragraphatts.js, or exportconfig.js.
  1. Inspect the current document before making changes.
  2. Choose the narrowest edit: selected object first, current spread next, whole document only when requested.
  3. Execute scripts with the Affinity MCP execute_script capability; a harness may expose a qualified tool name. Use console.log(JSON.stringify(...)) for observable output.
  4. Verify with render_selection(document_session_uuid) whenever the result is visual.
  5. Do not save, export, flatten, delete broad selections, or resize the spread unless the user asked for that kind of change.

Document Inspection

Use this baseline probe before editing:

const {Document} = require('/document');
const doc = Document.current;
if (!doc) {
  console.log(JSON.stringify({ok: false, reason: 'NO_CURRENT_DOCUMENT'}));
} else {
  console.log(JSON.stringify({
    ok: true,
    title: doc.title,
    path: doc.path,
    sessionUuid: doc.sessionUuid,
    isReadOnly: doc.isReadOnly,
    isDirty: doc.isDirty,
    needsSaving: doc.needsSaving,
    pageCount: doc.pageCount,
    spreadCount: doc.spreadCount,
    selectedCount: doc.selection.nodes.length,
    currentSpreadBox: doc.currentSpread.baseBox
  }, null, 2));
}

Stop cleanly if Document.current is null or doc.isReadOnly is true.

Object Operations

Use node operations for visible document objects:

  • doc.selection returns the current selection.
  • doc.selection.nodes gives selected nodes.
  • node.userDescription = '...' is useful for naming automation-created objects.
  • doc.selectAll(false) selects all document objects; use it deliberately because it changes selection.
  • doc.deleteSelection(selection) deletes selected objects; only use when the user wants replacement or cleanup.
  • doc.setVisible(visible, selection), doc.lockSelection(selection), and doc.unlockSelection(selection) operate through document commands.
  • For new nodes, doc.addNode(def, doc.currentSpread) adds to the current spread and selects the new object.

Use descriptions and final selection intentionally so the user can inspect or undo the right thing.

Geometry And Appearance

For basic shapes:

  • Create a ShapeNodeDefinition.
  • Set a shape, such as ShapeRectangle.create() or ShapeEllipse.create().
  • Set the bounding rectangle.
  • Add it to the current spread.
  • Apply fill and stroke to the resulting selection.

For exact freeform shapes:

  • Build a closed path with CurveBuilder.
  • Add it to a PolyCurve.
  • Put it into PolyCurveNodeDefinition.
  • Add it to the document.

For appearance:

  • Use RGBA8(r,g,b,a) from /colours.
  • Use FillDescriptor.createSolid(colour) for brush or pen fill.
  • Use FillDescriptor.createNone() to remove fill or stroke.
  • Use /linestyle and doc.setLineStyleDescriptor(...) when stroke weight, caps, joins, or alignment matter.

Read references/affinity-js-patterns.md for tested snippets. Read references/affinity-concepts-and-nuances.md when the task requires choosing between Affinity object types, text modes, non-destructive techniques, or verification methods.

Text Operations

Do not assume text node defaults exist. In current SDK usage, these fail:

  • FrameTextNodeDefinition.createDefault()
  • ArtTextNodeDefinition.createDefault()
  • TextNodeDefinition.createDefault()

Use StoryBuilder plus FrameTextNodeDefinition.createFromStoryBuilder(frameBox, storyBuilder) or ArtTextNodeDefinition.createFromStoryBuilder(point, storyBuilder):

  • Set defaults with sb.setToFrameTextDefaultStyle(doc.dpi, doc.format).
  • For Artistic Text, set defaults with sb.setToArtisticTextDefaultStyle(doc.dpi, doc.format).
  • Configure sb.glyphAtts for font, height, fill, and optional spacing.
  • Configure sb.paragraphAtts for alignment and explicit leading.
  • Add text line by line.
  • Use generous frame bounds, then render-check for clipping.
  • Treat glyph.characterSpacing as an em-like value. Use small values such as -0.02, 0, or 0.03; values like -1 or -4 can collapse glyph advance and make characters appear stacked.

For existing selected text, read commands.js and storydelta.js before applying formatting commands such as doc.formatText(...).

Artistic Text vs Frame Text

Choose the text object type intentionally:

  • Use Artistic Text for short display text, labels, numerals, titles, and poster-like fragments where the text box should hug the text content.
  • Use Frame Text for paragraphs, fixed-width copy blocks, multi-line text areas, and text that needs a deliberately sized container.
  • Frame Text has a container frame in the editing UI. That frame can be visually distracting while designing, but it is not part of the artwork/export unless an actual stroke/fill/decoration has been applied.
  • For rotated labels, create Artistic Text first, retrieve the created node, rotate it with DocumentCommand.createTransform(...), then measure node.spreadVisibleBox and translate it into place.
  • If a user complains about boxes around all text, first check whether objects are selected and render the spread. If render_spread shows no boxes, explain that the boxes are UI overlays/text containers, not exported artwork.
  • For visual verification of the full composition, prefer render_spread over doc.selectAll(false) plus render_selection, because selecting all objects can make UI selection boxes look like a design problem in the live app.

Document Features

Prefer documented command helpers over ad hoc state mutation:

  • Guides: DocumentCommand.createAddGuide(...).
  • Document/spread sizing: doc.setSpreadSizeWithAnchor(...); remember this can affect layout.
  • History: doc.undo(), doc.redo(), doc.undoDescription, doc.redoDescription.
  • Export: read document.js and exportconfig.js; use FileExportOptions and FileExportArea intentionally.
  • AI or image features: read commands.js first. Commands such as generate image, remove background, select subject, and generative edit may be restricted by Affinity settings; report NOT_ALLOWED clearly.

Verification And Reporting

After a meaningful operation, report:

  • What changed.
  • Whether the current document is dirty or needs saving.
  • Whether the result was visually verified.
  • Any known limitation, such as text clipping risk, missing selection, restricted feature, or unsaved file.

Use render_selection for visual checks. If the task modifies a single object, leave that object selected; if it rebuilds a composition, select all relevant objects before rendering.

For whole-layout verification, use render_spread when available. This is the best default for checking whether a composition itself is clean, because selecting everything can introduce UI overlays that are not part of exported artwork.

Learning Loop

When a new Affinity SDK lesson is discovered:

  1. Confirm it with a small script or visual check.
  2. If the MCP exposes add_sdk_hint, add a concise entry for future sessions.
  3. Update this skill only when the lesson is general enough to apply beyond the immediate artifact.

Keep this skill about manipulation of Affinity objects and features. Treat poster or layout recreation as one application of those primitives, not as the center of the skill.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.