Generated banner for Declarative Agent Developer
Generated logo for Declarative Agent Developer

Declarative Agent Developer

MicrosoftOfficialPublished by Microsoft

  • Skill
  • Tool integration
  • Software development
  • MIT
  • Low risk

From the author

Create, build, deploy, and localize declarative agents for M365 Copilot and Teams. USE THIS SKILL for ANY task involving a declarative agent — including localization, scaffolding, editing manifests, adding capabilities, and deploying. Localization requires tokenized manifests and language files that only this skill knows how to produce. Triggers: "create agent", "create a declarative agent", "new declarative agent", "scaffold an agent", "new agent project", "add a capability", "add a plugin", "configure my agent", "deploy my agent", "fix my agent manifest", "edit my agent", "localize my agent", "add localization", "translate my agent", "multi-language agent", "add an API plugin", "add an MCP plugin", "add OAuth to my plugin", "review instructions", "improve instructions", "fix my instructions"
— the description by Microsoft

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

The declarative-agent-developer skill provides a structured workflow for managing the lifecycle of M365 Copilot and Teams declarative agents. It utilizes the M365 Agent Toolkit (ATK) CLI to handle project scaffolding, manifest management, API plugin integration, and deployment. The skill enforces strict workspace validation, requiring specific project structures before allowing modifications, and provides standardized protocols for error handling, localization, and authentication configuration.

What it does

  • Scaffolds new declarative agent projects using the ATK CLI.
  • Manages and validates declarativeAgent.json manifests.
  • Integrates API plugins and MCP servers into existing agent projects.
  • Configures OAuth authentication for secure plugin communication.
  • Handles localization of agent manifests and language files.
  • Deploys agents to local environments for testing and validation.

When to use it

  • When creating a new declarative agent project for M365 Copilot or Teams.
  • When adding new capabilities, API plugins, or MCP servers to an existing agent.
  • When updating agent instructions or conversation starters.
  • When localizing an agent for multiple languages.
  • When troubleshooting or fixing errors in an agent manifest.

Advantages

  • Ensures consistent project structure through mandatory workspace checks.
  • Automates complex tasks like API plugin registration and OAuth setup.
  • Provides a clear, step-by-step protocol for error detection and resolution.
  • Facilitates standardized deployment and testing workflows.
  • Maintains schema compatibility by checking version requirements before feature implementation.

Usage examples

“Create a new declarative agent project.”
The agent will initialize a new project structure, including the necessary manifest files, provided the workspace is empty and valid for agent development.
“Add an API plugin to my agent using this OpenAPI spec URL.”
The agent will use the ATK CLI to integrate the specified API, map the requested operations, and prompt for necessary metadata updates.
“Localize my agent into French.”
The agent will generate the required tokenized manifests and language files to support French localization.
“Deploy my agent to the local environment.”
The agent will run the provisioning command and provide the M365 test link for the deployed agent.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/microsoft/declarative-agent-developer/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip declarative-agent-developer.zip -d .agents/skills

Documentation by Microsoft

M365 Agent Developer

Telemetry Tagging

Before running any atk CLI commands, set the session environment variable so all CLI invocations are tagged as skill-initiated:

export ATK_CLI_SKILL=true

Run this once at the start of the session. All subsequent atk commands in the same terminal will inherit it.

⛔ Workspace Check — MANDATORY FIRST STEP

Before doing ANYTHING, check the workspace files to fingerprint the project:

  1. Run npx -y --package @microsoft/m365agentstoolkit-cli atk --version to confirm ATK CLI is installed. If not found → Stop. Tell the user to install ATK.

  2. Check for m365agents.yml or teamsApp.yml at the project root.

  3. Check for appPackage/declarativeAgent.json.

  4. Check for non-agent indicators (package.json with express/react/next, src/index.js, app.py, etc.)

Then follow the decision gate:

