Koskamo

Perkadoo MCP

An official MCP server provided by Perkadoo that allows AI assistants to manage giveaways, streak programs, and perks. It supports picking verifiable winners, creating share cards, and running hosted campaigns, with optional authentication for advanced features.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Perkadoo MCP logo, by PerkadooVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-01Operated by Perkadoo
You need:You don't need an account to start.Without an account, use is rate limited per network: 10 draws a minute and 200 a day.When you ask for something that needs your account, your assistant asks you to connect Perkadoo.
MCP endpoint (Streamable HTTP)
https://mcp.perkadoo.com/mcp
Vendor documentation

What you can do with it

  • Pick verifiable giveaway winners from a list
  • Create and manage hosted giveaways and perks
  • Run streak programs and track member progress
  • Generate shareable winner and streak cards

Source and maintenance

Vendor evidenceRegistry 0.4.0

Protocol and capabilities

Server
perkadoo 0.4.0
MCP protocol
2025-06-18
Tools
22 advertised
Resources
1 advertised
Resource templates
0 advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "resources": {
    "listChanged": true
  }
}

Tools

22 advertised

list_projects — List projects
Advertised by the server during the last successful anonymous check.
Advertised read-only

List the Perkadoo projects available to the authenticated MCP credential.

list_projects input schema
{
  "type": "object",
  "properties": {}
}
list_projects annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_streak_performance — Read streak performance
Advertised by the server during the last successful anonymous check.
Advertised read-only

Read the streak distribution, best streaks and progress for a program. Excludes synthetic test activity.

get_streak_performance input schema
{
  "type": "object",
  "required": [
    "campaignId"
  ],
  "properties": {
    "campaignId": {
      "type": "string",
      "format": "uuid",
      "description": "Streak program ID from list_programs."
    }
  }
}
get_streak_performance annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_proof_report — Read Proof results
Advertised by the server during the last successful anonymous check.
Advertised read-only

Read the latest holdout experiment, its sample sizes and measured return rate. Returns null when no experiment exists; never invents uplift.

get_proof_report input schema
{
  "type": "object",
  "required": [
    "campaignId"
  ],
  "properties": {
    "campaignId": {
      "type": "string",
      "format": "uuid",
      "description": "Streak program ID from list_programs."
    }
  }
}
get_proof_report annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_programs — List streak programs
Advertised by the server during the last successful anonymous check.
Advertised read-only

List a brand's streak programs with their event key, cadence, target and status.

list_programs input schema
{
  "type": "object",
  "required": [
    "brandId"
  ],
  "properties": {
    "brandId": {
      "type": "string",
      "format": "uuid",
      "description": "Brand ID, the project that runs the streak."
    }
  }
}
list_programs annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_perks — List perks
Advertised by the server during the last successful anonymous check.
Advertised read-only

List a brand's perks with how many have been granted, revealed to members and redeemed, and for coupons with a code pool, how many codes are left and how many grants are waiting for one.

list_perks input schema
{
  "type": "object",
  "required": [
    "brandId"
  ],
  "properties": {
    "brandId": {
      "type": "string",
      "format": "uuid",
      "description": "Brand ID, the project that offers the perk."
    }
  }
}
list_perks annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
create_perk — Create a perk
Advertised by the server during the last successful anonymous check.

Create a reward a brand can give members: a coupon code, a link or a message. Milestone rewards set in the dashboard are perks too.

