Microsoft 365 Copilot Cowork can be extended with plugins. A plugin is a ZIP file that carries one or more skills, and an optional connector to a remote MCP server.
This is a beginner level post. Lets build a small plugin from an empty folder, package it, upload it to Cowork, and test it with a sample file.
What This Does
The example plugin reviews Power Platform solutions.
- Two skills. One audits an exported solution, the other designs a Dataverse schema.
- One connector to the Microsoft Learn MCP server, so findings cite official documentation.
- No server to host. The Learn MCP server is public and needs no authentication.
- Everything is plain Markdown and JSON. There is no code to compile.
Prerequisites
Make sure you have the following ready.
- A Microsoft 365 Copilot license with Cowork available.
- A text editor. Visual Studio Code works well.
- Two PNG icons. A 192×192 color icon and a 32×32 outline icon.
Lets start by creating the folder structure.
Create the Plugin Folder
- A plugin is just a folder with a fixed shape. Create the following.
powerplatform-solution-reviewer/├── manifest.json├── color.png├── outline.png├── tools/│ └── learn-mcp-tools.json└── skills/ ├── solution-health-check/ │ ├── SKILL.md │ └── references/ │ ├── alm-checklist.md │ └── scoring-rubric.md └── dataverse-schema-review/ ├── SKILL.md └── references/ └── naming-conventions.md

