Skip to content

API and MCP recipes

Three hand-written recipes for render.cuelark.com: an n8n HTTP Request that saves a 1200×630 Open Graph PNG, Cursor connected to the MCP server, and a Next.js generateMetadata helper that uses the image URL directly. We ran each HTTP and MCP call on 15 Nov 2026. No API key is required for charts or cards.

1. n8n: download an OG image

n8n's HTTP Request node can treat the response as a file. Point it at a GET /v1/og URL. The same URL is valid in curl, which is what we tested: HTTP 200, image/png, 1200×630.

  1. Add a Manual Trigger and an HTTP Request node (type version 4.2 works).
  2. Method: GET. URL: the query below. Options → Response → Response Format: File.
  3. Run the workflow. The binary output is card.png. You can post it to Slack, attach it to email, or write it to disk.
bash
curl -sL "https://render.cuelark.com/v1/og?template=blog&title=How+we+ship+faster+with+fewer+meetings&description=Five+habits+from+a+remote+team&eyebrow=Blog&author=Sam+Lee&site=example.com" -o card.png

To make a chart instead, POST JSON to /v1/chart. At scale: 2 the PNG is 1600×900. We tested this body too:

bash
curl -sL -H 'content-type: application/json' \
  -d '{"chart":{"type":"bar","title":"Signups by channel","labels":["Organic","Paid","Referral"],"datasets":[{"label":"November","data":[56,29,18]}]},"scale":2}' \
  -o chart.png https://render.cuelark.com/v1/chart

Importable n8n workflow (trigger + HTTP Request, response format File):

json
{
  "name": "Cuelark OG image",
  "nodes": [
    {
      "parameters": {},
      "id": "start-cuelark-og",
      "name": "When clicking ‘Test workflow’",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "url": "https://render.cuelark.com/v1/og?template=blog&title=How+we+ship+faster+with+fewer+meetings&description=Five+habits+from+a+remote+team&eyebrow=Blog&author=Sam+Lee&site=example.com",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "id": "http-cuelark-og",
      "name": "Download OG image",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        260,
        0
      ]
    }
  ],
  "connections": {
    "When clicking ‘Test workflow’": {
      "main": [
        [
          {
            "node": "Download OG image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}

2. Cursor: Render MCP server

The server lives at https://render.cuelark.com/mcp (Streamable HTTP, no sign-in required for charts and cards). Same install format as the MCP setup page.

  1. Save this as .cursor/mcp.json in your project, or paste it under Cursor Settings → MCP.
  2. Reload MCP. You should see four tools: render_chart, social_card, html_to_pdf and screenshot_url.
  3. Ask Cursor: “Call social_card with template blog, title ‘How we ship faster with fewer meetings’, description ‘Five habits from a remote team’, author Sam Lee, site example.com.” It returns a PNG, a permanent image URL, and meta tags you can paste.
json
{
  "mcpServers": {
    "cuelark-render": {
      "url": "https://render.cuelark.com/mcp"
    }
  }
}

Equivalent tool arguments (we called tools/call with this payload; the returned URL is a 1200×630 PNG):

json
{
  "name": "social_card",
  "arguments": {
    "template": "blog",
    "title": "How we ship faster with fewer meetings",
    "description": "Five habits from a remote team",
    "eyebrow": "Blog",
    "author": "Sam Lee",
    "site": "example.com"
  }
}

3. Next.js: generateMetadata and og:image

The GET URL is the image, so you do not need a Route Handler or opengraph-image.tsx unless you want the file to be served from your own origin. Put the URL in generateMetadata. The helper below produces the same URL we fetched: https://render.cuelark.com/v1/og… (1200×630 PNG, cached).

  1. Copy the generateMetadata helper into your App Router project (Next.js 13+).
  2. Pass each page's title, description and author into ogImageUrl.
  3. Set openGraph.images and twitter.images to that URL, with width 1200 and height 630.
ts
import type { Metadata } from "next";

const API = "https://render.cuelark.com";

export function ogImageUrl(post: {
  title: string;
  description?: string;
  author?: string;
  date?: string;
}): string {
  const q = new URLSearchParams({
    template: "blog",
    title: post.title,
    site: "example.com",
    eyebrow: "Blog",
  });
  if (post.description) q.set("description", post.description);
  if (post.author) q.set("author", post.author);
  if (post.date) q.set("date", post.date);
  return `${API}/v1/og?${q}`;
}

export function generateMetadata({ post }: { post: { title: string; description: string; author?: string } }): Metadata {
  const image = ogImageUrl(post);
  return {
    title: post.title,
    description: post.description,
    openGraph: {
      title: post.title,
      description: post.description,
      images: [{ url: image, width: 1200, height: 630, alt: post.title }],
    },
    twitter: { card: "summary_large_image", title: post.title, description: post.description, images: [image] },
  };
}

// Example values used in the test (swap in your CMS post):
export const examplePost = {
  "title": "How we ship faster with fewer meetings",
  "description": "Five habits from a remote team",
  "author": "Sam Lee"
};

Preview the example image: https://render.cuelark.com/v1/og?template=blog&title=How+we+ship+faster+with+fewer+meetings&description=Five+habits+from+a+remote+team&eyebrow=Blog&author=Sam+Lee&site=example.com

Full parameter lists are on the API docs. Limits, errors and URL safety rules are unchanged. Recipes last tested 15 Nov 2026.

Frequently asked questions

Do I need an API key?

No. Charts and social cards are free today, with a rate limit of 120 requests per minute per IP. Browser renders (PDF and screenshots) have a small daily cap. You can add a Render-scoped key later at auth.cuelark.com if you want a higher cap.

How do I get a chart PNG in n8n, not just an OG image?

Use an HTTP Request node with POST to https://render.cuelark.com/v1/chart, Content-Type application/json, and a body like the chart example on this page. Set the response format to File so the next node receives a PNG (1600×900 at scale 2).

Where does the Cursor MCP config go?

Put the JSON in your project's .cursor/mcp.json, or in Cursor Settings → MCP. After it connects you should see four tools: render_chart, social_card, html_to_pdf and screenshot_url. Then ask Cursor to call social_card with a title and template.

Should Next.js use the /v1/og URL as og:image, or fetch and host the PNG?

Use the URL as og:image. GET /v1/og is the image: it is cached at the edge (24 hours in browsers, 30 days at the CDN) and needs no key. Fetch-and-host is only needed if you upload a logo or background photo, because those POST-only cards have no permanent URL.

Can I put a logo on the card from Next.js or n8n?

Yes, with POST /v1/og and a logo or bgImage field as a base64 data URL under the size cap. Those cards are not given a permanent query URL, so save the PNG and host it with your site.