agentsclimarketplace

Teams adaptive cards

Skill ccheney/robust-skills/skills/teams-adaptive-cards

Robust skills for Agents

Install
npx -y skills add ccheney/robust-skills --skill teams-adaptive-cards

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

Proactively apply when generating Microsoft Teams Adaptive Card JSON, Bot Framework card attachments, Teams SDK card responses, message extension cards, Microsoft Graph chatMessage Adaptive Card attachments, Incoming Webhook or Workflows webhook Adaptive Cards, notification cards, approval cards, form cards, Action.Submit, Action.Execute, Universal Actions, refresh, user-specific views, card mentions, msteams.entities, msteams.width, Teams responsive card layout, CodeBlock, Table, FactSet, ColumnSet, Input.ChoiceSet, People Picker, or debugging Teams card rendering. Use when constructing, validating, wrapping, or migrating Teams card payloads, including MessageCard-to-Adaptive-Card migrations.

SKILL.md

12.5 KB, as published. Nobody here has run it

Teams Adaptive Cards

Adaptive Cards are the primary rich-message surface for Microsoft Teams. Always choose the transport first, because the same card JSON is wrapped differently for bots, Workflows webhooks, and Microsoft Graph — most broken Teams cards are wrapper mistakes, not card mistakes.

Quick Decision Trees

"Should I use a card?"

Response type?
|-- Short conversational reply, <3 lines        -> text only; use $teams-message-formatting
|-- Status notification with facts/actions      -> Adaptive Card
|-- Approval, form, or data collection          -> Adaptive Card through bot/Universal Actions
|-- Search result or message extension response -> Adaptive Card
|-- Service alert to a channel                  -> Workflows webhook or notification bot card
|-- Delegated Graph message with attachment     -> Graph chatMessage card wrapper
`-- Legacy connector/MessageCard payload        -> migrate to Workflows + Adaptive Card
                                                   (O365 connectors stopped working May 2026)

"Which transport wrapper?"

Delivery path?
|-- Bot Framework / Teams SDK
|   `-- Activity `attachments[]` with contentType `application/vnd.microsoft.card.adaptive`
|-- Workflows (Power Automate) webhook
|   `-- Top-level `{ "type": "message", "attachments": [...] }`
|       (same wrapper the retired Incoming Webhook connectors used)
|-- Microsoft Graph chatMessage
|   `-- Body `<attachment id="..."></attachment>` plus matching `attachments[]`
|       with the card as a JSON *string* in attachment content
|-- Message extension result
|   `-- Attachment with Adaptive Card content and preview as required by extension type
`-- Outlook + Teams universal scenario
    `-- Use Universal Actions (`Action.Execute`) with bot backend

"Which card version?"

Need maximum Teams mobile compatibility?
|-- Yes -> use version "1.2"
`-- No
    |-- Need Action.Execute / refresh / Universal Actions      -> version "1.4"+, bot-backed
    |-- Need Table / CodeBlock / charts / Icon / targetWidth   -> version "1.5"
    `-- No special features                                    -> version "1.2"

Teams supports Adaptive Card schema v1.5 or earlier; Teams does not support v1.6 (that release was scoped to mobile SDK renderers). Newer Teams elements — CodeBlock, chart elements (Chart.Donut, Chart.Line, ...), Icon, CompoundButton, people picker — are declared in "version": "1.5" payloads and gated by host capability, not by a schema bump. Teams mobile reliably supports up to v1.2; later-version features can render incorrectly or inconsistently on mobile, so default to v1.2 and provide fallback/fallbackText when you go higher.

Minimal Card

{
  "$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.2",
  "fallbackText": "Deployment succeeded for API.",
  "body": [
    {
      "type": "TextBlock",
      "text": "Deployment succeeded",
      "weight": "Bolder",
      "size": "Medium",
      "wrap": true
    },
    {
      "type": "FactSet",
      "facts": [
        { "title": "Service", "value": "API" },
        { "title": "Duration", "value": "4 min 12 sec" }
      ]
    }
  ],
  "actions": [
    {
      "type": "Action.OpenUrl",
      "title": "View release",
      "url": "https://example.com/releases/42"
    }
  ]
}

Transport Wrappers

Bot Framework / Teams SDK

{
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
        "$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
        "type": "AdaptiveCard",
        "version": "1.2",
        "body": [
          { "type": "TextBlock", "text": "Hello from a bot", "wrap": true }
        ]
      }
    }
  ]
}

Workflows Webhook

Office 365 connectors — including connector-based Incoming Webhooks — were disabled by Microsoft in May 2026. Post to a Workflows (Power Automate) webhook URL instead; the message wrapper is identical:

{
  "type": "message",
  "attachments": [
    {
      "contentType": "application/vnd.microsoft.card.adaptive",
      "contentUrl": null,
      "content": {
        "$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
        "type": "AdaptiveCard",
        "version": "1.2",
        "body": [
          { "type": "TextBlock", "text": "Webhook alert", "wrap": true }
        ]
      }
    }
  ]
}

Workflows also accepts legacy MessageCard payloads for migration, but interactive MessageCard elements (buttons, inputs) are not supported there — convert to Adaptive Cards. Webhook cards are notification-only: use Action.OpenUrl; use a bot when a button must reach a backend.

Microsoft Graph chatMessage

{
  "body": {
    "contentType": "html",
    "content": "<attachment id=\"74d20c7f-34aa-4a7f-b74e-2b30004247c5\"></attachment>"
  },
  "attachments": [
    {
      "id": "74d20c7f-34aa-4a7f-b74e-2b30004247c5",
      "contentType": "application/vnd.microsoft.card.adaptive",
      "contentUrl": null,
      "content": "{\"type\":\"AdaptiveCard\",\"version\":\"1.2\",\"body\":[{\"type\":\"TextBlock\",\"text\":\"Graph card\",\"wrap\":true}]}"
    }
  ]
}

Graph rules that differ from the other transports: attachment content is a JSON string, not an object; the attachment id (a GUID by convention) must exactly match the <attachment id> placeholder in body.content; and there is no { "type": "message" } wrapper. Normal sends require delegated permissions (ChannelMessage.Send / ChatMessage.Send) — application permission exists only for migration, so do not choose Graph as an app-only notification channel.

Layout Guidance

Use Teams-native card structure instead of Markdown tricks:

NeedUse
TitleTextBlock with weight: "Bolder", size, optional style: "heading" (v1.5)
Key-value dataFactSet for compact facts; ColumnSet for custom layouts
Status calloutContainer with subtle emphasis, icon/image, and concise text
TableTable only when v1.5/client support is acceptable
CodeCodeBlock (v1.5; renders on Teams web/desktop only)
ChartChart.Donut, Chart.Line, Chart.VerticalBar, etc. (v1.5)
FormInput.* elements plus Action.Submit or Action.Execute
People selectionInput.ChoiceSet with choices.data Data.Query people picker
Mention<at>Name</at> in text plus root msteams.entities
Wide desktop cardRoot msteams.width: "Full", then test narrow clients
Per-width layouttargetWidth on elements (veryNarrow/narrow/standard/wide)

Always set wrap: true on meaningful TextBlock content. Avoid fixed pixel thinking; Teams cards render in chats, channels, meeting side panels, mobile, and desktop.

Actions

ActionUseTeams Notes
Action.OpenUrlOpen external page/deep linkSafest for webhooks and notifications
Action.SubmitSubmit inputs to botRequires bot backend; explicitly unsupported in webhook cards; isEnabled unsupported in Teams
Action.ExecuteUniversal Actions across Teams/Outlookv1.4+; bot must handle adaptiveCard/action invokes
Action.ToggleVisibilityReveal/hide local detailsGood for progressive disclosure; works without a backend
Action.ShowCardInline secondary cardUse sparingly; can be confusing on mobile

Teams ignores positive/destructive action styling in Adaptive Cards. Do not rely on style: "positive" or style: "destructive" for visual meaning.

Validate Payloads

Run the bundled linter on any card or wrapped payload (from the skill directory):

node scripts/check-teams-card.mjs path/to/payload.json                  # auto-detect target
node scripts/check-teams-card.mjs --target card path/to/card.json      # raw Adaptive Card
node scripts/check-teams-card.mjs --target bot path/to/activity.json   # bot activity/attachment
node scripts/check-teams-card.mjs --target webhook path/to/payload.json
node scripts/check-teams-card.mjs --target graph path/to/message.json

Output is one ERROR:/WARN:/INFO: line per finding with a JSONPath-style location, plus a summary line. Exit code 0 means no errors (warnings allowed), 1 means at least one error or unparseable JSON, 2 means bad CLI usage. The script catches Teams-specific issues a generic schema validator misses: wrapper mismatches, Graph placeholder/id mismatches, stringified-content problems, unsupported action assumptions, mobile version risk, missing fallbackText, missing msteams.entities for mentions, and layout hazards.

Anti-Patterns

Anti-PatternProblemFix
Posting raw card JSON to a webhook URLWebhooks expect a message wrapperWrap in { "type": "message", "attachments": [...] }
Reusing webhook wrapper in GraphGraph needs body placeholder and stringified attachment contentUse Graph wrapper
Action.Submit in notification-only webhookUnsupported; no bot receives itUse Action.OpenUrl or build a bot
Version 1.5 by defaultMobile/client feature riskDefault to 1.2 unless a feature needs more
Version 1.6Not supported by TeamsUse 1.5 with capability-gated elements
Markdown table/heading/code fence in TextBlockUnsupported Markdown subsetUse Table, TextBlock sizing, or CodeBlock
Missing fallbackTextPoor fallback/accessibilityAdd a concise summary
Fixed-width multi-column layoutBreaks on mobile/side panelsDesign narrow-first; use targetWidth
Mention text without msteams.entitiesRenders as literal text, no notificationAdd root metadata
Connector MessageCard for new workConnectors retired May 2026Use Workflows or notification bot with Adaptive Cards

Reference Documentation

ReadBefore
references/CHEATSHEET.mdAny card work — wrappers, version policy, limits at a glance
references/ELEMENTS.mdChoosing body elements: inputs, Table, CodeBlock, charts, people picker, Media
references/ACTIONS.mdAdding buttons: Submit vs Execute, msteams data behaviors, refresh/user-specific views
references/SURFACES.mdPicking a delivery path: bots, message extensions, Graph, webhooks
references/WEBHOOKS-WORKFLOWS.mdBuilding webhook notifications or migrating retired connectors/MessageCards
references/GRAPH-ATTACHMENTS.mdSending cards through Microsoft Graph chatMessage
references/RESPONSIVE-DESIGN.mdDesigning layout: targetWidth, full width, mobile behavior, accessibility

Sources

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.