create_perk input schema
{
  "type": "object",
  "required": [
    "brandId",
    "name",
    "kind",
    "value"
  ],
  "properties": {
    "kind": {
      "enum": [
        "coupon",
        "url",
        "message"
      ],
      "type": "string",
      "description": "coupon (a code), url (a link) or message (text)."
    },
    "name": {
      "type": "string",
      "maxLength": 100,
      "minLength": 1,
      "description": "What the brand calls this perk."
    },
    "value": {
      "type": "string",
      "maxLength": 500,
      "minLength": 1,
      "description": "The coupon code, link or message."
    },
    "brandId": {
      "type": "string",
      "format": "uuid",
      "description": "Brand ID, the project that offers the perk."
    },
    "expiresAt": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "null"
        }
      ],
      "description": "When the perk stops being shown, as an ISO 8601 time."
    },
    "validDays": {
      "anyOf": [
        {
          "type": "integer",
          "maximum": 3650,
          "minimum": 1
        },
        {
          "type": "null"
        }
      ],
      "description": "How many days a member has to use it after it's given, like 30. Null keeps it until the perk's own expiry."
    },
    "valueCents": {
      "anyOf": [
        {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": 0
        },
        {
          "type": "null"
        }
      ],
      "description": "What the perk is worth to a member, in cents."
    },
    "uniqueCodes": {
      "type": "boolean",
      "description": "Coupons only. true when each member needs their own code, like a gift card: members wait for one until codes are added, and never get the value."
    }
  }
}
create_perk annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
create_giveaway — Create a giveaway
Advertised by the server during the last successful anonymous check.

Draft a hosted giveaway: prize, dates, draw, entry page, bonus entries and official rules. It starts as a draft with a preview link. A signed-in person approves it at dashboardUrl before it goes live; send them that link.

create_giveaway input schema
{
  "type": "object",
  "required": [
    "brandId",
    "name",
    "opensAt",
    "closesAt"
  ],
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 100,
      "minLength": 1,
      "description": "The giveaway's name, shown as its title."
    },
    "rules": {
      "type": "object",
      "default": {
        "fields": {},
        "document": null
      },
      "properties": {
        "fields": {
          "type": "object",
          "default": {},
          "description": "The official rules generator's operator fields: sponsor, eligibility and so on.",
          "propertyNames": {
            "type": "string",
            "maxLength": 64
          },
          "additionalProperties": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "array",
                "items": {
                  "type": "string",
                  "maxLength": 200
                },
                "maxItems": 60
              }
            ]
          }
        }
      },
      "description": "The official rules. sponsorCountry and countries default to the brand's own country. A person approves them before the giveaway goes live."
    },
    "prizes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "label"
        ],
        "properties": {
          "label": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1
          },
          "perkId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "A perk from this brand to give the winner of this place."
          }
        }
      },
      "default": [],
      "maxItems": 100,
      "description": "One prize per place for placed draws; otherwise the first prize goes to every winner."
    },
    "brandId": {
      "type": "string",
      "format": "uuid",
      "description": "Brand ID, the project that runs the giveaway."
    },
    "opensAt": {
      "type": "string",
      "format": "date-time",
      "description": "When entries open, as an ISO 8601 time."
    },
    "closesAt": {
      "type": "string",
      "format": "date-time",
      "description": "When entries close, as an ISO 8601 time. Must be after opensAt."
    },
    "language": {
      "enum": [
        "en",
        "es"
      ],
      "type": "string",
      "description": "The language entrants see: en or es. Left out, the language of the brand's country, else en."
    },
    "timezone": {
      "type": "string",
      "maxLength": 64,
      "description": "The time zone the official rules and dashboard use, e.g. Europe/London. Left out, the brand's own: from its site's country domain, then its saved zone."
    },
    "entryPage": {
      "type": "object",
      "default": {},
      "properties": {
        "headline": {
          "type": "string",
          "maxLength": 120
        },
        "imageUrl": {
          "anyOf": [
            {
              "type": "string",
              "format": "uri",
              "maxLength": 1000
            },
            {
              "type": "null"
            }
          ]
        },
        "brandColor": {
          "anyOf": [
            {
              "type": "string",
              "pattern": "^#[0-9a-fA-F]{6}$"
            },
            {
              "type": "null"
            }
          ]
        },
        "description": {
          "type": "string",
          "maxLength": 2000
        },
        "bonusActions": {
          "type": "object",
          "description": "Bonus entries on offer: referral, share, follow and visit. Pro and up.",
          "propertyNames": {
            "enum": [
              "referral",
              "share",
              "follow",
              "visit"
            ],
            "type": "string"
          },
          "additionalProperties": {
            "type": "object",
            "required": [
              "enabled"
            ],
            "properties": {
              "url": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 1000
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Where the follow or visit action sends people."
              },
              "enabled": {
                "type": "boolean"
              },
              "entries": {
                "type": "integer",
                "maximum": 10,
                "minimum": 1,
                "description": "Entries this action is worth."
              }
            }
          }
        }
      },
      "description": "The hosted entry page's headline, description, image, brand color and bonuses."
    },
    "drawMethod": {
      "enum": [
        "single",
        "multiple",
        "placed"
      ],
      "type": "string",
      "default": "single",
      "description": "single: one winner. multiple: equal winners. placed: 1st, 2nd, 3rd…"
    },
    "winnerCount": {
      "type": "integer",
      "default": 1,
      "maximum": 100,
      "minimum": 1,
      "description": "How many winners to draw."
    }
  }
}
create_giveaway annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
update_giveaway — Update a giveaway
Advertised by the server during the last successful anonymous check.
Advertised destructive