ConditionGateAction
Non-agent project files, no appPackage/RejectText-only response. No files, no commands.
No manifest, user wants to edit/deployRejectText-only response. Explain manifest is missing.
No manifest, user wants new projectScaffold→ Scaffolding Workflow
Manifest exists with errorsFixDetect → Inform → Ask (see below). Do NOT deploy.
Valid project, user reports behavior issuesReview→ Instruction Review — run the full 5-phase review workflow
Valid agent projectEdit→ Editing Workflow

Detailed gate rules, examples, and anti-patterns: Workspace Gates

🚫 HARD REJECTION RULES — No Exceptions

These rules override ALL other instructions. If any of these apply, you MUST stop immediately.

  1. NEVER create declarativeAgent.json yourself. If the manifest is missing and the user asked to edit/modify/deploy, respond with text only: explain the manifest is missing, suggest npx -y --package @microsoft/m365agentstoolkit-cli atk new or starting from scratch. Do NOT create the file, do NOT create appPackage/, do NOT "help" by scaffolding implicitly.

  2. NEVER create files in a non-agent project. If the workspace is an Express/React/Django/etc. app without appPackage/, your response must be text-only. Do NOT create any files, do NOT run any commands.

  3. NEVER deploy when errors exist. If the agent manifest has errors, STOP. Do NOT run npx -y --package @microsoft/m365agentstoolkit-cli atk provision — not "to test", not "to demonstrate the error", not "to see what happens". Report the errors and ask the user how to proceed.

🔍 Detect → Inform → Ask (Error-Handling Protocol)

When you encounter ANY problem (missing files, malformed JSON, validation errors, incompatible features), you MUST follow this sequence in order:

  1. Detect — Identify the specific problem. For JSON issues, attempt to parse the file and report syntax errors. For missing fields, check the manifest against the Schema.

  2. Inform — Tell the user BEFORE taking any action. Describe exactly what is wrong ("declarativeAgent.json has malformed JSON: missing comma on line 12, unclosed array on line 18").

  3. Ask — Wait for the user's response before making changes. Do NOT silently fix, auto-correct, or work around the problem.

This protocol applies to:

  • Missing declarativeAgent.json → Detect (file not found) → Inform ("no manifest found") → Ask ("would you like to create a new agent?")

  • Malformed JSON → Detect (parse errors) → Inform (list specific syntax issues) → Ask ("should I fix these syntax errors?")

  • Validation errors → Detect (parse and check manifest) → Inform (list all errors) → Ask ("how would you like to fix these?")

  • Version incompatibility → Detect (feature requires newer version) → Inform ("this feature requires v1.6, your agent is v1.4") → Ask ("should I upgrade?")


Phase Routing

ScenarioWorkflow Reference
Creating a NEW project from scratchScaffolding Workflow
Working with existing .json manifestsEditing Workflow
Adding an API pluginAPI Plugins
Adding an MCP serverMCP Plugin
Adding OAuth to an MCP or API pluginAuthentication
Reviewing or improving existing agent instructionsInstruction Review
User reports agent gives generic/wrong answersInstruction Review
Localizing an agent into multiple languagesLocalization
Adding a new language to an already-localized agentLocalization
Writing agent instructionsConversation Design

ATK CLI Setup

Before running any ATK commands, check if the ATK CLI is available by running npx -y --package @microsoft/m365agentstoolkit-cli atk --version. If not found, STOP and tell the user — do NOT attempt to install it yourself.

All commands use the npx -y --package @microsoft/m365agentstoolkit-cli atk prefix (e.g., npx -y --package @microsoft/m365agentstoolkit-cli atk provision --env local).


Critical Rules

1. Deploy After EVERY Edit

After ANY change to files in appPackage/, you MUST deploy and show the test link before responding:

npx -y --package @microsoft/m365agentstoolkit-cli atk provision --env local --interactive false

Then read M365_TITLE_ID from env/.env.local and ALWAYS present the review UX:

✅ Agent deployed successfully!

🚀 Test Your Agent in M365 Copilot:
🔗 https://m365.cloud.microsoft/chat/?titleId={M365_TITLE_ID}

⛔ Never respond without this link. If you deployed, the test link MUST appear in your response. This is not optional — it is how the user tests their agent.

  • If the manifest has errors → STOP. Fix errors. Do NOT deploy.

  • Exception: user explicitly asks you not to deploy

