$npx -y skills add microsoft/skills-for-copilot-studio --skill add-adaptive-cardGenerate and insert an Adaptive Card into a Copilot Studio topic using AdaptiveCardPrompt. Use when the user asks to add an adaptive card, rich card, form card, info card, confirmation card, or interactive card to a topic.
| 1 | # Add Adaptive Card |
| 2 | |
| 3 | Add an `AdaptiveCardPrompt` node to an existing Copilot Studio topic. Use this for all Adaptive Card scenarios — display-only cards, input forms, and confirmation flows. |
| 4 | |
| 5 | ## Instructions |
| 6 | |
| 7 | 1. **Auto-discover the agent directory**: |
| 8 | ``` |
| 9 | Glob: agents/**/agent.mcs.yml |
| 10 | ``` |
| 11 | NEVER hardcode an agent name. |
| 12 | |
| 13 | 2. **Clarify requirements** from the user if not specified: |
| 14 | - Which topic should the card be added to? |
| 15 | - Which card type (form, info, confirmation)? |
| 16 | - What fields, labels, and placeholders are needed? |
| 17 | - Which topic variables should receive the submitted values? |
| 18 | |
| 19 | 3. **Read the target topic file** to understand its structure and find the correct insertion point. |
| 20 | |
| 21 | 4. **Verify the schema** if needed: |
| 22 | ```bash |
| 23 | # Copilot Studio node schema |
| 24 | node ${CLAUDE_SKILL_DIR}/../../scripts/schema-lookup.bundle.js summary AdaptiveCardPrompt |
| 25 | |
| 26 | # Adaptive Cards element schema (v1.6 — the version supported by Copilot Studio) |
| 27 | node ${CLAUDE_SKILL_DIR}/../../scripts/schema-lookup.bundle.js ac-summary TextBlock |
| 28 | node ${CLAUDE_SKILL_DIR}/../../scripts/schema-lookup.bundle.js ac-summary Input.Text |
| 29 | node ${CLAUDE_SKILL_DIR}/../../scripts/schema-lookup.bundle.js ac-search Action |
| 30 | ``` |
| 31 | |
| 32 | 5. **Select and adapt the template** from [card-templates.md](card-templates.md) matching the requested type. |
| 33 | |
| 34 | 6. **Generate unique IDs** for all new nodes (format: `<nodeType>_<6-8 random alphanumeric>`). |
| 35 | |
| 36 | 7. **Insert the node(s)** at the correct position in the `actions` array using Edit. |
| 37 | |
| 38 | 8. **Validate** the updated topic file: |
| 39 | ```bash |
| 40 | node ${CLAUDE_SKILL_DIR}/../../scripts/schema-lookup.bundle.js validate <topic-file.yml> |
| 41 | ``` |
| 42 | |
| 43 | 9. **Inform the user** that they must push (VS Code Extension) and publish (Copilot Studio UI) before testing with `/chat-with-agent` or `/run-tests`. |
| 44 | |
| 45 | ## AdaptiveCardPrompt Structure |
| 46 | |
| 47 | `AdaptiveCardPrompt` is the correct node kind for all Adaptive Cards in Copilot Studio. The card JSON is embedded as a **multiline YAML literal string** under `card: |`. |
| 48 | |
| 49 | ```yaml |
| 50 | - kind: AdaptiveCardPrompt |
| 51 | id: adaptiveCardPrompt_m9Kp2x |
| 52 | card: | |
| 53 | { |
| 54 | "type": "AdaptiveCard", |
| 55 | "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", |
| 56 | "version": "1.5", |
| 57 | "body": [...], |
| 58 | "actions": [...] |
| 59 | } |
| 60 | output: |
| 61 | binding: |
| 62 | fieldId: Topic.MyVariable |
| 63 | outputType: |
| 64 | properties: |
| 65 | fieldId: |
| 66 | type: String |
| 67 | ``` |
| 68 | |
| 69 | **Rules**: |
| 70 | - `card: |` — the literal block scalar is mandatory. Do not use `card: >` or inline the JSON without it. |
| 71 | - `$schema` and `version` are required inside the card JSON. |
| 72 | - The `output.binding` maps each card input `id` to a topic variable (`Topic.VarName`, no `=` prefix). |
| 73 | - `outputType.properties` must declare a type for every bound field. |
| 74 | - Use plain `binding:` — no `kind:` property inside it. |
| 75 | - **Every `AdaptiveCardPrompt` must have `output`, `outputType`, and an `Action.Submit` button** — including display-only info cards. Omitting any of these causes VS Code extension errors (`MissingRequiredProperty`, `AdaptiveCardMissingActionSubmit`). |
| 76 | - For info cards with no meaningful inputs, add an `Action.Submit` (e.g. "OK") and bind a dummy acknowledgement variable (`Topic.CardAcknowledged`, type `String`). |
| 77 | |
| 78 | ## Node Comparison |
| 79 | |
| 80 | | Node | Use When | |
| 81 | |------|----------| |
| 82 | | `AdaptiveCardPrompt` | Any Adaptive Card — with or without input fields | |
| 83 | | `SendActivity` | Plain text messages with optional `{}` variable interpolation | |
| 84 | |
| 85 | Do NOT use `SendActivity` with an `attachments` array for Adaptive Cards. |
| 86 | |
| 87 | ## Field Validation |
| 88 | |
| 89 | Do NOT use `style: "Email"` or `style: "Tel"` for validation — these only change the mobile keyboard and do not validate on submit. Always use `regex`: |
| 90 | |
| 91 | ```json |
| 92 | { |
| 93 | "type": "Input.Text", |
| 94 | "id": "email", |
| 95 | "label": "Email address", |
| 96 | "placeholder": "Enter your email address", |
| 97 | "isRequired": true, |
| 98 | "regex": "^[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}$", |
| 99 | "errorMessage": "Enter a valid email address" |
| 100 | } |
| 101 | ``` |
| 102 | |
| 103 | ```json |
| 104 | { |
| 105 | "type": "Input.Text", |
| 106 | "id": "mobile", |
| 107 | "label": "Mobile number", |
| 108 | "placeholder": "Enter your mobile number", |
| 109 | "isRequired": true, |
| 110 | "regex": "^[+]?[0-9][\\s\\-\\(\\)0-9]{6,14}$", |
| 111 | "errorMessage": "Enter a valid mobile number" |
| 112 | } |
| 113 | ``` |
| 114 | |
| 115 | | Approach | Validates on submit? | Notes | |
| 116 | |----------|---------------------|-------| |
| 117 | | `regex` | Yes — blocks submit if pattern fails | Use for email, phone, any format | |
| 118 | | `isRequired: true` | Yes — blocks submit if empty | Mandatory fields | |
| 119 | | `style: "Email"` | No | Keyboard hint only — never use for validation | |
| 120 | | `style: "Tel"` | No | |