Change a giveaway before it's drawn. Changing its dates, draw, prizes, rules or bonus entries clears its approval and returns it to draft; pause a live giveaway first. Headline, description, image and color can change any time.

update_giveaway input schema
{
  "type": "object",
  "required": [
    "giveawayId"
  ],
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 100,
      "minLength": 1,
      "description": "The giveaway's name, shown as its title."
    },
    "rules": {
      "type": "object",
      "properties": {
        "fields": {
          "type": "object",
          "default": {},
          "description": "The official rules generator's operator fields: sponsor, eligibility and so on.",
          "propertyNames": {
            "type": "string",
            "maxLength": 64
          },
          "additionalProperties": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "array",
                "items": {
                  "type": "string",
                  "maxLength": 200
                },
                "maxItems": 60
              }
            ]
          }
        }
      },
      "description": "The official rules. A person approves them before the giveaway goes live."
    },
    "prizes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "label"
        ],
        "properties": {
          "label": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1
          },
          "perkId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "A perk from this brand to give the winner of this place."
          }
        }
      },
      "maxItems": 100,
      "description": "One prize per place for placed draws; otherwise the first prize goes to every winner."
    },
    "opensAt": {
      "type": "string",
      "format": "date-time",
      "description": "When entries open, as an ISO 8601 time."
    },
    "closesAt": {
      "type": "string",
      "format": "date-time",
      "description": "When entries close, as an ISO 8601 time. Must be after opensAt."
    },
    "language": {
      "enum": [
        "en",
        "es"
      ],
      "type": "string",
      "description": "The language the entry page, results page and site banner speak to entrants: en or es."
    },
    "timezone": {
      "type": "string",
      "maxLength": 64,
      "description": "The time zone the official rules and dashboard use, e.g. America/New_York."
    },
    "entryPage": {
      "type": "object",
      "properties": {
        "headline": {
          "type": "string",
          "maxLength": 120
        },
        "imageUrl": {
          "anyOf": [
            {
              "type": "string",
              "format": "uri",
              "maxLength": 1000
            },
            {
              "type": "null"
            }
          ]
        },
        "brandColor": {
          "anyOf": [
            {
              "type": "string",
              "pattern": "^#[0-9a-fA-F]{6}$"
            },
            {
              "type": "null"
            }
          ]
        },
        "description": {
          "type": "string",
          "maxLength": 2000
        },
        "bonusActions": {
          "type": "object",
          "description": "Bonus entries on offer: referral, share, follow and visit. Pro and up.",
          "propertyNames": {
            "enum": [
              "referral",
              "share",
              "follow",
              "visit"
            ],
            "type": "string"
          },
          "additionalProperties": {
            "type": "object",
            "required": [
              "enabled"
            ],
            "properties": {
              "url": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 1000
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Where the follow or visit action sends people."
              },
              "enabled": {
                "type": "boolean"
              },
              "entries": {
                "type": "integer",
                "maximum": 10,
                "minimum": 1,
                "description": "Entries this action is worth."
              }
            }
          }
        }
      },
      "description": "The hosted entry page's headline, description, image, brand color and bonuses."
    },
    "drawMethod": {
      "enum": [
        "single",
        "multiple",
        "placed"
      ],
      "type": "string",
      "description": "single: one winner. multiple: equal winners. placed: 1st, 2nd, 3rd…"
    },
    "giveawayId": {
      "type": "string",
      "format": "uuid",
      "description": "Giveaway ID. It is also the giveaway's campaign ID for approval and status."
    },
    "winnerCount": {
      "type": "integer",
      "maximum": 100,
      "minimum": 1,
      "description": "How many winners to draw."
    }
  }
}
update_giveaway annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
get_giveaway — Read a giveaway
Advertised by the server during the last successful anonymous check.
Advertised read-only