Write a Skill
- Each skill is a folder containing a
SKILL.mdfile. - The file has YAML frontmatter at the top and Markdown instructions below it.
name: solution-health-checkdescription: | Audits an EXISTING, already-built Power Platform solution for ALM readiness and deployment risk. Use when the user attaches or pastes a solution.xml or customizations.xml file, a solution component list, or a solution export, and asks to "review my solution", "check my solution before deployment", or "is this solution ready for production". Do NOT use when the user is designing a new data model or asking what tables and columns to create before anything is built - use dataverse-schema-review for that instead.license: MITmetadata: author: Rajeev Pentyala version: "1.0"# Power Platform Solution Health Check## Workflow1. Identify the solution: unique name, version, publisher, prefix, and managed or unmanaged.2. Inventory components by type.3. Check each item in `references/alm-checklist.md`.4. Score using `references/scoring-rubric.md`.
- Two frontmatter fields are required.
| Field | What it does |
|---|---|
name | The skill identifier. Must be kebab-case and must match the folder name exactly. |
description | Tells Cowork when to use the skill. Include the phrases a user would actually type. |
Important: The folder name must match the
namefield. A mismatch is the most common reason a skill never loads.
The description is important. Cowork reads it to decide which skill to run. When you have two skills, add a “Do NOT use when” line that points at the sibling skill. Without it, the wrong skill can pick up the request.
Content loads in three layers, so the context window stays small.
- Frontmatter loads always, at startup.
- The
SKILL.mdbody loads when the skill triggers. Aim for 1,500 to 2,000 words. - Files under
references/load only when the skill asks for them.
That is why detailed checklists belong in references/ and not in SKILL.md.
Now we have the skills written. Lets add the connector.
Add a Connector
- A connector points Cowork at a remote MCP server. This example uses the Microsoft Learn MCP server, which is public.
- Every connector needs a tool description file that you package inside the ZIP. Create
tools/learn-mcp-tools.json.
{ "tools": [ { "name": "microsoft_docs_search", "description": "Search official Microsoft Learn documentation and return relevant content excerpts with article titles and URLs.", "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "description": "A query or topic about Microsoft products, services, platforms, or APIs." } }, "required": ["query"] }, "annotations": { "title": "Microsoft Docs Search", "readOnlyHint": true } } ]}
Note: Authorization type
Noneworks here because the Learn MCP server is public. For your own API, useOAuthPluginVaultand register an OAuth client first.
Create the Manifest
- The manifest is the ID card of the plugin.
- Create
manifest.jsonfile in the plugin root.
{ "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.28/MicrosoftTeams.schema.json", "manifestVersion": "1.28", "version": "1.0.0", "id": "YOUR-GUID-HERE", "developer": { "name": "Rajeev Pentyala", "websiteUrl": "https://rajeevpentyala.com", "privacyUrl": "https://rajeevpentyala.com/privacy", "termsOfUseUrl": "https://rajeevpentyala.com/terms" }, "name": { "short": "Solution Reviewer", "full": "Power Platform Solution Reviewer for Copilot Cowork" }, "description": { "short": "Reviews Power Platform solutions for ALM readiness and Dataverse schema quality", "full": "Audits an exported Power Platform solution for ALM readiness, and reviews proposed Dataverse data models against naming and relationship conventions." }, "icons": { "color": "color.png", "outline": "outline.png" }, "accentColor": "#742774", "agentSkills": [ { "folder": "./skills/solution-health-check" }, { "folder": "./skills/dataverse-schema-review" } ], "agentConnectors": [ { "id": "microsoft-learn-mcp", "displayName": "Microsoft Learn MCP Server", "description": "Grounds every review finding in official Microsoft Learn documentation.", "toolSource": { "remoteMcpServer": { "mcpServerUrl": "https://learn.microsoft.com/api/mcp", "mcpToolDescription": { "file": "tools/learn-mcp-tools.json" }, "authorization": { "type": "None" } } } } ]}
- Here is what each field is for, and the value used above.
| Field | What it does | Value used |
|---|---|---|
$schema | Points to the schema the manifest is checked against. | Teams v1.28 schema URL |
manifestVersion | The schema version. Must match the $schema URL. | 1.28 |
version | Version of your plugin. Bump this every time you re-upload. | 1.0.0 |
id | A GUID that uniquely identifies the plugin. | Generated, see below |
developer.name | Publisher name shown in Cowork. | Rajeev Pentyala |
developer.websiteUrl | Link to your site. | My blog URL |
developer.privacyUrl | Link to a privacy statement. | Blog URL plus /privacy |
developer.termsOfUseUrl | Link to terms of use. | Blog URL plus /terms |
name.short | Short name in the plugin list. | Solution Reviewer |
name.full | Full name on the details page. | Power Platform Solution Reviewer for Copilot Cowork |
description.short | One line summary in the list. | The review purpose in one sentence |
description.full | Longer summary on the details page. | What each skill covers |
icons.color | Filename of the color icon. | color.png |
icons.outline | Filename of the outline icon. | outline.png |
accentColor | Background color behind the outline icon. | #742774 |
agentSkills[].folder | Path to each skill folder inside the package. | Both skill folders |
agentConnectors[].id | Your own name for the connector. | microsoft-learn-mcp |
agentConnectors[].displayName | Connector name shown on the details page. | Microsoft Learn MCP Server |
mcpServerUrl | The remote MCP endpoint to call. | Microsoft Learn MCP URL |
mcpToolDescription.file | Path to the tool description file in the package. | tools/learn-mcp-tools.json |
authorization.type | How to authenticate to the MCP server. | None, since Learn MCP is public |
- Generate a GUID. You can this tool to generate new GUID. Then paste the result into
idfield of the manifest file.
Package as a ZIP
Cowork expects the plugin contents at the root of the ZIP. There must be no wrapper folder around them.
- Open the
powerplatform-solution-reviewerfolder. - Select all five items inside it. Those are
manifest.json,color.png,outline.png, thetoolsfolder, and theskillsfolder. - Right click the selection and choose Send to, then Compressed (zipped) folder.
- Windows names the ZIP after the item you right clicked. Rename it to
powerplatform-solution-reviewer.zip.
Note: Select the five items inside the folder, not the folder itself. Right clicking the folder puts everything one level deep inside the ZIP, and the upload fails.
The package is ready. Lets upload it to Cowork.
Deploy the Plugin
- Open Copilot and switch to the Cowork tab.
- Select Customize in the left navigation.
- On the Plugins tab select Add plugin at the top right.
- Drag the ZIP onto the dialog, or select choose a file.

- Upload the Plugin .zip file prepared in the above section.
- The Share dialog opens next. Pick Only you while testing, then select Apply.

- The plugin now appears under Installed with its toggle on.

- Select the plugin row to open its detail page. Confirm both skills and the MCP server are listed.

Tip: If a skill is missing from this page, the problem is in the manifest or in the folder name. Check the folder to
namematch first.
The plugin is installed. Now lets test it.
Test the Plugin
- In the Cowork, select New task.
- Attach an exported solution ZIP and type a prompt that matches the skill description.

- Cowork reads the files inside the solution ZIP
- Watch the response header. It names the skill that fired.
- The Workspace panel on the right lists the plugin under Skills & Plugins.
- The Microsoft docs search entries confirm the MCP connector is working.

- The final report shows the score, the arithmetic behind it, and findings with links to Microsoft Learn.

That is a plugin built, deployed, and tested. Here is a quick recap.
Summary
We created a plugin folder, wrote two skills, added a public MCP connector, packaged it, and tested it in Cowork.
- A plugin is a ZIP with
manifest.json, two icons, askills/folder, and an optionaltools/folder. - The skill folder name must match the
namein theSKILL.mdfrontmatter. - The
descriptionfield decides when a skill runs, so write it with real user phrases. - Keep long checklists in
references/, because they load only when needed. - Every MCP connector needs a tool description file packaged inside the ZIP.
- Upload from Cowork then Customize then Plugins then Add plugin.
Official documentation: Build plugins for Copilot Cowork and Customize Copilot Cowork
🙂



Leave a Reply