AffinityMCP
Provides tools for automating Affinity applications (Photo, Designer, Publisher) including opening files, creating documents, exporting, applying filters, and batch operations.
Allows control of Affinity Photo for image editing tasks such as opening files, applying filters, and exporting in various formats.
Enables creating designs and managing design workflows through Canva's API, including creating new designs with optional templates and dimensions.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@AffinityMCPCreate a new document 1920x1080 in Affinity Photo"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
AffinityMCP
The Universal MCP Server (Rust) exposes tools for Canva workflows—and Affinity Photo/Designer/Publisher automation—designed for natural language usage in MCP-compatible clients.
Features
🎨 Natural Language Control: Control Affinity applications using natural language commands
🖼️ File Operations: Open files, create new documents, export in various formats
⚡ 16-Parallel Processing: Process up to 16 files simultaneously for maximum efficiency
🔧 Advanced Tools: Apply filters, get document info, and more
🚀 Easy Setup: Simple setup for beginners with comprehensive documentation
🌐 Cross-Platform Ready: Currently macOS (AppleScript), Windows support planned
Quick Start
For beginners, see SETUP_GUIDE.md for detailed step-by-step instructions.
Quick installation:
# Build
cargo build --release
cp target/release/affinity-mcp dist/
# Use with Cursor
# Add to Cursor MCP settings:
{
"mcpServers": {
"affinity-mcp": {
"command": "npx",
"args": ["affinity-mcp"],
"autoStart": true
}
}
}Installation
Prerequisites
Node.js 18+ (for the thin npx wrapper)
Rust 1.76+ / Cargo (for local builds)
Set
AFFINITY_MCP_API_KEYif using Canva Connect/MCP endpoints.
Get an API key
If your tools require Canva APIs, obtain credentials from the Canva developer console or MCP server guidance. Otherwise, you can skip this step.
Build locally
cd /path/to/affinity-mcp
cargo build --release
# copy target/release/affinity-mcp -> ./dist/
cp target/release/affinity-mcp dist/Setup: Claude Code (CLI)
Use this one-liner (replace with your real values):
claude mcp add AffinityMCP -s user -e AFFINITY_MCP_API_KEY="sk-your-real-key" -- npx affinity-mcpTo remove:
claude mcp remove AffinityMCPSetup: Cursor (Do not commit .cursor/mcp.json here)
Create the config in your client:
{
"mcpServers": {
"affinity-mcp": {
"command": "npx",
"args": ["affinity-mcp"],
"env": { "AFFINITY_MCP_API_KEY": "sk-your-real-key" },
"autoStart": true
}
}
}Other Clients and Agents
code --add-mcp '{"name":"affinity-mcp","command":"npx","args":["affinity-mcp"],"env":{"AFFINITY_MCP_API_KEY":"sk-your-real-key"}}'Follow the MCP install guide and reuse the standard config above.
Command: npx
Args: ["affinity-mcp"]
Env: AFFINITY_MCP_API_KEY=sk-your-real-key
Type: STDIO
Command: npx
Args: ["affinity-mcp"]
Enabled: true
~/.config/opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"affinity-mcp": {
"type": "local",
"command": ["npx", "affinity-mcp"],
"enabled": true
}
}
}Add a new MCP and paste the standard JSON config.
See docs and reuse the standard config above.
Setup: Codex (TOML)
Example (Serena):
[mcp_servers.serena]
command = "uvx"
args = ["--from", "git+https://github.com/oraios/serena", "serena", "start-mcp-server", "--context", "codex"]This server (minimal):
[mcp_servers.affinity-mcp]
command = "npx"
args = ["affinity-mcp"]
# Optional environment variables:
# AFFINITY_MCP_API_KEY = "sk-your-real-key"
# MCP_NAME = "affinity-mcp"Configuration (Env)
AFFINITY_MCP_API_KEY: Canva API key or token (if applicable)MCP_NAME: Server name override (default: affinity-mcp)
If your tools are purely local, no API keys are required.
Available Tools
Affinity Tools (Natural Language Support)
All Affinity tools support natural language commands. Examples:
"Open the file /path/to/image.jpg in Affinity Photo"
"Create a new document with width 1920 and height 1080"
"Export the current document as PDF to /path/to/output.pdf"
affinity.open_file
Open a file in Affinity application (auto-detects app from file extension).
inputs: { "path": string, "app"?: "Photo"|"Designer"|"Publisher" }
outputs: { "opened": boolean, "app": string, "path": string }
affinity.create_new
Create a new Affinity document.
inputs: { "app": "Photo"|"Designer"|"Publisher", "width"?: number, "height"?: number }
outputs: { "created": boolean, "app": string }
affinity.export
Export the currently open document.
inputs: { "path": string, "format": "pdf"|"png"|"jpg"|"tiff"|"svg", "quality"?: number }
outputs: { "exported": boolean, "path": string }
affinity.apply_filter
Apply a filter to the current document.
inputs: { "filter_name": string, "intensity"?: number }
outputs: { "applied": boolean, "filter_name": string }
affinity.get_active_document
Get information about the currently active document.
inputs: {}
outputs: { "is_open": boolean, "name"?: string, "path"?: string }
affinity.close_document
Close the currently open document.
inputs: {}
outputs: { "closed": boolean }
affinity.batch_open_files ⚡ 16-Parallel
Open multiple files simultaneously (up to 16 files in parallel).
inputs: { "paths": string[], "app"?: "Photo"|"Designer"|"Publisher" }
outputs: { "success_count": number, "failure_count": number, "results": OpenFileResult[] }
Natural language example: "Open multiple files: /path/to/image1.jpg, /path/to/image2.jpg, /path/to/image3.jpg"
affinity.batch_export ⚡ 16-Parallel
Export multiple documents simultaneously (up to 16 exports in parallel).
inputs: { "exports": ExportParams[] }
outputs: { "success_count": number, "failure_count": number, "results": ExportResult[] }
Natural language example: "Export all open documents as PDF files"
Canva Tools
canva.create_design
inputs: { "title": string, "template_id"?: string, "width"?: number, "height"?: number }
outputs: { "design_id": string, "url"?: string }
Example Usage
Natural Language Commands
In Cursor or other MCP-compatible clients, you can use natural language:
Example 1: Open a file
User: "Open /Users/john/Desktop/image.jpg in Affinity Photo"
AI: [Calls affinity.open_file with path="/Users/john/Desktop/image.jpg", app="Photo"]Example 2: Create and export
User: "Create a new Affinity Photo document with size 1920x1080, then export it as PDF to my Desktop"
AI: [Calls affinity.create_new, then affinity.export]Example 3: Get document info
User: "What document is currently open?"
AI: [Calls affinity.get_active_document]Example 4: Batch operations (16-parallel)
User: "Open these 5 images simultaneously: /path/to/img1.jpg, /path/to/img2.jpg, /path/to/img3.jpg, /path/to/img4.jpg, /path/to/img5.jpg"
AI: [Calls affinity.batch_open_files with paths array]Example 5: Batch export (16-parallel)
User: "Export all open documents as PDF files to the Desktop"
AI: [Calls affinity.batch_export with multiple export configurations]Direct Tool Invocation (MCP tool call)
{
"type": "tool",
"name": "affinity.open_file",
"arguments": {
"path": "/path/to/image.jpg",
"app": "Photo"
}
}Documentation
SETUP_GUIDE.md: Beginner-friendly setup guide with step-by-step instructions
SPEC.md: Technical specification (Japanese)
README.md: This file (English documentation)
For complex schemas, see src/tools/*.rs.
Name Consistency & Troubleshooting
Always use CANONICAL_ID (affinity-mcp) for identifiers and keys.
Use CANONICAL_DISPLAY (AffinityMCP) only for UI labels.
Do not mix legacy keys after registration.
Consistency Matrix
npm package name →
affinity-mcpBinary name →
affinity-mcpMCP server name →
affinity-mcpEnv default MCP_NAME →
affinity-mcpClient registry key →
affinity-mcpUI label →
AffinityMCP
Conflict Cleanup
Remove stale keys and re-add with affinity-mcp only.
Cursor is UI-configured only; this repo intentionally omits .cursor/mcp.json.
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/tacyan/AffinityMCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server