Read a giveaway with its phase, approval, links, winners and numbers: entrants, entries, sources, entries by day, top referrers and flagged entries. dashboardUrl is where a signed-in person approves it or, once approved, draws it.

get_giveaway input schema
{
  "type": "object",
  "required": [
    "giveawayId"
  ],
  "properties": {
    "giveawayId": {
      "type": "string",
      "format": "uuid",
      "description": "Giveaway ID. It is also the giveaway's campaign ID for approval and status."
    }
  }
}
get_giveaway annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_giveaways — List giveaways
Advertised by the server during the last successful anonymous check.
Advertised read-only

List a brand's giveaways, newest first, with their phase and entry counts.

list_giveaways input schema
{
  "type": "object",
  "required": [
    "brandId"
  ],
  "properties": {
    "brandId": {
      "type": "string",
      "format": "uuid",
      "description": "Brand ID, the project that runs the giveaway."
    }
  }
}
list_giveaways annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_giveaway_entries — List giveaway entries
Advertised by the server during the last successful anonymous check.
Advertised read-only

List a giveaway's entries, newest first, with email, entries, source, referrer, status and risk signals. Filter by status to review flagged entries.

list_giveaway_entries input schema
{
  "type": "object",
  "required": [
    "giveawayId"
  ],
  "properties": {
    "limit": {
      "type": "integer",
      "default": 50,
      "maximum": 200,
      "minimum": 1
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0
    },
    "status": {
      "enum": [
        "valid",
        "flagged",
        "disqualified"
      ],
      "type": "string"
    },
    "giveawayId": {
      "type": "string",
      "format": "uuid",
      "description": "Giveaway ID. It is also the giveaway's campaign ID for approval and status."
    }
  }
}
list_giveaway_entries annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_goal — Read the brand's goal
Advertised by the server during the last successful anonymous check.
Advertised read-only

See how many new faces or returning members a brand has toward its goal, the target, the deadline and whether it's on pace. Returns null when no goal is set.

get_goal input schema
{
  "type": "object",
  "required": [
    "brandId"
  ],
  "properties": {
    "brandId": {
      "type": "string",
      "format": "uuid",
      "description": "Brand ID, the project Doo runs."
    }
  }
}
get_goal annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
set_goal — Set the brand's goal
Advertised by the server during the last successful anonymous check.

Aim a brand at more new faces or more returning members: a number to reach by a deadline. Doo plans around it and Home tracks it. Replaces the current goal, which is kept as history.

set_goal input schema
{
  "type": "object",
  "required": [
    "brandId",
    "metric",
    "target",
    "deadline"
  ],
  "properties": {
    "metric": {
      "enum": [
        "new_faces",
        "returning"
      ],
      "type": "string",
      "description": "new_faces counts first-time members who left an email. returning counts members active in two or more weeks."
    },
    "target": {
      "type": "integer",
      "maximum": 1000000,
      "minimum": 1,
      "description": "The number to reach."
    },
    "brandId": {
      "type": "string",
      "format": "uuid",
      "description": "Brand ID, the project Doo runs."
    },
    "deadline": {
      "type": "string",
      "format": "date-time",
      "description": "When to reach it, within the next 366 days. ISO 8601 with an offset."
    }
  }
}
set_goal annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
make_winners_card — Make a winners card
Advertised by the server during the last successful anonymous check.
Open-world

Make a square card announcing a drawn giveaway's winners, with emails masked: a public page link and a PNG to post. It publishes nothing itself.

make_winners_card input schema
{
  "type": "object",
  "required": [
    "giveawayId"
  ],
  "properties": {
    "giveawayId": {
      "type": "string",
      "format": "uuid",
      "description": "A drawn giveaway."
    }
  }
}
make_winners_card annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
get_draw — Read a draw result
Advertised by the server during the last successful anonymous check.
Open-world