2. Never Invent Content or Create Missing Files
  • Do NOT invent placeholder names, descriptions, or instructions

  • Do NOT create declarativeAgent.json or appPackage/ if they don't exist — this is a REJECT scenario, not a "help by creating" scenario

  • If required fields are missing, report the gaps, and ASK the user

  • If JSON is malformed, follow Detect → Inform → Ask: parse the file first, tell the user what's broken, then ask before fixing. Use surgical edits (not rewrites)

  • ⛔ NEVER set placeholder values for environment variables that are populated by automation (e.g., <PREFIX>_MCP_AUTH_ID, TEAMS_APP_ID). Leave them empty (VAR_NAME=). Placeholders will be treated as real values and will NOT be overwritten by provisioning.

3. Schema Version Compatibility

Before adding ANY feature, read the version field in declarativeAgent.json and check the Schema feature matrix. If the feature isn't supported in that version, refuse and offer to upgrade.

Key version gates:

  • sensitivity_label, worker_agents, EmbeddedKnowledge → v1.6 only

  • Meetings → v1.5+

  • ScenarioModels, behavior_overrides, disclaimer → v1.4+

  • Dataverse, TeamsMessages, Email, People → v1.3+

4. Use npx -y --package @microsoft/m365agentstoolkit-cli atk add action for API Plugins — NEVER Create Plugin Files Manually

You are forbidden from manually creating ai-plugin.json, OpenAPI specs, adaptive cards, or editing the actions array. Use the CLI:

# ⛔ Always list ALL operations in a single call — NEVER run separate calls per operation
npx -y --package @microsoft/m365agentstoolkit-cli atk add action --api-plugin-type api-spec --openapi-spec-location URL --api-operation "GET /path,POST /path,PATCH /path/{id},DELETE /path/{id}" -i false

Run a single npx -y --package @microsoft/m365agentstoolkit-cli atk add action call per OpenAPI spec, listing all operations as a comma-separated list in --api-operation. Never run separate npx -y --package @microsoft/m365agentstoolkit-cli atk add action calls for different operations from the same spec — this creates multiple plugins instead of one. If npx -y --package @microsoft/m365agentstoolkit-cli atk add action fails, report the error; do NOT fall back to manual creation.

Exception: MCP servers are not supported by npx -y --package @microsoft/m365agentstoolkit-cli atk add action. Use the MCP Plugin workflow instead.

5. MCP Server Integration

When the user mentions an MCP server URL, follow the MCP Plugin workflow. You MUST discover tools via the MCP protocol handshake (initialize → notifications/initialized → tools/list) — NEVER fabricate tool names/descriptions. For authenticated MCP servers, follow the authentication guide to configure OAuth.

6. Always Update Instructions & Starters After Changes

Adding a capability or plugin without updating instructions is incomplete. After ANY change:

  1. Update instructions to describe the new/changed functionality — every data source should have clear intent coverage (WHEN and WHY to use it) per the Instruction Review quality bar. Built-in capabilities don't need exact names; actions/plugins should be named.

  2. Do NOT list tool names, descriptions, or parameters in instructions — these are already in the plugin metadata (ai-plugin.json, MCP manifests, capability config). Instructions should contain decision logic only: WHEN to use each tool, chaining rules, and failure handling.

  3. Stay within the 8,000-character instruction limit — if close to the limit, cut tool descriptions first

  4. Add at least 1 conversation starter per added capability/plugin

  5. Remove starters that reference removed capabilities

  6. Run the Diagnostic Checklist against the updated instructions to verify quality

7. App Name Requirement

Always update the app name and description to something meaningful. Never leave defaults like "My Agent".


References

Shared
  • Authentication — OAuth discovery, credentials, oauth/register lifecycle, OAuthPluginVault

  • Best Practices — Security, performance, testing, compliance

  • Conversation Design — Authoring instructions and conversation starters from scratch

  • Instruction Review — Auditing, diagnosing, and improving existing instructions; anti-pattern detection; before/after rewrites

  • Deployment — ATK CLI workflows, environments, CI/CD

  • Localization — Multi-language support, tokenized manifests, language files

  • Workspace Gates — Detailed gate rules, examples, anti-patterns

