Skip to content

Session Log — 2026-07-11

OpenCode as a chat agent / MCP discussion

  • User asked whether an MCP could turn OpenCode into a general chat agent.
  • Conclusion: OpenCode is already a general chat agent; MCPs extend capabilities (tools/data/channels), they don't change the core nature.
  • Noted available local tooling for image work: ImageMagick (convert/mogrify) and Pillow 12.3 are installed.

Built: canva-design OpenCode skill (local Canva-style generator)

User wanted "more like Canva" — i.e. design generation (templates, text overlays, branded graphics), not just pixel edits.

Researched two paths: 1. Official Canva MCP — hosted at https://mcp.canva.com/mcp, OAuth2 via mcp-remote bridge, needs a Canva account. True Canva, cloud-bound. 2. Local skill — generate designs locally, no account. Chosen by user (all design types: social posts, thumbnails/banners, flyers, quote/branded graphics).

Confirmed global skill path: ~/.config/opencode/skills/<name>/SKILL.md (name must be lowercase-hyphen, match dir).

Files created (~/.config/opencode/skills/canva-design/)

  • SKILL.md — frontmatter + workflow + dimensions catalog + render/preview commands
  • templates/ — 9 starter HTML/CSS templates:
  • social-post.html 1080×1080 · story.html 1080×1920 · linkedin-banner.html 1584×396
  • youtube-thumbnail.html 1280×720 · banner.html 1200×628 · flyer.html 1080×1350
  • quote-card.html 1080×1080 · announcement.html 1080×1080 · logo.html 600×600
  • lib/render.jsnode lib/render.js <in.html> <out.png> <w> <h> [scale]; renders via cached Chromium (Playwright). Installed playwright into lib/ (browsers already cached). Default scale 2 → 2× crisp output.
  • lib/serve.jsnode lib/serve.js <file> [port]; serves over localhost + opens in browser (xdg-open). For HTML previews user can refresh after edits.
  • lib/brand.json — default brand kit (colors/fonts/logo) to persist the user's brand.

Browser preview added

  • Agent cannot read images, so added serve.js to display designs in the user's browser.
  • Verified DISPLAY=:1 is set → xdg-open opens a real window. Remote note: ssh -L 8787:localhost:8787.

Verification

  • All 9 templates rendered to correct dimensions (e.g. 1080×1080 → 2160×2160 at 2×).
  • End-to-end test: custom "Summer Sale" post (orange + black) rendered successfully.

Test: LEMO Instagram post

Generated an Instagram post for LEMO EGG.2B.302.CLL as a skill demo (user confirmed it was just a test, "well done").

  • Source image: original product image EGG_CLL.webp from the Shopify store (https://cdn.shopify.com/s/files/1/1050/7662/1393/files/EGG_CLL.webp), converted to egg_cll.png (450×450).
  • Product context (from store + lemo.com): EGG.2B.302.CLL = 2-pin panel socket, fixed panel front mount, solder, IP50, −55→+250°C, 5000 mating cycles, chrome-plated brass, push-pull self-latching, B Series.
  • Output: /home/dini/designs/lemo/instagram-post.{html,png} (2160×2160), served at http://localhost:8787/instagram-post.png.

Notes / follow-ups

  • ~ does NOT expand in the OpenCode bash tool shell — use absolute paths (/home/dini/...).
  • Could add a /design slash command and more template styles later.
  • Official Canva MCP remains an option if true Canva integration is ever wanted.

Edited: Shopify Import Tool V12 — added global Tags column

User wanted the v12 metafield tool (/home/dini/Downloads/work/Shopify_import_tool_V12.html) to output a Tags column.

Decision: a manual global Tags box (not auto-derived from metafields). User types comma-separated tags once; that value is written to the Tags column of every exported product row.

Changes made to Shopify_import_tool_V12.html

  • New #globalTags text input in the Metafields card (under the bulk-apply row).
  • New #pTags preview in the Preview card (live badge preview as you type).
  • globalTags variable, persisted to localStorage (v12_global_tags); input listener updates it + the preview live.
  • render() shows #pTags.
  • exportCSV(): header now Handle,Title,Body (HTML),Variant SKU,Tags,...; every row gets the tags value (normalized: trimmed, comma-joined).
  • Backup saved as Shopify_import_tool_V12.bak.html before editing.

Verification (headless Playwright)

  • Unit: normalization + preview correct.
  • E2E: loaded real shopify_metafield_export.csv (47 products) → 47 export rows → Tags column at index 4 (after Variant SKU) → all 47 rows contain the entered tags. PASS.

Notes

  • Tags are global (one value → all rows), per user's "on every product line" intent.
  • Out of scope (user dropped earlier idea): auto-deriving tags from Series/Size metafields.