canva
MCP skill for canva. Provides 22 tools: upload-asset-from-url, resolve-shortlink, search-designs, get-design, get-design-pages, get-design-content, get-presenter-notes, import-design-from-url, merge-designs, export-design, get-export-formats, create-folder, move-item-to-folder, list-folder-items, search-folders, comment-on-design, list-comments, list-replies, reply-to-comment, generate-design, create-design-from-candidate, list-brand-kits
What this skill does
# canva
MCP skill for canva. Provides 22 tools: upload-asset-from-url, resolve-shortlink, search-designs, get-design, get-design-pages, get-design-content, get-presenter-notes, import-design-from-url, merge-designs, export-design, get-export-formats, create-folder, move-item-to-folder, list-folder-items, search-folders, comment-on-design, list-comments, list-replies, reply-to-comment, generate-design, create-design-from-candidate, list-brand-kits
## Authentication
This MCP server uses **OAuth** authentication.
The OAuth flow is handled automatically by the MCP client. Tokens are persisted
to `~/.mcp-skill/auth/` so subsequent runs reuse the same credentials without
re-authenticating.
```python
app = CanvaApp() # uses default OAuth flow
```
To bring your own OAuth provider, pass it via the `auth` argument:
```python
app = CanvaApp(auth=my_oauth_provider)
```
## Dependencies
This skill requires the following Python packages:
- `mcp-skill`
Install with uv:
```bash
uv pip install mcp-skill
```
Or with pip:
```bash
pip install mcp-skill
```
## How to Run
**Important:** Add `.agents/skills` to your Python path so imports resolve correctly:
```python
import sys
sys.path.insert(0, ".agents/skills")
from canva.app import CanvaApp
```
Or set the `PYTHONPATH` environment variable:
```bash
export PYTHONPATH=".agents/skills:$PYTHONPATH"
```
**Preferred: use `uv run`** (handles dependencies automatically):
```bash
PYTHONPATH=.agents/skills uv run --with mcp-skill python -c "
import asyncio
from canva.app import CanvaApp
async def main():
app = CanvaApp()
result = await app.upload_asset_from_url(url="example", name="example", user_intent="example")
print(result)
asyncio.run(main())
"
```
**Alternative: use `python` directly** (install dependencies first):
```bash
pip install mcp-skill
PYTHONPATH=.agents/skills python -c "
import asyncio
from canva.app import CanvaApp
async def main():
app = CanvaApp()
result = await app.upload_asset_from_url(url="example", name="example", user_intent="example")
print(result)
asyncio.run(main())
"
```
## Available Tools
### upload-asset-from-url
Upload an asset (e.g. an image, a video) from a URL into Canva
If the API call returns "Missing scopes: [asset:write]", you should ask the user to disconnect and reconnect their connector. This will generate a new access token with the required scope for this tool.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| url | `str` | Yes | URL of the asset to upload into Canva |
| name | `str` | Yes | Name for the uploaded asset |
| user_intent | `str` | No | Mandatory description of what the user is trying to accomplish with this tool call. This should always be provided by LLM clients. Please keep it concise (255 characters or less recommended). |
**Example:**
```python
result = await app.upload_asset_from_url(url="example", name="example", user_intent="example")
```
### resolve-shortlink
Resolves a Canva shortlink ID to its target URL. IMPORTANT: Use this tool FIRST when a user provides a shortlink (e.g. https://canva.link/abc123). Shortlinks need to be resolved before you can use other tools. After resolving, extract the design ID from the target URL and use it with tools like get-design, start-editing-transaction, or get-design-content.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| shortlink_id | `str` | Yes | The shortlink ID to resolve (e.g., "abc123" from https://canva.link/abc123) |
| user_intent | `str` | No | Mandatory description of what the user is trying to accomplish with this tool call. This should always be provided by LLM clients. Please keep it concise (255 characters or less recommended). |
**Example:**
```python
result = await app.resolve_shortlink(shortlink_id="example", user_intent="example")
```
### search-designs
Search docs, presentations, videos, whiteboards, sheets, and other designs in Canva, except for templates or brand templates.
Use when you need to find specific designs by keywords rather than browsing folders.
Use 'query' parameter to search by title or content.
If 'query' is used, 'sortBy' must be set to 'relevance'. Filter by 'any' ownership unless specified. Sort by relevance unless specified.
Use the continuation token to get the next page of results, when there are more results.
CRITICAL REQUIREMENTS:
1. ALWAYS use the 'search-brand-templates' tool when the user is searching for templates or wants to use a template.
2.** 🚫 When a user says search a template, they ALWAYS mean brand-templates. Therefore NEVER call this tool, ALWAYS call the 'search-brand-templates' tool to search for the templates. **
3.** 🚫 NEVER use this tool when the user expresses intent to “generate”, “create”, “autofill”, “search a template”, “start from a template”, “use my template”, or “pick a template for generation”.
In all such cases, ALWAYS use search-brand-templates.
ANY query involving:
– “generate a presentation”
– “generate a report”
– “make a design using a template”
– “generate from a template”
– “produce a presentation from their template”
- "search for available templates"
MUST NOT use search-designs.
This tool ONLY searches existing designs (docs, presentations, whiteboards, videos, etc.) that the user already owns or that are shared with them.
It DOES NOT find templates and MUST NOT be used as a fallback for template selection. **
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| query | `str` | No | Optional search term to filter designs by title or content. If it is used, 'sortBy' must be set to 'relevance'. |
| ownership | `str` | No | Filter designs by ownership: 'any' for all designs owned by and shared with you (default), 'owned' for designs you created, 'shared' for designs shared with you |
| sort_by | `str` | No | Sort results by: 'relevance' (default), 'modified_descending' (newest first), 'modified_ascending' (oldest first), 'title_descending' (Z-A), 'title_ascending' (A-Z). Optional sort order for results. If 'query' is used, 'sortBy' must be set to 'relevance'. |
| continuation | `str` | No |
Pagination token for the current search context.
CRITICAL RULES:
- ONLY set this parameter if the previous response included a continuation token.
- If no continuation token was returned → OMIT this parameter completely. NEVER EVER fabricate a token.
- Do not set to null, empty string, or any other value when no token was provided.
Usage:
- First request: omit this parameter
- Previous response had continuation token: use that exact token
- Previous response had NO continuation token: omit this parameter
- New search query: omit this parameter
|
| user_intent | `str` | No | Mandatory description of what the user is trying to accomplish with this tool call. This should always be provided by LLM clients. Please keep it concise (255 characters or less recommended). |
**Example:**
```python
result = await app.search_designs(query="example", ownership="example", sort_by="example")
```
### get-design
Get detailed information about a Canva design, such as a doc, presentation, whiteboard, video, or sheet. This includes design owner information, title, URLs for editing and viewing, thumbnail, created/updated time, and page count. This tool doesn't work on folders or images. You must provide the design ID, which you can find by using the `search-designs` or `list-folder-items` tools. When given a URL to a Canva design, you can extract the design ID from the URL. Example URL: https://www.canva.com/design/{design_id}. If the user provides a shortlink (e.g. https://canva.link/abc123), use `resolve-shortlink`Related in Ads & Marketing
ads
IncludedMulti-platform paid advertising audit and optimization skill. Analyzes Google, Meta, YouTube, LinkedIn, TikTok, Microsoft, and Apple Ads. 250+ checks with scoring, parallel agents, industry templates, and AI creative generation.
banana
IncludedAI image generation Creative Director powered by Google Gemini Nano Banana models. Use this skill for ANY request involving image creation, editing, visual asset production, or creative direction. Triggers on: generate an image, create a photo, edit this picture, design a logo, make a banner, visual for my anything, and all /banana commands. Handles text-to-image, image editing, multi-turn creative sessions, batch workflows, and brand presets.
rpg-migration-analyzer
IncludedAnalyzes legacy RPG (Report Program Generator) programs from AS/400 and IBM i systems for migration to modern Java applications. Extracts business logic from RPG III/IV/ILE source code, identifies data structures (D-specs), file operations (F-specs), program dependencies (CALLB/CALLP), and converts RPG constructs to Java equivalents. Generates migration reports, complexity estimates, and Java implementation strategies with POJO classes, JPA entities, and service methods. Use when modernizing AS/400 or IBM i legacy systems, analyzing RPG source files (.rpg, .rpgle, .RPGLE), converting RPG to Java, mapping data specifications to Java classes, planning legacy system migration, or when user mentions RPG analysis, Report Program Generator, RPG III/IV/ILE, AS/400 modernization, IBM i migration, packed decimal conversion, or mainframe application rewrite.
brand-library-architect
IncludedBuild a complete brand library for a product — visual asset render pipeline, brand documentation set (BRAND, COPY, MANIFESTO, BIOS, FAQ, GLOSSARY, TONE, PRICING), open-source convention files (README, CONTRIBUTING, SECURITY, CODE_OF_CONDUCT), and a self-contained press kit. This skill should be used when the user asks to "build a brand library / brand kit / press kit / brand assets" for a product, "set up a brand library workflow," "create a positioning manifesto plus visual identity," or any combination of brand documentation + visual asset pipeline. Apply phase-by-phase or run end-to-end. Templates are product-agnostic and use {{TOKEN}} placeholders the skill prompts the user to fill.
writing-tech-post
IncludedAuthors engineering blog posts end-to-end: launch deep-dives, incident postmortems, architecture migrations, performance case studies, tutorials, AI/agent system writeups, security disclosures, and research-to-product translations. Picks the correct archetype, plans the abstraction ladder, enforces an evidence cadence (diagrams, benchmarks, profiles, traces, code, ablations), tunes voice against publisher house styles (Datadog, Vercel, GitHub, AWS, Meta, Cloudflare, Jane Street), and runs a pre-publish gate for narrative momentum and disclosure ethics. Use when drafting a new engineering post, restructuring a draft that feels flat, deciding which evidence form belongs where, validating that depth and product context are balanced, or preparing a postmortem, migration, or performance narrative for external publication. Do not use for API reference documentation, README authoring, marketing copy, release notes, generic SEO content, ghost-written executive thought leadership, or non-engineering long-form essays.
blog-google
IncludedGoogle API integration for blog performance: PageSpeed Insights, CrUX Core Web Vitals with 25-week history, Search Console performance, URL Inspection, Indexing API, GA4 organic traffic, NLP entity analysis for E-E-A-T, YouTube video search for embedding, and Google Ads Keyword Planner. Progressive feature availability based on credential tier (API key, OAuth/service account, GA4, Ads). Shares config with claude-seo at ~/.config/claude-seo/google-api.json. Use when user says "google data", "page speed", "core web vitals", "search console", "indexation", "GA4", "keyword research", "nlp entities", "blog performance", "youtube search", "google api setup".