Scaffolding
JSON Development
  • Editing Workflow — Step-by-step JSON development instructions

  • Schema — Official JSON schema for agent manifests

  • API Plugins — OpenAPI integration for JSON agents

  • MCP Plugin — MCP server integration with RemoteMCPServer, OAuth, response semantics, logo handling

  • Examples — JSON manifest examples

Files

references/localization.md

Localization Workflow

Quick Reference — Complete Localization Checklist

For adding localization to an agent (Workflow A):

  1. ⛔ Tokenize declarativeAgent.json → replace name, description, all conversation_starters[].title and .text with [[token]] syntax

  2. ⛔ Create language files → en.json (default) + one per additional language, each with name.short, name.full, description.short, description.full, and localizationKeys mapping EVERY token

  3. ⛔ Update manifest.json → add localizationInfo with defaultLanguageTag, defaultLanguageFile, additionalLanguages

  4. ⛔ Deploy → npx -y --package @microsoft/m365agentstoolkit-cli atk provision --env local --interactive false

For adding a language to an already-localized agent (Workflow B):

  1. Read existing default language file to get the list of localizationKeys

  2. Create new {lang}.json with the SAME set of keys, translated values

  3. Add new entry to additionalLanguages in manifest.json

  4. ⛔ Deploy


This document provides step-by-step instructions for localizing an M365 Copilot declarative agent into multiple languages.

Localization spans two layers: the app manifest (manifest.json) and the declarative agent manifest (declarativeAgent.json). Both use the same set of language files, but reference strings differently.

Important: If an agent supports more than one language, you must provide a separate language file for every supported language, including the default language. Single-language agents do not require language files.


⛔ STOP — READ THIS FIRST

Two Localization Scenarios
ScenarioWhat to do
Agent has NO localization yet (no localizationInfo in manifest.json, no [[tokens]] in declarativeAgent.json)Follow Workflow A: Add Localization to an Agent — you must tokenize, externalize instructions, create ALL language files, and update manifest.json
Agent is ALREADY localized (localizationInfo exists, manifests use [[tokens]])Follow Workflow B: Add a Language to an Already-Localized Agent — you only create a new language file and update localizationInfo

⛔ MANDATORY: You MUST check which scenario applies BEFORE making any changes. Read manifest.json to see if localizationInfo exists, and read declarativeAgent.json to see if it already uses [[token]] syntax.

⛔ Anti-Patterns — NEVER Do These
❌ Anti-PatternWhy It Fails✅ Correct Approach
Replacing strings directly with translated text in declarativeAgent.jsonHardcoded translations don't support multi-language switching. Only one language works at a time.Use [[token]] syntax and create language files with localizationKeys.
Leaving instructions inline in declarativeAgent.json when localizingInstructions must be separated from localizable content. Inline instructions block proper tokenization.Create appPackage/instructions.txt and set "instructions": "$[file]('instructions.txt')".
Creating language files without tokenizing declarativeAgent.json firstLanguage file localizationKeys are only resolved when the manifest uses [[token]] syntax. Without tokens, the language files have no effect.Always tokenize the manifest BEFORE creating language files.
Using [[token]] for the instructions fieldInstructions are NOT localizable. The LLM consumes them in a single language.Use $[file]('instructions.txt') for instructions. Never tokenize them.
Setting defaultLanguageTag to a non-English language without an en.json fallbackThe default language must have the default language file. English should typically be the default.Set defaultLanguageTag: "en" and defaultLanguageFile: "en.json". Add other languages as additionalLanguages.
How Localization Works
LayerKey styleExample
App manifest (manifest.json)JSONPath expressionsname.short, description.full
Agent / plugin manifestsDouble-bracket tokens resolved via localizationKeys[[agent_name]], [[plugin_description]]

Both types of localized strings live in the same language file per locale.


Workflow A: Add Localization to an Agent

