Source profileQuality 84/100

github/awesome-copilot/skills/mcp-create-adaptive-cards/SKILL.md

mcp-create-adaptive-cards

Skill converted from mcp-create-adaptive-cards.prompt.md

Source repository stars
37,126
Declared platforms
0
Static risk flags
1
Last source update
2026-07-28
Source checked
2026-07-28

Decision brief

What it does—and where it fits

Add Adaptive Card response templates to MCP-based API plugins to enhance how data is presented visually in Microsoft 365 Copilot.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/github/awesome-copilot --skill "skills/mcp-create-adaptive-cards"
    Safe inspection promptEditorial

    Inspect the Agent Skill "mcp-create-adaptive-cards" from https://github.com/github/awesome-copilot/blob/9933dcad5be5caeb288cebcd370eeeb2fc2f1685/skills/mcp-create-adaptive-cards/SKILL.md at commit 9933dcad5be5caeb288cebcd370eeeb2fc2f1685. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Workflow

      Ask the user: 1. What type of data does the API return? 2. Are all items the same type (static) or different types (dynamic)? 3. What fields should appear in the card? 4. Should there be actions (e.g., "View Details")? 5. Are there multiple states or categories requiring differe…

      What type of data does the API return?Are all items the same type (static) or different types (dynamic)?What fields should appear in the card?
    2. 02

      Adaptive Card Types

      Use when API always returns items of the same type and format doesn't change often.

      Use when API always returns items of the same type and format doesn't change often.Define in responsesemantics.statictemplate in ai-plugin.json:Use when API returns multiple types and each item needs a different template.
    3. 03

      Static Response Templates

      Use when API always returns items of the same type and format doesn't change often.

      Use when API always returns items of the same type and format doesn't change often.Define in responsesemantics.statictemplate in ai-plugin.json:
    4. 04

      Dynamic Response Templates

      Use when API returns multiple types and each item needs a different template.

      Use when API returns multiple types and each item needs a different template.ai-plugin.json configuration:API Response with Embedded Templates:
    5. 05

      Combined Static and Dynamic Templates

      Use static template as default when item doesn't have templateselector or when value doesn't resolve.

      Use static template as default when item doesn't have templateselector or when value doesn't resolve.

    Permission review

    Static risk signals and limitations

    Network access

    medium · line 204

    The documentation includes network, browsing, or remote request actions.

    JSONPath query indicating where data resides in API response:

    Network access

    medium · line 464

    The documentation includes network, browsing, or remote request actions.

    [Adaptive Card Designer](https://adaptivecards.microsoft.com/designer) - Visual design tool

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score84/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars37,126SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    github/awesome-copilot
    Skill path
    skills/mcp-create-adaptive-cards/SKILL.md
    Commit
    9933dcad5be5caeb288cebcd370eeeb2fc2f1685
    License
    MIT
    Collected
    2026-07-28
    Default branch
    main
    View the original SKILL.md
    ---
    mode: 'agent'
    tools: ['changes', 'search/codebase', 'edit/editFiles', 'problems']
    description: 'Add Adaptive Card response templates to MCP-based API plugins for visual data presentation in Microsoft 365 Copilot'
    model: 'gpt-4.1'
    tags: [mcp, adaptive-cards, m365-copilot, api-plugin, response-templates]
    ---
    
    # Create Adaptive Cards for MCP Plugins
    
    Add Adaptive Card response templates to MCP-based API plugins to enhance how data is presented visually in Microsoft 365 Copilot.
    
    ## Adaptive Card Types
    
    ### Static Response Templates
    Use when API always returns items of the same type and format doesn't change often.
    
    Define in `response_semantics.static_template` in ai-plugin.json:
    
    ```json
    {
      "functions": [
        {
          "name": "GetBudgets",
          "description": "Returns budget details including name and available funds",
          "capabilities": {
            "response_semantics": {
              "data_path": "$",
              "properties": {
                "title": "$.name",
                "subtitle": "$.availableFunds"
              },
              "static_template": {
                "type": "AdaptiveCard",
                "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                "version": "1.5",
                "body": [
                  {
                    "type": "Container",
                    "$data": "${$root}",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "Name: ${if(name, name, 'N/A')}",
                        "wrap": true
                      },
                      {
                        "type": "TextBlock",
                        "text": "Available funds: ${if(availableFunds, formatNumber(availableFunds, 2), 'N/A')}",
                        "wrap": true
                      }
                    ]
                  }
                ]
              }
            }
          }
        }
      ]
    }
    ```
    
    ### Dynamic Response Templates
    Use when API returns multiple types and each item needs a different template.
    
    **ai-plugin.json configuration:**
    ```json
    {
      "name": "GetTransactions",
      "description": "Returns transaction details with dynamic templates",
      "capabilities": {
        "response_semantics": {
          "data_path": "$.transactions",
          "properties": {
            "template_selector": "$.displayTemplate"
          }
        }
      }
    }
    ```
    
    **API Response with Embedded Templates:**
    ```json
    {
      "transactions": [
        {
          "budgetName": "Fourth Coffee lobby renovation",
          "amount": -2000,
          "description": "Property survey for permit application",
          "expenseCategory": "permits",
          "displayTemplate": "$.templates.debit"
        },
        {
          "budgetName": "Fourth Coffee lobby renovation",
          "amount": 5000,
          "description": "Additional funds to cover cost overruns",
          "expenseCategory": null,
          "displayTemplate": "$.templates.credit"
        }
      ],
      "templates": {
        "debit": {
          "type": "AdaptiveCard",
          "version": "1.5",
          "body": [
            {
              "type": "TextBlock",
              "size": "medium",
              "weight": "bolder",
              "color": "attention",
              "text": "Debit"
            },
            {
              "type": "FactSet",
              "facts": [
                {
                  "title": "Budget",
                  "value": "${budgetName}"
                },
                {
                  "title": "Amount",
                  "value": "${formatNumber(amount, 2)}"
                },
                {
                  "title": "Category",
                  "value": "${if(expenseCategory, expenseCategory, 'N/A')}"
                },
                {
                  "title": "Description",
                  "value": "${if(description, description, 'N/A')}"
                }
              ]
            }
          ],
          "$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
        },
        "credit": {
          "type": "AdaptiveCard",
          "version": "1.5",
          "body": [
            {
              "type": "TextBlock",
              "size": "medium",
              "weight": "bolder",
              "color": "good",
              "text": "Credit"
            },
            {
              "type": "FactSet",
              "facts": [
                {
                  "title": "Budget",
                  "value": "${budgetName}"
                },
                {
                  "title": "Amount",
                  "value": "${formatNumber(amount, 2)}"
                },
                {
                  "title": "Description",
                  "value": "${if(description, description, 'N/A')}"
                }
              ]
            }
          ],
          "$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
        }
      }
    }
    ```
    
    ### Combined Static and Dynamic Templates
    Use static template as default when item doesn't have template_selector or when value doesn't resolve.
    
    ```json
    {
      "capabilities": {
        "response_semantics": {
          "data_path": "$.items",
          "properties": {
            "title": "$.name",
            "template_selector": "$.templateId"
          },
          "static_template": {
            "type": "AdaptiveCard",
            "version": "1.5",
            "body": [
              {
                "type": "TextBlock",
                "text": "Default: ${name}",
                "wrap": true
              }
            ]
          }
        }
      }
    }
    ```
    
    ## Response Semantics Properties
    
    ### data_path
    JSONPath query indicating where data resides in API response:
    ```json
    "data_path": "$"           // Root of response
    "data_path": "$.results"   // In results property
    "data_path": "$.data.items"// Nested path
    ```
    
    ### properties
    Map response fields for Copilot citations:
    ```json
    "properties": {
      "title": "$.name",            // Citation title
      "subtitle": "$.description",  // Citation subtitle
      "url": "$.link"               // Citation link
    }
    ```
    
    ### template_selector
    Property on each item indicating which template to use:
    ```json
    "template_selector": "$.displayTemplate"
    ```
    
    ## Adaptive Card Template Language
    
    ### Conditional Rendering
    ```json
    {
      "type": "TextBlock",
      "text": "${if(field, field, 'N/A')}"  // Show field or 'N/A'
    }
    ```
    
    ### Number Formatting
    ```json
    {
      "type": "TextBlock",
      "text": "${formatNumber(amount, 2)}"  // Two decimal places
    }
    ```
    
    ### Data Binding
    ```json
    {
      "type": "Container",
      "$data": "${$root}",  // Break to root context
      "items": [ ... ]
    }
    ```
    
    ### Conditional Display
    ```json
    {
      "type": "Image",
      "url": "${imageUrl}",
      "$when": "${imageUrl != null}"  // Only show if imageUrl exists
    }
    ```
    
    ## Card Elements
    
    ### TextBlock
    ```json
    {
      "type": "TextBlock",
      "text": "Text content",
      "size": "medium",      // small, default, medium, large, extraLarge
      "weight": "bolder",    // lighter, default, bolder
      "color": "attention",  // default, dark, light, accent, good, warning, attention
      "wrap": true
    }
    ```
    
    ### FactSet
    ```json
    {
      "type": "FactSet",
      "facts": [
        {
          "title": "Label",
          "value": "Value"
        }
      ]
    }
    ```
    
    ### Image
    ```json
    {
      "type": "Image",
      "url": "https://example.com/image.png",
      "size": "medium",  // auto, stretch, small, medium, large
      "style": "default" // default, person
    }
    ```
    
    ### Container
    ```json
    {
      "type": "Container",
      "$data": "${items}",  // Iterate over array
      "items": [
        {
          "type": "TextBlock",
          "text": "${name}"
        }
      ]
    }
    ```
    
    ### ColumnSet
    ```json
    {
      "type": "ColumnSet",
      "columns": [
        {
          "type": "Column",
          "width": "auto",
          "items": [ ... ]
        },
        {
          "type": "Column",
          "width": "stretch",
          "items": [ ... ]
        }
      ]
    }
    ```
    
    ### Actions
    ```json
    {
      "type": "Action.OpenUrl",
      "title": "View Details",
      "url": "https://example.com/item/${id}"
    }
    ```
    
    ## Responsive Design Best Practices
    
    ### Single-Column Layouts
    - Use single columns for narrow viewports
    - Avoid multi-column layouts when possible
    - Ensure cards work at minimum viewport width
    
    ### Flexible Widths
    - Don't assign fixed widths to elements
    - Use "auto" or "stretch" for width properties
    - Allow elements to resize with viewport
    - Fixed widths OK for icons/avatars only
    
    ### Text and Images
    - Avoid placing text and images in same row
    - Exception: Small icons or avatars
    - Use "wrap": true for text content
    - Test at various viewport widths
    
    ### Test Across Hubs
    Validate cards in:
    - Teams (desktop and mobile)
    - Word
    - PowerPoint
    - Various viewport widths (contract/expand UI)
    
    ## Complete Example
    
    **ai-plugin.json:**
    ```json
    {
      "functions": [
        {
          "name": "SearchProjects",
          "description": "Search for projects with status and details",
          "capabilities": {
            "response_semantics": {
              "data_path": "$.projects",
              "properties": {
                "title": "$.name",
                "subtitle": "$.status",
                "url": "$.projectUrl"
              },
              "static_template": {
                "type": "AdaptiveCard",
                "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                "version": "1.5",
                "body": [
                  {
                    "type": "Container",
                    "$data": "${$root}",
                    "items": [
                      {
                        "type": "TextBlock",
                        "size": "medium",
                        "weight": "bolder",
                        "text": "${if(name, name, 'Untitled Project')}",
                        "wrap": true
                      },
                      {
                        "type": "FactSet",
                        "facts": [
                          {
                            "title": "Status",
                            "value": "${status}"
                          },
                          {
                            "title": "Owner",
                            "value": "${if(owner, owner, 'Unassigned')}"
                          },
                          {
                            "title": "Due Date",
                            "value": "${if(dueDate, dueDate, 'Not set')}"
                          },
                          {
                            "title": "Budget",
                            "value": "${if(budget, formatNumber(budget, 2), 'N/A')}"
                          }
                        ]
                      },
                      {
                        "type": "TextBlock",
                        "text": "${if(description, description, 'No description')}",
                        "wrap": true,
                        "separator": true
                      }
                    ]
                  }
                ],
                "actions": [
                  {
                    "type": "Action.OpenUrl",
                    "title": "View Project",
                    "url": "${projectUrl}"
                  }
                ]
              }
            }
          }
        }
      ]
    }
    ```
    
    ## Workflow
    
    Ask the user:
    1. What type of data does the API return?
    2. Are all items the same type (static) or different types (dynamic)?
    3. What fields should appear in the card?
    4. Should there be actions (e.g., "View Details")?
    5. Are there multiple states or categories requiring different templates?
    
    Then generate:
    - Appropriate response_semantics configuration
    - Static template, dynamic templates, or both
    - Proper data binding with conditional rendering
    - Responsive single-column layout
    - Test scenarios for validation
    
    ## Resources
    
    - [Adaptive Card Designer](https://adaptivecards.microsoft.com/designer) - Visual design tool
    - [Adaptive Card Schema](https://adaptivecards.io/schemas/adaptive-card.json) - Full schema reference
    - [Template Language](https://learn.microsoft.com/en-us/adaptive-cards/templating/language) - Binding syntax guide
    - [JSONPath](https://www.rfc-editor.org/rfc/rfc9535) - Path query syntax
    
    ## Common Patterns
    
    ### List with Images
    ```json
    {
      "type": "Container",
      "$data": "${items}",
      "items": [
        {
          "type": "ColumnSet",
          "columns": [
            {
              "type": "Column",
              "width": "auto",
              "items": [
                {
                  "type": "Image",
                  "url": "${thumbnailUrl}",
                  "size": "small",
                  "$when": "${thumbnailUrl != null}"
                }
              ]
            },
            {
              "type": "Column",
              "width": "stretch",
              "items": [
                {
                  "type": "TextBlock",
                  "text": "${title}",
                  "weight": "bolder",
                  "wrap": true
                }
              ]
            }
          ]
        }
      ]
    }
    ```
    
    ### Status Indicators
    ```json
    {
      "type": "TextBlock",
      "text": "${status}",
      "color": "${if(status == 'Completed', 'good', if(status == 'In Progress', 'attention', 'default'))}"
    }
    ```
    
    ### Currency Formatting
    ```json
    {
      "type": "TextBlock",
      "text": "$${formatNumber(amount, 2)}"
    }
    ```