Read and verify a Winner Picker result from its public slug. If randomness is now available, completes the previously committed draw. Returns the original winners and share image; never picks a replacement winner.

get_draw input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "pattern": "^[2-9a-z]{10}$"
    }
  }
}
get_draw annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
create_share_card — Make a share card
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Make a card for a win, streak, perk, giveaway entry or winner announcement. Returns a public page and PNG image in square, story or link size. Uses supplied text; it does not verify a winner, grant a perk or publish a social post. Never put private tokens or coupon codes in a card.

create_share_card input schema
{
  "type": "object",
  "required": [
    "template",
    "fields"
  ],
  "properties": {
    "site": {
      "type": "string",
      "format": "uri",
      "maxLength": 300,
      "description": "Optional website backlink. Query strings and fragments are removed."
    },
    "size": {
      "enum": [
        "square",
        "story",
        "link"
      ],
      "type": "string",
      "default": "square"
    },
    "theme": {
      "enum": [
        "ink",
        "light",
        "sun",
        "cobalt"
      ],
      "type": "string",
      "default": "ink"
    },
    "fields": {
      "type": "object",
      "description": "Template text: winner uses name, prize, from; streak uses days, habit, optional name; perk uses milestone, perk, from; entered uses giveaway, prize, from; announce uses title, winners (one per line), from.",
      "propertyNames": {
        "type": "string",
        "maxLength": 30
      },
      "additionalProperties": {
        "type": "string",
        "maxLength": 500
      }
    },
    "template": {
      "enum": [
        "winner",
        "streak",
        "perk",
        "entered",
        "announce"
      ],
      "type": "string"
    }
  }
}
create_share_card annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
draw_winners — Pick giveaway winners
Advertised by the server during the last successful anonymous check.
Open-world

Pick random winners from a list of names with Perkadoo's Winner Picker. The draw uses public drand randomness that didn't exist when the names were locked in, so anyone can check it. Returns the winners and a public results link to share.

draw_winners input schema
{
  "type": "object",
  "required": [
    "entrants"
  ],
  "properties": {
    "title": {
      "type": "string",
      "maxLength": 120,
      "description": "A name for the giveaway, shown on the results page."
    },
    "method": {
      "enum": [
        "single",
        "multiple",
        "placed"
      ],
      "type": "string",
      "default": "single",
      "description": "single: one winner. multiple: several equal winners. placed: 1st, 2nd, 3rd… with a prize per place."
    },
    "prizes": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 120
      },
      "maxItems": 100,
      "description": "Prize labels. For placed draws, one per place in order; otherwise one prize for every winner."
    },
    "entrants": {
      "anyOf": [
        {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 400
          },
          "maxItems": 10000
        },
        {
          "type": "string",
          "maxLength": 2000000
        }
      ],
      "description": "The entrants: an array of names, or text with one name per line. A name listed twice gets two entries."
    },
    "winnerCount": {
      "type": "integer",
      "default": 1,
      "maximum": 100,
      "minimum": 1,
      "description": "How many winners to pick."
    }
  }
}
draw_winners output schema
{
  "type": "object",
  "required": [
    "status",
    "entrantCount",
    "resultsUrl",
    "drandRound",
    "winners"
  ],
  "properties": {
    "title": {
      "type": "string"
    },
    "status": {
      "enum": [
        "committed",
        "drawn"
      ],
      "type": "string"
    },
    "winners": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "place"
        ],
        "properties": {
          "label": {
            "type": "string"
          },
          "place": {
            "type": "integer",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991
          },
          "prize": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    },
    "drandRound": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991
    },
    "resultsUrl": {
      "type": "string",
      "format": "uri"
    },
    "entrantCount": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991
    }
  },
  "additionalProperties": false
}
draw_winners annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
read_post_comments — Read a post's comments from its link
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Read every top-level comment on a public post from its link, with no account: YouTube videos. Returns the post (title, the account that posted it) and each comment's handle, text and time, ready for draw_winners or a comment picker. An Instagram post needs its owner: the answer is a link for them to pick a verifiable winner from that post.