Use this workflow when localizing an agent for the first time — the agent currently has hardcoded strings and no localizationInfo.

Step A1: Tokenize Agent Manifests — MANDATORY

Replace ALL user-facing strings in declarativeAgent.json (and plugin.json, if applicable) with tokenized keys wrapped in double brackets ([[key_name]]).

You MUST tokenize ALL of these fields:

FieldToken example
name[[agent_name]]
description[[agent_description]]
Every conversation_starters[].title[[starter_travel_title]], [[starter_remote_title]], etc.
Every conversation_starters[].text[[starter_travel_text]], [[starter_remote_text]], etc.
disclaimer.text (if present)[[disclaimer_text]]

Token key rules:

  • Must match the pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$

  • Use descriptive, snake_case names (e.g., starter_vpn_title not key1)

  • Keep names consistent across agent and plugin manifests

Example — tokenized declarativeAgent.json:

{
  "$schema": "https://developer.microsoft.com/json-schemas/copilot/declarative-agent/v1.6/schema.json",
  "version": "v1.6",
  "name": "[[agent_name]]",
  "description": "[[agent_description]]",
  "instructions": "$[file]('instructions.txt')",
  "conversation_starters": [
    {
      "title": "[[starter_vpn_title]]",
      "text": "[[starter_vpn_text]]"
    },
    {
      "title": "[[starter_password_title]]",
      "text": "[[starter_password_text]]"
    }
  ],
  "disclaimer": {
    "text": "[[disclaimer_text]]"
  }
}

If API plugin exists — tokenize plugin.json too:

{
  "schema_version": "v2.4",
  "name_for_human": "[[plugin_name]]",
  "description_for_human": "[[plugin_description]]",
  "description_for_model": "[[plugin_model_description]]"
}

⛔ NEVER skip tokenization. Writing localization files without first tokenizing the manifests makes localization non-functional. The manifests MUST use [[token]] syntax for the language files to take effect.

✅ POST-TOKENIZATION CHECKPOINT — Verify before proceeding to Step A2:

  • [ ] name field uses [[agent_name]] or similar token

  • [ ] description field uses [[agent_description]] or similar token

  • [ ] Every conversation_starters[].title uses a [[token]]

  • [ ] Every conversation_starters[].text uses a [[token]]

  • [ ] instructions field is NOT tokenized (it should remain as $[file]('instructions.txt') or inline text — never [[token]])

If any box is unchecked, STOP and fix it before continuing.

Step A2: Create Language Files — MANDATORY

Create one JSON file per language in appPackage/, named {languageTag}.json (e.g., en.json, fr.json, ja.json).

Every language file MUST contain:

  1. $schema — The localization schema reference

  2. App manifest strings — name.short, name.full, description.short, description.full (all four are REQUIRED)

  3. localizationKeys object — One entry per [[token]] used in declarativeAgent.json and plugin.json, using the token name WITHOUT brackets

Default language file (en.json) — use the ORIGINAL English values from the agent:

{
  "$schema": "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.Localization.schema.json",
  "name.short": "IT Help Desk",
  "name.full": "IT Help Desk Agent",
  "description.short": "Resolve common IT issues",
  "description.full": "Helps employees resolve common IT issues using internal knowledge bases and ticketing systems.",
  "localizationKeys": {
    "agent_name": "IT Help Desk Agent",
    "agent_description": "Helps employees resolve common IT issues using internal knowledge bases and ticketing systems.",
    "starter_vpn_title": "VPN issues",
    "starter_vpn_text": "I can't connect to the corporate VPN. What should I try?",
    "starter_password_title": "Password reset",
    "starter_password_text": "How do I reset my password?",
    "disclaimer_text": "This agent provides general IT guidance. For urgent issues, contact the helpdesk directly."
  }
}

Additional language file (fr.json) — use translations provided by the user:

