MCP server

Connect Advent Calendar Maker to Claude, Cursor or any other MCP client and let your assistant build the calendar: plan the doors with you, fill them in one go, and tell you later which door was opened most.

Last updated: 2026-09-29

Get an API key

API and MCP access is included in Premium (£159 per year) and Enterprise (£999 per year). Write to [email protected] with your account email and we send you a test key and a live key.

Request a key

Overview

The Model Context Protocol (MCP) is an open standard that lets AI assistants use outside tools. Our MCP server offers the functions of the REST API as tools the assistant can call itself.

What that looks like in practice: you tell your assistant "make an advent calendar for our newsletter, a discount behind every door, doors open at 8", answer two or three questions, and a few minutes later you have a public link.

  • Plan a calendar in conversation and create it with the right dates, time zone and design.
  • Fill all doors from a list, a spreadsheet or a product feed you paste in.
  • Change single doors later ("swap door 12 for the new gift card").
  • Ask for numbers ("which doors were opened least?").

Access

The MCP server uses the same keys as the API and is included in Premium (£159 per year) and Enterprise (£999 per year) at no extra cost. Keys are issued by hand; write to [email protected].

The assistant has exactly the features of your plan. It cannot upgrade the plan, pay or change billing. If you ask for something your plan does not include, it tells you which plan you need and where to change it.

Server address

The server speaks MCP over Streamable HTTP at https://mcp.adventcalendarmaker.co.uk/mcp. Authentication is the API key as bearer token.

bash Check that the server is reachable
curl https://mcp.adventcalendarmaker.co.uk/health
# {"status":"ok","protocol":["2025-06-18","2025-03-26"]}

Set up your client

Claude Code

bash One command in the terminal
claude mcp add --transport http advent-calendar \
  https://mcp.adventcalendarmaker.co.uk/mcp \
  --header "Authorization: Bearer $ACM_API_KEY"

Claude Desktop

Claude Desktop connects remote servers through mcp-remote. Add this to claude_desktop_config.json and restart the app.

json claude_desktop_config.json
{
  "mcpServers": {
    "advent-calendar": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://mcp.adventcalendarmaker.co.uk/mcp",
        "--header", "Authorization: Bearer ${ACM_API_KEY}"
      ],
      "env": { "ACM_API_KEY": "sk_live_..." }
    }
  }
}

Cursor and other clients

Clients that support remote servers directly only need the URL and the header.

json .cursor/mcp.json
{
  "mcpServers": {
    "advent-calendar": {
      "url": "https://mcp.adventcalendarmaker.co.uk/mcp",
      "headers": { "Authorization": "Bearer ${env:ACM_API_KEY}" }
    }
  }
}

Use a sk_test_ key while you try things out. Test calendars look real, carry a test banner and disappear after 30 days.

Tools

ToolScopeWhat it does
create_calendarcalendars:writeCreates a calendar with title, date range, opening time, time zone and design.
list_calendarscalendars:readLists your calendars, optionally only those running on a given day.
get_calendarcalendars:readSettings, public link and all doors of one calendar.
update_calendarcalendars:writeChanges settings such as dates, opening time, design or animation.
set_doorcalendars:writeWrites the content of one door.
fill_doorscalendars:writeWrites up to 50 doors in one call. By default it does not overwrite doors that already have content.
add_media_from_urlcalendars:writeFetches an image or video from a public URL and returns a media id for a door.
get_statsstats:readViews and opens per door.
list_optionscalendars:readTemplate styles, background designs, tags, content types and what the current plan allows.

There is deliberately no tool to delete a calendar. Deleting stays a decision you make in the editor or through the API.

Tool definitions

Every tool comes with a JSON Schema for its input and a description written for the model. The descriptions contain the rules the assistant has to follow, for example that it must not invent coupon codes.

json Definition of fill_doors
{
  "name": "fill_doors",
  "description": "Writes content into several doors of a calendar at once. Only use content the user gave or approved. Never invent coupon codes, prices or links.",
  "inputSchema": {
    "type": "object",
    "required": ["calendar_id", "doors"],
    "properties": {
      "calendar_id": { "type": "string" },
      "doors": {
        "type": "array",
        "maxItems": 50,
        "items": {
          "type": "object",
          "required": ["day", "content_type"],
          "properties": {
            "day": { "type": "integer", "minimum": 1, "maximum": 50 },
            "content_type": { "type": "string", "enum": ["text", "embed", "link", "image", "video", "coupon", "quiz", "product", "event", "giveaway", "download", "survey", "music"] },
            "title": { "type": "string", "maxLength": 255 },
            "text": { "type": "string" },
            "url": { "type": "string", "format": "uri" },
            "coupon_code": { "type": "string", "maxLength": 64 },
            "data": { "type": "object", "description": "Type specific fields: options, answer, price, date, time, location, prize, deadline, button, artist" },
            "media_id": { "type": "string" }
          }
        }
      },
      "overwrite": { "type": "boolean", "default": false }
    }
  },
  "annotations": { "readOnlyHint": false, "idempotentHint": true }
}

Tool results

Results contain a short text for the assistant to pass on, a link to the affected resource and structuredContent with the exact numbers, so the assistant does not have to guess from prose.

