| name | membership-card-pdf |
| description | Generate a printable BlastPass membership card as a PDF. Use when an associate or member asks to print, reprint, or replace a BlastPass membership card. The skill takes the member details returned by the Membership MCP (get_membership) and generates and runs a short Python (reportlab) snippet that renders a CR80-sized membership card to a real PDF file. It only renders the card from already-retrieved values — it never looks anything up or invents data. |
BlastPass Membership Card PDF Generator
This skill produces a printable BlastPass membership card — the simplest
file-generation flow in the demo. You take the member record you already pulled
from the Membership MCP (get_membership), then generate and run a short
Python snippet that renders a styled card to a PDF using reportlab.
Never invent a member, tier, or serial number — every value on the card comes from
the get_membership result. This skill only draws the card; it does not decide
anything.
When to use
Use this skill when the associate asks to print / reprint / replace a BlastPass
membership card for a known member. The only prerequisite is a single
get_membership(customer_id) call on the Membership MCP. There is no policy lookup,
no calculation, and no other agent involved — that is what makes this the
entry-level scenario.
Inputs (all from the Membership MCP get_membership result)
| Card field | Source field |
|---|
member_name | member_name |
member_id | customer_id |
tier | tier |
tier_code | tier_code (plus | extra | mega) — drives the accent color & perks |
console_serial | console_serial |
member_since | activation_date |
valid_through | term_end_date |
status | status |
The tier_code selects the card's accent color, header badge, and the perks line
printed beneath the card:
plus → blue, "PLUS", 5% off + 10 BlastPoints/$1
extra → purple, "PLUS EXTRA", 10% off + 20% BlastPoints bonus
mega → orange, "MEGA!!!", 15% off + 50% BlastPoints + day-one exclusives
Workflow
1. Pull the member record
Call get_membership with the mega-blast-customer-id (e.g. MEGA-BLAST-2048).
Map its fields into the card dict below. Do not add fields the MCP didn't
return.
2. Generate and run this Python to render the PDF
Fill the card dict with the confirmed values and run the snippet. It writes
blastpass_card.pdf to the working directory; report that path back to the
associate.
from reportlab.lib.pagesizes import LETTER
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.pdfgen import canvas
card = {
"member_name": "Sam Sparkle",
"member_id": "MEGA-BLAST-2048",
"tier": "BlastPass Plus Extra MEGA!!!",
"tier_code": "mega",
"console_serial": "OMEGA-9B1C-2048",
"member_since": "2026-05-30",
"valid_through": "2027-05-30",
"status": "active",
}
TIERS = {
"plus": ("#3aa0ff", "PLUS",
"Free 2-day shipping | 5% off accessories | 10 BlastPoints / $1"),
"extra": ("#9b51e0", "PLUS EXTRA",
"Free next-day shipping | 10% off accessories | +20% BlastPoints bonus"),
"mega": ("#ff7a18", "MEGA!!!",
"Same-day delivery | 15% off everything | +50% BlastPoints | Day-one exclusives"),
}
accent_hex, tier_badge, perks = TIERS.get(card["tier_code"], TIERS["plus"])
accent = colors.HexColor(accent_hex)
ink = colors.HexColor()
PAGE_W, PAGE_H = LETTER
CARD_W, CARD_H = * inch, * inch
x0 = (PAGE_W - CARD_W) /
y0 = (PAGE_H - CARD_H) /
c = canvas.Canvas(, pagesize=LETTER)
c.setStrokeColor(colors.HexColor())
c.setDash(, )
c.rect(x0 - , y0 - , CARD_W + , CARD_H + )
c.setDash()
c.setFillColor(ink)
c.roundRect(x0, y0, CARD_W, CARD_H, , stroke=, fill=)
c.setFillColor(accent)
c.roundRect(x0, y0 + CARD_H - * inch, CARD_W, * inch, , stroke=, fill=)
c.rect(x0, y0 + CARD_H - * inch, CARD_W, * inch, stroke=, fill=)
c.setFillColor(colors.white)
c.setFont(, )
c.drawString(x0 + * inch, y0 + CARD_H - * inch, )
c.setFont(, )
badge_w = c.stringWidth(tier_badge, , ) + * inch
bx_badge = x0 + CARD_W - * inch - badge_w
c.setFillColor(colors.Color(, , , alpha=))
c.roundRect(bx_badge, y0 + CARD_H - * inch, badge_w, * inch, , stroke=, fill=)
c.setFillColor(colors.white)
c.drawCentredString(bx_badge + badge_w / , y0 + CARD_H - * inch, tier_badge)
c.setFillColor(colors.white)
c.setFont(, )
c.drawString(x0 + * inch, y0 + CARD_H - * inch, card[])
c.setFillColor(accent)
c.setFont(, )
c.drawString(x0 + * inch, y0 + CARD_H - * inch, card[])
details = [
(, card[]),
(, card[]),
(, card[]),
]
dy = y0 + CARD_H - * inch
label, val details:
c.setFillColor(colors.HexColor())
c.setFont(, )
c.drawString(x0 + * inch, dy, label)
c.setFillColor(colors.white)
c.setFont(, )
c.drawString(x0 + * inch, dy, (val))
dy -= * inch
bx = x0 + * inch
by = y0 + * inch
c.setFillColor(colors.white)
hashlib
seed = (hashlib.md5(card[].encode()).hexdigest(), )
w =
i =
w < CARD_W - * inch:
bar = * inch + ((seed >> (i % )) & ) * * inch
i % == :
c.rect(bx + w, by, bar, * inch, stroke=, fill=)
w += bar
i +=
c.setFillColor(colors.HexColor())
c.setFont(, )
c.drawCentredString(PAGE_W / , y0 - * inch, perks)
c.setFont(, )
c.drawCentredString(PAGE_W / , y0 - * inch,
)
c.showPage()
c.save()
()
3. Hand back the file
Tell the associate the card was generated (blastpass_card.pdf) and read back the
member name, tier, and member ID so they can confirm it before handing it over.
Notes
- The reference renderer lives next to this file as
card_pdf.py and is validated
against the four mock members in the Membership MCP.
- The barcode is decorative (deterministic from the member ID) — it is not a real
scannable symbology.
- All data is mock; the card is for demo purposes only.