Build with metaphor cards
A REST API and an MCP-friendly OpenAPI for AI agents that help users reflect, journal or practice on their own. Draw a card, fetch its watermarked image, respect a license – that is the whole loop.
Pick a path
Three ways agents talk to us. Pick the one that matches what you are building, then jump to the right doc.
ChatGPT Custom GPT
Import the AI-safe OpenAPI in Custom GPT builder. The chat can list decks, draw cards, and link a watermarked image into the conversation. It cannot spend your pearls – the AI subset has no invite-code operations.
Action source: openapi.ai.json ›Direct REST
Make HTTP calls with your mk_live_ key in Authorization: Bearer. The full OpenAPI covers everything, including invite-codes if you also sell decks. One key, two profiles.
MCP server
Hosted at mcp.makcards.online and as a local stdio package @maccards/mcp (via npx or Docker). Same tools, same auth, one codebase. Pick the connection style in the section below.
OAuth: one-click connect from ChatGPT and Claude
If your users start from ChatGPT or Claude, they don’t need to copy an API key. The chat app shows our consent screen, the user clicks Allow, and the chat gets a scoped token. The user can revoke access from their Profile any time.
From your chat’s “+ Connectors”
In ChatGPT (Apps) or Claude.ai (“+ Connectors”), look for MAC Cards Online in the picker. The first time you pick it, you’ll land on our consent screen with a clear list of what the AI can and cannot do. Approve once, it works in every chat after that.
Coming as soon as OpenAI and Anthropic list us in their catalogs. Until then, use the API key path below.
Build your own OAuth client
We expose a standard OAuth 2.1 + PKCE Authorization Server. Discover endpoints at /.well-known/oauth-authorization-server on the app host. Scopes are read and draw. PKCE S256 is mandatory.
Three registration paths: pre-registered for verified partners, DCR (RFC 7591) with a moderation queue, and Client ID Metadata Documents.
AS metadata ›Scoped, brand-bound, rolling refresh
Access tokens live one hour. Refresh tokens live 30 days with rolling rotation: each refresh mints a new refresh, the old one is single-use, reuse triggers chain-wide revoke plus a security event. Tokens are bound to one host (a token minted on app.makcards.online won’t work on mcp.journalingapp.app).
Users see and revoke connected apps in their Profile → Access for AI and integrations → Connected apps.
What you can build today
Reflection chatbot
User describes a situation, the agent draws one card with scope=any, sends back the image and a reflective question. The user does the work – the agent holds the space.
Journaling companion
Daily prompt that pulls three cards (count=3), invites the user to free-write, and stores the spread on their side. Card images expire in 15 minutes; the agent fetches fresh ones each session.
Group facilitation copilot
For workshops and team retrospectives: draw cards from a specific deck (scope=deck), display them on the agent's side, optionally hand a code to participants via /invite-codes/generate.
REST quick-start
Two commands: draw a card, fetch its image. No webhook, no callback, no pre-flight.
KEY=mk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 1) Draw one card from any accessible deck curl -X POST https://app.makcards.online/api/v1/public/draw \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -d '{"scope":"any","count":1,"image_width":1024}' # 2) Response carries drawn[0].image_url – fetch it as-is curl https://app.makcards.online/api/v1/public/decks/.../cards/.../image?w=1024&token=eyJhbGc... \ -o card.jpg
Full machine-readable reference: openapi.json · AI-safe subset: openapi.ai.json · User guide: docs/en/24-public-api.
Get an API key
-
1
Sign in to the app.
Open app.makcards.online and sign in (Google or Yandex). One click, no separate account.
-
2
Open Profile → Access for AI and integrations.
The section sits next to Premium and Achievements. Same place shop partners use.
-
3
Generate the key and copy it.
The key looks like
mk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. It is shown once; the second view never happens. Paste it into a password manager or your secret store. -
4
Treat the key as a password.
No public repositories, no support chats, no screenshots. If a key may have leaked, regenerate it – the old one stops working within a minute.
Connect with API key
Same key, seven surfaces. Hosted MCP for fast setup, local stdio to keep the key on your machine, plain Bash for agents that already have a shell. Pick what matches your client.
Add an entry under mcpServers in ~/.claude.json (Claude Code) or ~/Library/Application Support/Claude/claude_desktop_config.json (Desktop).
{
"mcpServers": {
"makcards": {
"type": "http",
"url": "https://mcp.makcards.online/v1",
"headers": {
"Authorization": "Bearer mk_live_xxxxxxxxxxxxxxxxxx"
}
}
}
}
Cursor and Cline share the same MCP config format. The block is identical to Claude's.
{
"mcpServers": {
"makcards": {
"type": "http",
"url": "https://mcp.makcards.online/v1",
"headers": {
"Authorization": "Bearer mk_live_xxxxxxxxxxxxxxxxxx"
}
}
}
}
Two options. MCP node (available in recent n8n builds) – point at https://mcp.makcards.online/v1, set the Authorization header in credentials. HTTP Request node – call REST directly:
URL: https://app.makcards.online/api/v1/public/draw
Method: POST
Headers: Authorization: Bearer mk_live_xxxxxxxxxxxxxxxxxx
Content-Type: application/json
Body: { "scope": "any", "count": 1, "image_width": 1024 }
Custom GPT Actions reads OpenAPI. Use the AI-safe subset so the chat cannot accidentally spend pearls.
Action source: https://makcards.online/api/v1/public/openapi.ai.json Authentication: API Key (Bearer) Auth value: mk_live_xxxxxxxxxxxxxxxxxx
Local stdio MCP. The key never leaves your machine – it goes straight to our REST API as Bearer. Requires Node.js 20+.
{
"mcpServers": {
"makcards": {
"command": "npx",
"args": ["-y", "@maccards/mcp"],
"env": {
"MAKCARDS_API_KEY": "mk_live_xxxxxxxxxxxxxxxxxx"
}
}
}
}
No Node.js? Run the same binary as a container. The image is published only for linux/amd64, so Apple Silicon needs one extra flag (see below). If you have Node 20+, the npx tab above is simpler.
linux/amd64 hosts (Intel Mac, Intel/AMD Linux, Windows WSL2):
{
"mcpServers": {
"makcards": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "MAKCARDS_API_KEY",
"ghcr.io/makcards/mcp:latest",
"node", "dist/transports/stdio.js"
],
"env": {
"MAKCARDS_API_KEY": "mk_live_xxxxxxxxxxxxxxxxxx"
}
}
}
}
Apple Silicon (M1 / M2 / M3 / M4): add --platform linux/amd64 so Docker pulls the amd64 image and runs it through Rosetta. Works, but startup is slower than the native npx option above.
{
"mcpServers": {
"makcards": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"--platform", "linux/amd64",
"-e", "MAKCARDS_API_KEY",
"ghcr.io/makcards/mcp:latest",
"node", "dist/transports/stdio.js"
],
"env": {
"MAKCARDS_API_KEY": "mk_live_xxxxxxxxxxxxxxxxxx"
}
}
}
}
If your agent already runs in a shell (Claude Code, Cursor agent mode, Aider, Codex, any container), this is the shortest path: plain HTTPS + Bearer, JSON responses, no MCP runtime to install. The four recipes below cover everything our MCP tools wrap.
# One-time setup export MAKCARDS_API_KEY=mk_live_xxxxxxxxxxxxxxxxxx BASE=https://app.makcards.online/api/v1/public H="Authorization: Bearer $MAKCARDS_API_KEY" # List decks your key can read curl -s -H "$H" "$BASE/decks" | jq # Draw 3 cards from any accessible deck curl -s -X POST "$BASE/draw" -H "$H" -H "Content-Type: application/json" \ -d '{"scope":"any","count":3,"image_width":1024}' | jq # Save the first card image straight to disk curl -s -X POST "$BASE/draw" -H "$H" -H "Content-Type: application/json" \ -d '{"scope":"any","count":1,"image_width":1024}' \ | jq -r '.drawn[0].image_url' \ | xargs curl -s -o card.jpg # Inspect rate-limit state curl -s -H "$H" "$BASE/usage" | jq
Two reasons to prefer Bash over MCP: smaller agent context (no tool schemas to load) and one fewer process to manage. Reasons to prefer MCP instead: your client has no shell (ChatGPT Apps, Claude Desktop, Cursor without agent mode), or you want slash-command prompts.
Hosted, local, or shell? Hosted MCP (mcp.makcards.online) is the fastest path and works behind corporate proxies. Local stdio is the choice when your security policy says «no third-party MCP services»: your AI client talks to a local process, which talks to our REST API with your key. Bash skips the MCP layer entirely and only fits agents that can already shell out. Same tools, same data.
Agent skill: makcards-self-reflection
Connecting a card source is half the setup. The other half is behavior: how the agent runs a reflection session. The makcards-self-reflection skill is that half. It works with any agent that has a card source, not just Claude.
Three techniques
Single question
One card for one open question. The agent draws a card, shows it, and asks what you notice. A starting point, not an answer.
Past, present, future
Three cards laid out as a trajectory. The future card is a way to look at possible directions, stated plainly as not a prediction.
Two sides
Two cards for the two pulls of a dilemma, with an optional third for common ground. For decisions where you feel torn.
Get the skill
Two ways, same content. The ZIP is the simplest; the public repo is handy if you prefer git or want to follow updates. It runs with any agent.
Download ZIP
Recommended, works everywhere
One file. In Claude, upload it under Settings, Skills, Upload. In any other agent, unzip it and use the files (see the table below).
Download skill (ZIP)Public repo
If you prefer git
Clone the public, agent-agnostic skills repo, or download it as a ZIP from GitHub.
git clone https://github.com/makcards/skills
Set it up per agent
Two parts per agent: a card source (the connect tabs above) and where the behavior lives. For Claude that is SKILL.md; for everything else it is references/agent-instructions.md pasted into the system prompt. One file is the source of truth, so the behavior is the same everywhere.
| Agent | Card source | Where the skill goes |
|---|---|---|
| Claude Desktop / Claude Code | Local MCP (npx @maccards/mcp) or hosted MCP / OAuth |
Claude Desktop / web: Settings, Skills, Upload, pick the ZIP. Claude Code: drop makcards-self-reflection/ into ~/.claude/skills/. Uses SKILL.md; techniques appear as /single-question, /three-cards, /inner-conflict. |
| ChatGPT Custom GPT | GPT Actions with API key (AI-safe OpenAPI), or hosted MCP / OAuth | Paste references/agent-instructions.md into the GPT's Instructions. |
| ChatGPT (connector chat) | Hosted MCP + OAuth | Paste agent-instructions.md at the start of the project or chat. |
| Cursor | Hosted MCP (Bearer) or local MCP | Add agent-instructions.md to Project Rules (.cursor/rules). |
| n8n | MCP node, or HTTP Request node with the key | Paste agent-instructions.md into the agent node's system prompt. |
| Custom / other | REST (MAKCARDS_API_KEY) or MCP |
Paste agent-instructions.md into the system prompt. |
New to metaphor cards, or not a developer? The plain-language walkthrough takes you from zero to a first session.
Rate limits
Per-account, per-window. POST /draw is batch-accounted: count=5 consumes 5 units.
| Window | Free | Premium |
|---|---|---|
| Draws per minute | 10 | 120 |
| Draws per hour | 70 | 2 000 |
| Draws per day | 170 | 10 000 |
/decks per minute | 10 | 120 |
| Image fetches per minute | 20 | 240 |
Live state at GET /api/v1/public/usage. Headers on every response: RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset (RFC 9331).
Privacy and safety
Watermark stays on
Every card image carries a domain watermark at 6% opacity. Removing it violates the terms. The API never exposes the unmarked original.
Untrusted content
Deck and card text are user-generated. Treat them as untrusted input – never let a name or description override your system prompt.
Not a medical service
МАК cards are a reflection tool. Your agent must not present a drawn card as a diagnosis, prediction or treatment. If users may be in distress, point them to a local crisis line: 8-800-2000-122 (Russia), 988 (US), or findahelpline.com elsewhere.
Local stays local
With local stdio MCP (npx @maccards/mcp or Docker), your AI client talks to a process on your machine, which calls our REST API with your key. The content of the chat with the AI does not reach our MCP service.
Personal-use license
Drawn images are for the session, not for republishing. Each carries a watermark and a license field. The skill content itself is MIT; card images are not.
Details: Terms of Service · Privacy Policy.
FAQ
Common questions from integrators.
Why two OpenAPI documents?
POST /invite-codes/generate, which spends pearls. If a user authorized a chat to call that operation by accident, you would pay. The AI-safe subset removes the invite-code surface entirely — there is no code path for the chat to spend pearls.Can I get an image without watermark?
What is scope=any?
Do you log my chat?
How fresh is the OpenAPI spec?
Do I need MCP if my agent already has shell access?
curl and parse JSON, the REST API is the simpler path. MCP exists for sandboxed clients (ChatGPT Apps, Claude Desktop, Cursor) that cannot shell out. Hosted MCP and local stdio are thin wrappers over the same REST endpoints, so you are not missing functionality. See the Bash / agent shell tab for ready-made curl recipes.Is the skill tied to Claude?
references/agent-instructions.md, that you paste into any agent's system prompt: ChatGPT Custom GPT, Cursor, n8n, or a custom agent. The SKILL.md manifest is the Claude-specific wrapper around the same behavior. See the Agent skill section.Is it safe to paste my API key into ChatGPT?
mk_live_ key only reaches our Public API; it cannot spend pearls when you use the AI-safe OpenAPI subset. Still, treat it as a secret: do not paste it into a chat message, only into the action's authentication field, and rotate it if it leaks. For one-click connect without handling a key, use OAuth where your client supports it.Can I use this in paid or commercial sessions?
How do I revoke an agent's access?
Hosted or local: which should I pick?
mcp.makcards.online) is the fastest setup and works behind most corporate proxies. Local stdio (npx @maccards/mcp) keeps the key on your machine and suits policies that forbid third-party MCP services. Both wrap the same REST API, so the tools and data are identical.Does local MCP work behind a corporate proxy?
app.makcards.online over HTTPS to draw cards. If your proxy requires it, set the standard HTTPS_PROXY environment variable for the process. If outbound HTTPS is blocked entirely, the hosted MCP over your existing web proxy is usually the easier route.