json Result of fill_doors
{
  "content": [
    {
      "type": "text",
      "text": "Saved 24 doors in \"Northwind Coffee Advent Calendar\". Door 1 opens on 1 December 2026 at 08:00 (Europe/Berlin). Public link: https://adventcalendarmaker.co.uk/c/k7x2mq9t/"
    },
    { "type": "resource_link", "uri": "calendar://cal_4Hq8nW2kLp", "name": "Calendar", "mimeType": "application/json" }
  ],
  "structuredContent": {
    "calendar_id": "cal_4Hq8nW2kLp",
    "doors_written": 24,
    "doors_skipped": 0,
    "doors_filled": 24,
    "door_count": 24
  },
  "isError": false
}

Resources

Besides tools, the server offers resources that a client can load into the conversation as context, for example to discuss an existing calendar before changing it.

text Resource URIs
calendar://{id}                  calendar settings and public link
calendar://{id}/doors            all doors with unlock times and content
calendar://{id}/doors/{day}      a single door
stats://{id}                     views, door opens, clicks, entries
backgrounds://catalog            background designs, styles and tags

Prompts

The server brings ready made prompts that clients show as commands. They guide the assistant through the right questions before it creates anything.

  • plan_marketing_calendar: customer calendar with one offer per door, for shops and brands.
  • plan_team_calendar: calendar for colleagues with greetings, quiz questions and small surprises.
  • plan_family_calendar: personal calendar with messages, photos and videos for someone you love.
  • review_calendar: checks an existing calendar for empty doors, broken links and doors that open on a weekend when the office is closed.
json Definition of plan_marketing_calendar
{
  "name": "plan_marketing_calendar",
  "description": "Plans a customer advent calendar with one offer per door and fills it after approval.",
  "arguments": [
    { "name": "brand", "required": true },
    { "name": "door_count", "description": "usually 24", "required": false },
    { "name": "offers", "description": "list of offers or products to feature", "required": false }
  ]
}

Example conversation

A coffee roaster builds a newsletter calendar with Claude. Tool calls are shown in square brackets.

text From idea to link in four turns
User:  We are a small coffee roaster. I want an advent calendar for our
       newsletter, 24 doors, a new discount every morning at 8.

Agent: [list_options] Sounds good. Which products should the doors feature,
       and do you already have coupon codes in your shop system?

User:  Filter coffee, espresso, the winter blend and our grinder. Codes are
       ADVENT01 to ADVENT24, all 15 % off, door 24 is 30 %.

Agent: [create_calendar: 2026-12-01 to 2026-12-24, 08:00, Europe/Berlin,
        template_style=cozy]
       Here is my plan for the 24 doors: ... Shall I fill them like this?

User:  Yes, but door 6 should be a video from our roastery instead.

Agent: [fill_doors: 23 coupon doors]
       [set_door: day=6, content_type=embed, url=https://youtu.be/...]
       Done. All 24 doors are filled, door 1 opens on 1 December at 08:00.
       Link for the newsletter: https://adventcalendarmaker.co.uk/c/k7x2mq9t/

What the assistant does not do

  • It does not invent coupon codes, prices, links or legal texts. If content is missing, it asks you.
  • It shows you the plan for all doors before it fills them, and it does not overwrite doors with content unless you agree.
  • It does not delete calendars and does not change your plan or payment details.
  • It does not set a password or tracking code unless you give it one.
  • It never sees data of your visitors, only the aggregated numbers from get_stats.

These rules are in the tool descriptions and are also enforced by the server: fill_doors without overwrite: true skips doors that are already filled, and a delete tool does not exist.

Scopes

On request we issue a key with fewer rights, for example for an assistant that should only report numbers.

ScopeAllows
calendars:readlist_calendars, get_calendar, list_options and the resources.
calendars:writeAdditionally create_calendar, update_calendar, set_door, fill_doors, add_media_from_url.
stats:readget_stats and stats://.

Tools outside the scope of the key are not listed to the client at all.

Errors

If a tool call fails, the result has isError: true and a text that tells the assistant what went wrong and what it can do next. That way it can correct itself or ask you instead of giving up.

json Door outside the date range
{
  "content": [
    {
      "type": "text",
      "text": "Door 25 does not exist: this calendar runs from 2026-12-01 to 2026-12-24 and has 24 doors. Ask the user whether to extend end_date with update_calendar (up to 50 doors) or to drop door 25."
    }
  ],
  "isError": true
}

Plan limits come back the same way: the text names the plan that is needed and asks the assistant to tell you.

Limits

Tool calls count against the same rate limit as the API (120 requests per minute per key); fill_doors counts as one call. Media from add_media_from_url follow the same size limits: images up to 2 MB, videos up to 20 MB, audio files and downloads up to 10 MB.

Privacy

The MCP server stores nothing of your conversation. It receives only the tool calls and their arguments, the same as an API request, and keeps request logs for 30 days for support.

What your assistant does with the results depends on its provider. If door content is confidential, check the data settings of your AI client.

Support

If your client does not connect or a tool behaves differently than described, write to [email protected] with the name of the client, the tool and the time. We read every message.

Get an API key

API and MCP access is included in Premium (£159 per year) and Enterprise (£999 per year). Write to [email protected] with your account email and we send you a test key and a live key.

Request a key