read_post_comments input schema
{
  "type": "object",
  "required": [
    "link"
  ],
  "properties": {
    "link": {
      "type": "string",
      "maxLength": 1000,
      "minLength": 1,
      "description": "The post's link, as copied from its share button: a YouTube video."
    }
  }
}
read_post_comments annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
create_streak_badge — Start a streak badge
Advertised by the server during the last successful anonymous check.
Open-world

Start a personal streak for any habit with Perkadoo's Streak Badge, no account needed. Returns a public streak page, a live SVG badge for a README or website, and a private check-in link. The check-in link is the only way to check in, so tell the person to save it.

create_streak_badge input schema
{
  "type": "object",
  "required": [
    "title"
  ],
  "properties": {
    "theme": {
      "enum": [
        "light",
        "dark"
      ],
      "type": "string",
      "description": "Badge colours. Default light."
    },
    "title": {
      "type": "string",
      "maxLength": 160,
      "description": "The habit, e.g. 'Read 20 pages' or 'Ship a commit'."
    },
    "timeZone": {
      "type": "string",
      "maxLength": 64,
      "description": "IANA time zone that decides when a day starts, e.g. Europe/London. Default UTC."
    },
    "ownerName": {
      "type": "string",
      "maxLength": 80,
      "description": "Whose streak it is, shown on the public page."
    }
  }
}
create_streak_badge annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
check_in_streak_badge — Check in to a streak badge
Advertised by the server during the last successful anonymous check.
Open-world

Check in today on a Perkadoo Streak Badge with its private token. One check-in per day in the streak's time zone; checking in again the same day changes nothing. Missing a day starts the streak over.

check_in_streak_badge input schema
{
  "type": "object",
  "required": [
    "slug",
    "token"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "maxLength": 40,
      "description": "The streak's public slug, from its link /s/<slug>."
    },
    "token": {
      "type": "string",
      "maxLength": 200,
      "description": "The secret token from the private check-in link."
    }
  }
}
check_in_streak_badge annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
get_streak_badge — Read a streak badge
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Read a Perkadoo Streak Badge: the live streak, best streak, total days and the last seven days.

get_streak_badge input schema
{
  "type": "object",
  "required": [
    "slug"
  ],
  "properties": {
    "slug": {
      "type": "string",
      "maxLength": 40,
      "description": "The streak's public slug, from its link /s/<slug>."
    }
  }
}
get_streak_badge annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
build_prebuild_from_site — Build my giveaway and streak from my site
Advertised by the server during the last successful anonymous check.
Open-world

Give Doo your site's address. Doo reads it and builds your giveaway, daily streak and perks in your brand colors, then returns a private preview link. Nothing goes live until you make it yours from that page.

build_prebuild_from_site input schema
{
  "type": "object",
  "required": [
    "url"
  ],
  "properties": {
    "url": {
      "type": "string",
      "maxLength": 2000,
      "minLength": 1,
      "description": "Your site's address, like yoursite.com."
    }
  }
}
build_prebuild_from_site annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

1 advertised

draw-results — Giveaway winners

Advertised by the server during the last successful anonymous check.

The winners of a Perkadoo draw, with a link to verify it.

draw-results URI
ui://perkadoo/draw-results-v3.html

MIME type: text/html;profile=mcp-app

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
848 ms
95th percentile latency
848 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 848 ms · metadata changed · 22 tool(s), 1 resource(s), 0 resource template(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http perkadoo-mcp https://mcp.perkadoo.com/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add perkadoo-mcp --url https://mcp.perkadoo.com/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable perkadoo-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "perkadoo-mcp": {
      "url": "https://mcp.perkadoo.com/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "perkadoo-mcp": {
      "type": "streamableHttp",
      "url": "https://mcp.perkadoo.com/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start perkadoo-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "perkadoo-mcp": {
      "type": "http",
      "url": "https://mcp.perkadoo.com/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http perkadoo-mcp https://mcp.perkadoo.com/mcp

Claude Desktop

Merge this into claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop.
Claude Desktop configuration
{
  "mcpServers": {
    "perkadoo-mcp": {
      "url": "https://mcp.perkadoo.com/mcp"
    }
  }
}

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "perkadoo-mcp": {
      "serverUrl": "https://mcp.perkadoo.com/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Perkadoo MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Perkadoo MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing