Purview Dlp Integration logo

Purview Dlp Integration

Organization
microsoft
purview-dlp-integration

Integrate Microsoft Purview DLP (data loss prevention) + audit into an existing Microsoft Agent 365 (A365 SDK) agent, so sensitive prompts are blocked before the LLM and responses can be audited. Use when a user wants to add Purview DLP to an AI agent, block sensitive data (credit cards, SSNs, PII) in agent turns, enforce data protection/compliance on an A365 AgentApplication, call the Graph processContent API, or wire a DLP gate into agent code. Bundles drop-in guards for Node.js/TypeScript, Python, and .NET, minimal wiring for each, a PowerShell script to create the AI-apps DLP policy, a Purview portal/tenant enablement guide, and verification + troubleshooting. Works with A365 agents in Node.js (@microsoft/agents-hosting), Python (microsoft-agents-hosting-*), and .NET (Microsoft.Agents.*).

Overview

Publishermicrosoft
Repositoryagent365-skills
Skill namepurview-dlp-integration
Stars
50
Forks
12
Bundled files
13
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 13 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by microsoft on GitHub. Read the source before you install it.

Installation

Install the Purview Dlp Integration AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/microsoft/agent365-skills/tree/main/plugins/agent365/skills/purview-dlp-integration
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/microsoft/agent365-skills.git /tmp/agent365-skills
mkdir -p .claude/skills
cp -r /tmp/agent365-skills/plugins/agent365/skills/purview-dlp-integration .claude/skills/purview-dlp-integration
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Purview Dlp Integration in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Purview Dlp Integration on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Purview Dlp Integration is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Microsoft Purview DLP Integration for Agent 365

Trigger phrases — any of these will activate this skill automatically:

  • "add Purview DLP to my agent"
  • "add data loss prevention to my A365 agent"
  • "block credit cards / SSNs / PII before my agent's LLM sees them"
  • "enforce compliance / audit on agent prompts and responses"
  • "wire a DLP gate into my agent code"
  • "call the Graph processContent API from my agent"
  • "add Purview blocking to my Node.js / Python / .NET agent"

Add a Purview data-loss-prevention gate before an existing A365 agent's LLM call: each prompt is evaluated via the Graph processContent API and blocked when an input-blocking policy matches. Optional response checks provide audit, not response blocking, for the supplied Applications policy. processContent sends the checked text to Microsoft Purview for evaluation and audit. Designed for minimal, reversible changes to the customer's agent.

When to use

  • "Add Purview DLP / data loss prevention to my agent."
  • "Block credit cards / SSNs / PII before my agent's LLM sees them."
  • "Enforce compliance / audit on agent prompts and responses."
  • Any A365 agent — Node.js, Python, or .NET — that needs inline DLP.

When NOT to use

  • Adding OpenTelemetry tracing / MAC Activity telemetry → use instrument-observability.
  • Diagnosing why telemetry isn't reaching MAC Activity / Defender → use a365-code-validator.
  • Provisioning the blueprint / Entra permissions from scratch → use a365-setup / make-a365-agent first, then return here.

How it works

user turn ─► [INPUT gate] processContent(uploadText, /me)  ─► block? ─► reply "blocked", STOP (LLM never called)
                                                            └─ allow ─► LLM ─► optional output audit ─► reply
  • Token: the agent's agentic delegated Graph token, evaluated as /me (the agent identity) — acquired via the agent's own auth handler: Node.js GetAgenticUserToken, Python authorization.exchange_token(…), .NET UserAuthorization.GetTurnTokenAsync(…). A365 blueprint apps cannot use app-only client-credentials here — Graph strips data-plane roles from that token.
  • Fail-closed by default: any Purview error/timeout blocks the turn.
  • Content limit: delegated guards reject messages over 100,000 characters before sending them to Graph, even in fail-open mode. They never approve a full message based on a prefix.
  • Output: PURVIEW_CHECK_OUTPUT=true submits responses for audit. The supplied workload does not support DownloadText blocking; do not promise that it filters sensitive responses. With fail-closed mode, a failed output audit still withholds the reply.
  • Policy: a dedicated Purview DLP policy scoped to the agent's Entra app id (portal: "Managed cloud apps" / Applications workload) with a RestrictAccess=Block rule.

S2S / app-only agents (autonomous, no AgentApplication)

For an agent that authenticates service-to-service (no signed-in user, no @microsoft/agents-hosting AgentApplication — e.g. an Express / worker-loop agent using the A365 FMI client-credentials chain), use the S2S guard assets/purview-s2s.ts instead of purview.ts.

Verified 2026-08-26: app-only DLP is supported — the "blueprint app-only tokens get stripped" rule is true for the blueprint app but not for the agent identity:

Token sourceroles in the Graph token
Blueprint app-only (client-credentials)AgentIdentity.CreateAsManager — Content.Process. STRIPPED*
Agent identity via the FMI 3-hop chainContent.Process.All RETAINED ✅

So the S2S guard (1) mints the agent identity's Graph token through the FMI chain (Blueprint → fmi_path → Agent Identity → Graph), (2) calls the app-only endpoint POST /beta/users/{sponsorUserId}/dataSecurityAndGovernance/processContent (app-only can't use /me), and (3) passes an agents:[{"@odata.type":"aiAgentInfo", blueprintId, identifier, name}] entry plus protectedAppMetadata.applicationLocation = the agent app id (the DLP policy scope).

Two steps differ from the delegated path:

  • Permission: grant Content.Process.All (Application) to the agent identity SP (not the blueprint) — run scripts/Grant-ContentProcessAppRole.ps1 instead of Grant-DelegatedGraphScope.ps1.
  • Wiring: import purviewGuard from ./purview-s2s.js and call evaluatePrompt(text) / evaluateResponse(text) directly around the LLM call (no TurnContext / Authorization args). The guard prefers the existing AGENT365_TENANT_ID, AGENT365_AGENT_ID, AGENT365_CLIENT_ID, and AGENT365_CLIENT_SECRET credentials; AGENT365_BLUEPRINT_ID sets the default policy app ID. Confirm these are configured: a365 setup all does not populate the lowercase agent365Observability__clientId / agent365Observability__clientSecret credentials. Use a real directory user object ID for PURVIEW_SPONSOR_USER_ID. Configure secrets directly in the environment or secret store, never in chat. This variant requires client-secret FMI; do not switch managed-identity-only agents to it.

Everything else — the DLP policy (Step 6), the [purview] log format, fail-closed semantics — is identical.


Before you start — read the A365 config, then ask for the rest

First, auto-discover from the project's A365 config. The guard and both scripts read these automatically, but read them yourself to confirm values and drive the workflow. From the agent project root, read a365.config.json and a365.generated.config.json:

ValueConfig source
App (client) id → PURVIEW_APP_IDa365.generated.config.json → agentBlueprintId (or botMsaAppId)
Blueprint id → PURVIEW_BLUEPRINT_IDa365.generated.config.json → agentBlueprintId
Agent SP object id (for the consent script)Resolved by the script for the requested app ID in the signed-in tenant; cached SP IDs are not trusted.
Display name → PURVIEW_APP_NAMEa365.config.json → agentBlueprintDisplayName / agentDescription
Tenant ida365.config.json → tenantId
Current Graph scopes (is Content.Process.User already granted?)a365.generated.config.json → resourceConsents[] where resourceName == "Microsoft Graph" → scopes

Then ask the customer only for what's not in config (use the ask-questions tool):

AskNotes / default
DLP policy — new, existing, or skipAlways ask (unless the user specified it when invoking the skill): create a new policy (default), use an existing one, or skip (they'll add it manually / already have it). Drives Step 6.
Sensitive info type(s) to blockDefault Credit Card Number. Any Purview SIT. Only needed when creating a new policy.
Admin UPN for alertsOptional; recommended (agents are unaware of blocks).
Agentic auth handler nameThe static authHandlerName on their AgentApplication (usually agentic).
Entry/handler file + LLM call siteWhere the message handler + LLM call live (locate in code when possible).
Who does Purview admin?Confirm they (or an admin) can enable billing/DSPM-for-AI + run the scripts.

If the project has no a365 config (non-A365 or not yet provisioned), ask for the app id, display name, and tenant id directly and pass them explicitly to the scripts/env.


Procedure

Before Step 1, show the following checklist. In Claude Code, use TaskCreate and TaskUpdate; in Copilot, show and update the Markdown checkboxes. Keep one item in progress and mark it complete as soon as its numbered steps finish. Do not mark a permission or policy failure complete.

  • Locate the handler and confirm its authentication (Steps 0-1)
  • Copy the guard and wire the checks (Steps 2-3)
  • Configure and verify enablement (Step 4)
  • Grant and verify Graph permission (Step 5)
  • Resolve policy choice and tenant prerequisites (Steps 6-7)
  • Build and verify a blocked turn (Step 8)

0. Detect the agent language

For delegated agents, pick the guard/wiring by the agent's stack (all three share the SAME env vars, PowerShell scripts, policy, and [purview] log format). For Node.js S2S, follow the S2S variant above instead of the delegated guard/wiring steps below.

LanguageDetect byGuard assetWiring
Node.js / TypeScriptpackage.json (@microsoft/agents-hosting)assets/purview.tsassets/wiring-snippet.ts
Pythonpyproject.toml / requirements.txt (microsoft-agents-hosting-*)assets/purview.pyassets/wiring-snippet.py
.NET*.csproj (Microsoft.Agents.*)assets/purview.csassets/wiring-snippet.cs

Node.js and Python guards are verified against a live agent; the .NET guard is a best-effort port — verify the ITurnContext / UserAuthorization namespaces against your SDK version.

1. Locate the agent code

Find the message handler (the method that calls the LLM) and the LLM call:

  • Node.js: the AgentApplication subclass, onActivity(ActivityTypes.Message, …).
  • Python: the AgentInterface implementation's process_user_message (or the aiohttp host's on_message).
  • .NET: the AgentApplication subclass's OnMessageAsync.

Confirm the A365 runtime/hosting package is present (Node.js @microsoft/agents-a365-runtime, Python microsoft-agents-hosting-core, .NET Microsoft.Agents.*) — standard for A365 agents. Confirm the selected handler can obtain a delegated Graph token; for .NET, its configured scopes must include https://graph.microsoft.com/.default. A plain bot without a supported hosting/authentication path cannot be integrated just by supplying app IDs: stop before copying the guard and route to a365-setup. Do not switch an existing S2S agent to delegated auth.

2. Add the guard (1 new file)

Copy the guard for your language into the agent's source folder (next to the agent class) — it is generic and env-driven, no edits needed:

3. Wire the two gates (minimal edits)

Apply the wiring snippet for your language to the message handler (and any notification/email handler that calls the LLM): import the guard, add the input gate before the LLM and the output gate before the reply is sent. Pass the agent's authorization handler + auth-handler name + turn context/id.

  • Node.js: assets/wiring-snippet.ts — passes this.authorization.
  • Python: assets/wiring-snippet.py — for response-returning process_user_message handlers; passes auth, auth_handler_name, context. The caller sends the returned text. If wiring directly into a host on_message callback instead, send the block/withhold message with await context.send_activity(...) and then return; returning a string alone does not send a reply.
  • .NET: assets/wiring-snippet.cs — passes UserAuthorization, the agentic handler name, turnContext.

4. Add environment variables

Use the keys from assets/purview.env.example, preserving existing values rather than appending duplicate keys:

  • Node.js / Python: add missing keys to .env, which their guards load.
  • .NET: set PURVIEW_DLP_ENABLED in the selected Properties/launchSettings.json profile's environmentVariables, or in the cloud host's process environment. A .env file or appsettings.json key alone is not loaded by this guard. For a one-session local run, PowerShell can set $env:PURVIEW_DLP_ENABLED = 'true' before dotnet run.

On a delegated A365 project the only required guard key is PURVIEW_DLP_ENABLED=true — the guard auto-reads PURVIEW_APP_ID / PURVIEW_APP_NAME / blueprint id from a365.config.json + a365.generated.config.json. Set them explicitly only to override or for a non-A365 project. Confirm the guard's isEnabled / is_enabled / IsEnabled is true in the running agent.

For Node.js S2S, confirm the canonical credentials listed above instead of relying on config auto-discovery.

5. Grant the delegated Graph scope

For Node.js S2S, use Grant-ContentProcessAppRole.ps1 as described above and skip this delegated step.

Run scripts/Grant-DelegatedGraphScope.ps1 from the agent project folder (needs az login). -AppId is auto-discovered from a365.generated.config.json (pass -AppId <app-id> to override, or -ConfigDir <path> if the config lives elsewhere). It appends Content.Process.User to the agent's existing agentic consent. Never run az ad app permission admin-consent on the blueprint app. The scripts stop on failed CLI commands or failed verification. Surface that failure and resolve the tenant/admin issue before claiming permission setup is complete; do not broaden permissions.

6. Choose the DLP policy — new, existing, or skip

Ask the user which policy to use (skip the prompt only if they already told you when invoking the skill, e.g. "use my existing 'Corp PII' policy", "create a new one", or "I'll add it manually"):

"Which Purview DLP policy should gate this agent?

  1. Create a new dedicated AI-app policy (default),
  2. Use an existing DLP policy you already have, or
  3. Skip — don't create one now; I'll add it manually (or already have one)."

The guard is policy-name-agnostic — it calls processContent with the agent's app id as the applicationLocation, and Purview evaluates every policy whose Applications location includes that app id. So this choice affects only this step, never the guard code.

Option A — Create a new policy (default): Run scripts/New-AiAppDlpPolicy.ps1 from the agent project folder (needs the ExchangeOnlineManagement module). -AppId / -AppName are auto-discovered from the a365 config; typically you only pass -SensitiveInfoType "Credit Card Number" -NotifyUser <admin-upn>. Override with -AppId / -AppName for a non-A365 project. Or follow references/purview-portal-guide.md to do it in the portal. The script reuses existing names only when the app, enforcement mode, and enabled input-blocking rule match. On a mismatch, it stops without modifying those objects. Ask the admin to review them or use distinct names; do not silently rewrite an existing policy.

Option B — Use an existing policy:

  1. List candidates (read-only) to see which policies already cover this agent's app id:
    powershell
    ./scripts/New-AiAppDlpPolicy.ps1 -ListExisting
    It connects to Security & Compliance and prints every DLP policy, flagging whether the agent's app id is already COVERS THIS APP.
  2. If the chosen policy already covers the app id — nothing to create; the guard will match it. Confirm its Mode is Enable and it has a RestrictAccess/Block rule on UploadText.
  3. If the chosen policy does not cover the app id — add this agent's app id to that policy's Applications (Managed cloud apps) location in the portal (purview-portal-guide.md), or fall back to Option A.

Option C — Skip (add the policy manually, or handle it later): Create nothing now. The guard stays wired and enabled — it just won't block until a matching policy exists (until then it logs allowed … 0 policyAction(s)). To add the policy yourself, it must have ALL of the following or the guard won't block (full portal walkthrough: purview-portal-guide.md):

#RequirementValue / note
1Location = Applications (portal: "Managed cloud apps")scoped to the agent's Entra app (client) id (PURVIEW_APP_ID). Do not combine Exchange/SharePoint/OneDrive/Teams in the same policy — Purview rejects that mix for this workload.
2Enforcement plane = ApplicationNOT "Copilot experiences" (that's first-party Copilot).
3Rule condition = Content contains sensitive info typeyour SIT(s), e.g. Credit Card Number.
4Rule action = Restrict access → Block on the prompt (UploadText)blocking the response (DownloadText) isn't supported for this workload → prompt/input gate only.
5Mode = Enableturn the policy on.
6(optional) Notify an admin UPNagents don't surface a block to a human.

Equivalent Security & Compliance PowerShell (exactly what Option A automates — run it by hand if you prefer):

powershell
Connect-IPPSSession
$loc = '[{"Workload":"Applications","Location":"<APP_ID>","LocationDisplayName":"<name>","LocationSource":"Entra","LocationType":"Individual","Inclusions":[{"Type":"Tenant","Identity":"All"}]}]'
New-DlpCompliancePolicy -Name "<policy>" -Mode Enable -Locations $loc -EnforcementPlanes @('Application')
New-DlpComplianceRule   -Name "<rule>" -Policy "<policy>" `
  -ContentContainsSensitiveInformation @(@{ Name = 'Credit Card Number' }) `
  -RestrictAccess @(@{ setting = 'UploadText'; value = 'Block' })

Judge success only by the agent's [purview] uploadText -> BLOCKED (… 1 policyAction(s) … errors=0) log line — not by DistributionStatus (shows Pending even for live policies). Allow up to ~1 hour to propagate.

7. Confirm tenant prerequisites

DLP-for-AI is metered. If everything is configured but nothing blocks (with errors=0), verify pay-as-you-go billing + DSPM-for-AI onboarding + licensing — see references/purview-portal-guide.md §0.

8. Build, run, verify

Rebuild/restart the agent so it reloads .env (Node.js: npm run build && npm start; Python: restart the existing Python command; .NET: dotnet run with the configured process environment from Step 4). Send a message containing a Luhn-valid test value, e.g. My credit card is 4111 1111 1111 1111. Watch the console. Verify that a blocked prompt never reaches the LLM call, not just that a block log appears. Also send an ordinary prompt and confirm it reaches the LLM. Output audit is not proof of response blocking for this workload.


Verify — expected logs

[turn] in  <- ... text="My credit card is 4111 1111 1111 1111"
[purview] uploadText -> BLOCKED (HTTP 200, 1 policyAction(s), scopeState=modified, errors=0)
  • ✅ BLOCKED + 1 policyAction(s) + errors=0 → working; the agent replies with the block message and the LLM is never called.
  • allowed (… 0 policyAction(s) … errors=0) → request fine, but no policy matched yet (scope/propagation/tenant enablement).
  • REQUEST ERROR (… errors=1 …) → malformed request (usually the name field) — see troubleshooting.

Full symptom→fix table: references/troubleshooting.md.


Dependencies (customer agent)

No extra Graph SDK / @azure/identity / MSAL needed for any language — the guard uses the agent's own agentic auth handler + a plain HTTPS POST.

  • Node.js: @microsoft/agents-hosting + @microsoft/agents-a365-runtime, Node 18+ (global fetch), dotenv.
  • Python: microsoft-agents-hosting-core + httpx (both standard in A365 Python agents), python-dotenv.
  • .NET: Microsoft.Agents.* hosting packages (standard); uses System.Net.Http + System.Text.Json (no extra NuGet).

Non-negotiable constraints (why it's built this way)

  1. Agentic delegated token + /me (AgentApplication agents); agent-identity FMI token (S2S agents) — a blueprint app-only token is stripped of data-plane roles (Content.Process.*) by Graph, so an AgentApplication agent must use its agentic delegated token (Node.js AgenticAuthenticationService.GetAgenticUserToken, Python authorization.exchange_token(…), .NET UserAuthorization.GetTurnTokenAsync(…)). But an S2S / autonomous agent CAN do app-only DLP — using the agent identity's FMI-minted Graph token (not the blueprint's) against /users/{sponsor}/… instead of /me. See "S2S / app-only agents" above. Do not "fix" the AgentApplication path by switching it to client-credentials.
  2. contentEntry.name is required — omitting it returns a permanent BadRequest that looks like a clean allow. The guard always sets it and treats processingErrors as fail-closed.
  3. Dedicated AI-app policy — the Applications/Managed-cloud-apps location can't be combined with Exchange/SharePoint/OneDrive/Teams in one policy.
  4. RestrictAccess block, EnforcementPlanes=Application — not BlockAccess, not CopilotExperiences (that's first-party Copilot).
  5. Never admin-consent the blueprint app — it can narrow the agentic consent and break the agent's sign-in. Append the scope instead.
  6. Trust the [purview] log, not DistributionStatus (which reads Pending even for live policies).

Files in this skill

FilePurpose
assets/purview.ts · purview.py · purview.csDrop-in DLP guard (Node.js / Python / .NET — generic, env-driven).
assets/purview-s2s.tsS2S (app-only) DLP guard for autonomous Node.js agents — agent-identity FMI Graph token, /users/{sponsor} endpoint.
assets/wiring-snippet.ts · .py · .csThe minimal handler edits (Node.js / Python / .NET).
assets/purview.env.exampleEnvironment variables (same for all three languages).
scripts/Grant-DelegatedGraphScope.ps1Append the delegated Graph scope (surgical, no admin-consent).
scripts/Grant-ContentProcessAppRole.ps1S2S: grant Content.Process.All (Application) to the agent identity SP.
scripts/New-AiAppDlpPolicy.ps1Create the AI-app DLP policy + block rule.
references/purview-portal-guide.mdTenant enablement (billing/DSPM) + manual portal policy steps.
references/troubleshooting.mdLog reference + symptom→cause→fix table.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Purview Dlp Integration AI skill do?

Integrate Microsoft Purview DLP (data loss prevention) + audit into an existing Microsoft Agent 365 (A365 SDK) agent, so sensitive prompts are blocked before the LLM and responses can be audited. Use when a user wants to add Purview DLP to an AI agent, block sensitive data (credit cards, SSNs, PII) in agent turns, enforce data protection/compliance on an A365 AgentApplication, call the Graph processContent API, or wire a DLP gate into agent code. Bundles drop-in guards for Node.js/TypeScript, Python, and .NET, minimal wiring for each, a PowerShell script to create the AI-apps DLP policy, a...

Why use Purview Dlp Integration on TypingMind?

Because you install it once and use it with any model. Purview Dlp Integration is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Purview Dlp Integration in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/microsoft/agent365-skills/tree/main/plugins/agent365/skills/purview-dlp-integration. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Purview Dlp Integration?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Purview Dlp Integration?

As many as you like. As long as a model supports skills, you can use Purview Dlp Integration with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Purview Dlp Integration AI skill free?

Yes. It is published on GitHub by microsoft under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