{
  "$schema": "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.Localization.schema.json",
  "name.short": "Support informatique",
  "name.full": "Agent de support informatique",
  "description.short": "Résoudre les problèmes informatiques courants",
  "description.full": "Aide les employés à résoudre les problèmes informatiques courants à l'aide des bases de connaissances internes.",
  "localizationKeys": {
    "agent_name": "Agent de support informatique",
    "agent_description": "Aide les employés à résoudre les problèmes informatiques courants à l'aide des bases de connaissances internes.",
    "starter_vpn_title": "Problèmes de VPN",
    "starter_vpn_text": "Je n'arrive pas à me connecter au VPN de l'entreprise. Que dois-je essayer ?",
    "starter_password_title": "Réinitialisation du mot de passe",
    "starter_password_text": "Comment réinitialiser mon mot de passe ?",
    "disclaimer_text": "Cet agent fournit des conseils informatiques généraux. Pour les problèmes urgents, contactez le service d'assistance directement."
  }
}

⛔ CRITICAL: The localizationKeys in EVERY language file must have the EXACT SAME set of keys. If en.json has agent_name, agent_description, starter_vpn_title, etc., then fr.json must also have ALL of those same keys. Missing keys cause runtime resolution failures.

If the user did not provide translations for some strings (e.g., conversation starters), you MUST ask the user for them. Do NOT invent translations.

Step A3: Add localizationInfo to manifest.json — MANDATORY

Add the localizationInfo section to manifest.json:

{
  "localizationInfo": {
    "defaultLanguageTag": "en",
    "defaultLanguageFile": "en.json",
    "additionalLanguages": [
      {
        "languageTag": "fr",
        "file": "fr.json"
      },
      {
        "languageTag": "es",
        "file": "es.json"
      }
    ]
  }
}

Rules:

  • defaultLanguageTag and defaultLanguageFile are always required

  • Each additional language needs an entry in additionalLanguages

  • Language files live in appPackage/ alongside the manifests

  • Use language-only tags (e.g., en rather than en-us) for top-level translations; add region-specific overrides only when needed

Step A4: Deploy — MANDATORY

After completing ALL localization changes, deploy the agent:

npx -y --package @microsoft/m365agentstoolkit-cli atk provision --env local --interactive false

Then read M365_TITLE_ID from env/.env.local and present the test link. ⛔ Never skip deployment after localization changes.


Workflow B: Add a Language to an Already-Localized Agent

Use this workflow when the agent is ALREADY localized (manifests use [[tokens]], localizationInfo exists, language files exist) and the user wants to add another language.

⛔ Do NOT re-tokenize manifests or recreate existing language files. Only create the NEW language file and update localizationInfo.

Step B1: Read Existing Localization Setup
  1. Read manifest.json — note the localizationInfo section (default language, existing additional languages)

  2. Read the default language file (e.g., en.json) — note ALL keys in localizationKeys (these are the keys the new file must also have)

  3. Read declarativeAgent.json — confirm it uses [[token]] syntax (if not, switch to Workflow A)

Step B2: Create the New Language File

Create appPackage/{languageTag}.json with:

  1. $schema — same as existing language files

  2. name.short, name.full, description.short, description.full — translated values from the user

  3. localizationKeys — one entry per key from the default language file, with translated values from the user

⛔ CRITICAL: The new file MUST have the EXACT SAME set of localizationKeys as the default language file. Copy the key names from the existing default language file and fill in translated values.

Step B3: Update localizationInfo in manifest.json

Add the new language to the additionalLanguages array:

{
  "languageTag": "pt-BR",
  "file": "pt-BR.json"
}

⛔ Do NOT modify existing language files or the defaultLanguageFile entry. Only add to additionalLanguages.

Step B4: Deploy — MANDATORY

Deploy the agent:

npx -y --package @microsoft/m365agentstoolkit-cli atk provision --env local --interactive false

Then present the test link. ⛔ Never skip deployment.


Localizable Fields Reference

Declarative agent manifest:

FieldDescriptionMax lengthRequired
nameDisplay name of the agent100 chars✔️
descriptionDescription shown to users1,000 chars✔️
conversation_starters[].titleShort title for a conversation starter—
conversation_starters[].textFull prompt text for a conversation starter—
disclaimer.textDisclaimer shown at conversation start—

