Create a new Copilot Studio topic YAML file. Use when the user asks to create a new topic, conversation flow, or dialog for their agent.
npx skills add https://github.com/microsoft/skills-for-copilot-studio --skill new-topic
Generate a new Copilot Studio topic YAML file based on user requirements.
Glob: **/agent.mcs.yml
If multiple agents found, ask which one. NEVER hardcode an agent name.
${CLAUDE_SKILL_DIR}/../../templates/topics/ first:greeting.topic.mcs.yml — OnConversationStart greetingfallback.topic.mcs.yml — OnUnknownIntent fallback with escalationarithmeticsum.topic.mcs.yml — Topic with inputs/outputs and computationquestion-topic.topic.mcs.yml — Question with branching logicsearch-topic.topic.mcs.yml — Generative answers from knowledgeauth-topic.topic.mcs.yml — Authentication flowerror-handler.topic.mcs.yml — Error handlingdisambiguation.topic.mcs.yml — Multiple topics matchedIf a template matches, use it as the starting point.
kind: values against the schema before writing them: node ${CLAUDE_SKILL_DIR}/../../scripts/schema-lookup.bundle.js kinds # List all valid kind values
node ${CLAUDE_SKILL_DIR}/../../scripts/schema-lookup.bundle.js resolve AdaptiveDialog # Resolve trigger structure
node ${CLAUDE_SKILL_DIR}/../../scripts/schema-lookup.bundle.js resolve <TriggerType> # Resolve specific trigger
node ${CLAUDE_SKILL_DIR}/../../scripts/schema-lookup.bundle.js search <ActionKind> # Verify an action kind exists
NEVER write a kind: value you haven't verified exists in the schema. This is the #1 source of hallucination errors. If schema-lookup.bundle.js search <kind> returns no results, the kind does NOT exist — do not use it.
OnRecognizedIntent — For topics triggered by user phrases (most common)OnConversationStart — For welcome/greeting topicsOnUnknownIntent — For fallback topicsOnEscalate — For escalation to human agentOnError — For error handling# Name: comment at the topkind: AdaptiveDialogbeginDialog with correct trigger<nodeType>_<6-8 random alphanumeric>)_REPLACE placeholders with unique IDsGenerativeActionsEnabled. Read the agent's settings.mcs.yml to check.topics/<topic-name>.topic.mcs.yml directoryStep A: Schema validation — always run this first:
node ${CLAUDE_SKILL_DIR}/../../scripts/schema-lookup.bundle.js validate <saved-file.yml>
Step B: LSP-based validation — also run this if the agent has .mcs/conn.json:
Read .mcs/conn.json to get connection details, then:
node ${CLAUDE_SKILL_DIR}/../../scripts/manage-agent.bundle.js validate \
--workspace "<path-to-agent-folder>" \
--tenant-id "<tenantId>" \
--environment-id "<envId>" \
--environment-url "<envUrl>" \
--agent-mgmt-url "<mgmtUrl>"
Both validations are complementary: schema validation checks structural correctness (action kinds, property placement), while LSP validation checks Power Fx expressions, cross-file references, and environment-specific rules. If either fails, fix the issues before reporting success to the user.
When the agent has GenerativeActionsEnabled: true in settings:
Use Topic Inputs (AutomaticTaskInput) instead of Question nodes to auto-collect user info.
Place inputs at the AdaptiveDialog root level (NOT inside beginDialog):
kind: AdaptiveDialog
inputs: # <-- at AdaptiveDialog root, NOT inside beginDialog
- kind: AutomaticTaskInput
propertyName: userName
description: "The user's name"
entity: StringPrebuiltEntity
shouldPromptUser: true
beginDialog:
kind: OnRecognizedIntent
id: main
actions:
- ...
Use Topic Outputs instead of SendActivity for final results.
Use outputType at the root level and SetVariable to set output values — do NOT use TaskOutput (which is only valid in TaskDialog connector actions):
kind: AdaptiveDialog
inputs:
- ...
beginDialog:
kind: OnRecognizedIntent
id: main
actions:
- kind: SetVariable
id: setVar_abc123
variable: Topic.result
value: ="computed value"
outputType: # <-- at AdaptiveDialog root
properties:
result:
displayName: result
description: The computed result
type: String
Include inputType/outputType schemas at the AdaptiveDialog root level when using inputs/outputs:
inputType:
properties:
userName:
displayName: userName
description: "The user's name"
type: String
outputType:
properties:
result:
displayName: result
type: String
When a topic exists alongside other topics or other actions (i.e. TaskDialog), think carefully about the topic outputs — it directly affects whether the orchestrator will chain to an action.
Two scenarios:
Ask yourself: Does this topic complete the task on its own, or does it prepare data for an action/other topic? If the latter, output the data, not a status message.
Alternative approaches for data-gathering topics:
=: value: =Text(Topic.num1 + Topic.num2){}: activity: "Hello {Topic.UserName}"Text(), Now(), IsBlank(), !IsBlank(), DateTimeFormat.UTCvariable: init:Topic.MyVar (first assignment uses init:)SetTextVariable instead of SetVariable to convert non-text types (Number, DateTime, etc.) to text via template interpolation: value: "Guests: {Topic.NumberOfGuests}"Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
Replace with description of the skill and when Claude should use it.
Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies
This skill should be used when the user wants to "create a skill", "add a skill to plugin", "write a new skill", "improve skill description", "organize skill content", or needs guidance on skill structure, progressive disclosure, or skill development best practices for Claude Code plugins.
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
Use when creating new skills, editing existing skills, or verifying skills work before deployment
Take microsoft/new-topic from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.