API plugin manifest:

FieldDescriptionMax lengthRequired
name_for_humanShort, human-readable plugin name20 chars✔️
description_for_humanHuman-readable description100 chars✔️
description_for_modelDescription provided to the model2,048 chars
conversation_starters[].titleTitle for plugin conversation starters—
conversation_starters[].textText for plugin conversation starters—
Required App Manifest Keys in Every Language File
KeyDescriptionMax lengthRequired
name.shortShort app name30 chars✔️
name.fullFull app name100 chars✔️
description.shortShort app description80 chars✔️
description.fullFull app description4,000 chars✔️

Language Resolution Order

The Microsoft 365 host resolves strings in the following order:

  1. Start with the default language strings

  2. Overwrite with the user's language-only file (e.g., en)

  3. Overwrite with the user's language + region file (e.g., en-gb), if available

For example, if the default language is fr, and you provide en and en-gb files, a user with locale en-gb sees: fr → overwritten by en → overwritten by en-gb.

Tip: Provide top-level, language-only translations (e.g., en rather than en-us). Add region-specific overrides only for the few strings that need them.


Project Structure

A localized app package includes the language files alongside the manifests:

my-agent/
├── appPackage/
│   ├── manifest.json
│   ├── declarativeAgent.json
│   ├── instructions.txt            # externalized instructions (NOT tokenized)
│   ├── plugin.json                 # optional
│   ├── en.json                     # default language file
│   ├── fr.json                     # French language file
│   ├── es.json                     # Spanish language file
│   ├── color.png
│   └── outline.png
├── env/
│   └── .env.dev
└── m365agents.yml

Critical Rules

  1. Every [[token]] must have a matching localizationKeys entry in every language file. Missing keys cause runtime failures.

  2. Keep token names descriptive — use starter_vpn_title not key1.

  3. Do NOT localize instructions — externalize to instructions.txt via $[file]('instructions.txt'). Never use [[tokens]] for instructions.

  4. Schema version consistency — $schema in language files must match manifest.json.

  5. Always deploy after localization changes.

  6. Do NOT invent translations — ask the user for translated strings. Never machine-translate without confirmation.

  7. Tokenization is MANDATORY — language files have no effect without [[token]] syntax in the manifests.


⛔ FINAL GATE — Before Responding to the User

STOP. Before writing your response, verify ALL of the following:

  • [ ] declarativeAgent.json uses [[token]] syntax for ALL localizable fields (name, description, every conversation starter title/text, disclaimer)

  • [ ] instructions field is NOT tokenized (never use [[token]] for instructions)

  • [ ] A default language file exists (e.g., en.json) with name.short, name.full, description.short, description.full, and ALL localizationKeys

  • [ ] Every additional language file has the EXACT SAME set of localizationKeys as the default

  • [ ] manifest.json has localizationInfo with defaultLanguageTag, defaultLanguageFile, and additionalLanguages

  • [ ] I deployed with npx -y --package @microsoft/m365agentstoolkit-cli atk provision --env local --interactive false

  • [ ] I presented the test link

If you cannot check ALL boxes, you are NOT done. Go back and complete the missing steps.


Error Handling

ErrorAction
Token in manifest has no matching localizationKeys entryStop. List the missing keys and the language files that need them. Ask the user to provide the translations.
Language file referenced in localizationInfo doesn't existStop. List the missing files. Ask the user to provide them or remove the language from additionalLanguages.
localizationInfo.defaultLanguageFile is missingStop. Inform the user that a default language file is required when localizationInfo is present.
Agent has only one languageInform the user that language files are not required for single-language agents. Ask if they want to add more languages.

Learn More

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server, Needs Node.js

Security

What our scanner noticed· Low risk

  • Phrasing that asks for actions without confirmation
  • Instructions that use the network

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Microsoft
Publisher
Microsoft (Official)
Source
microsoft/skills · .github/plugins/microsoft-365-agents-toolkit/skills/declarative-agent-developer · commit 0696600
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Microsoft.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download declarative-agent-developer.zip