What Are OpenWork Skills and How to Create Custom Skills
OpenWork skills are reusable, instructional markdown documents that agents discover and invoke through the OpenWork capability rail, enabling teams to standardize AI-assisted workflows without writing code.
An OpenWork skill is a plain-text markdown file with minimal front-matter that describes a prompt, workflow, or guidance for LLM-based agents. Skills serve as the foundational building blocks of the OpenWork platform, allowing developers to package expertise into discoverable, versionable artifacts. This guide explains the skill architecture in the different-ai/openwork repository and walks through creating custom skills for both local use and marketplace distribution.
Understanding OpenWork Skill Types
Skills exist in two scopes with identical runtime contracts but different discovery mechanisms.
Local Skills
Local skills reside in a workspace's skills/ folder on the developer's machine. They are discovered via the listLocalSkills desktop command defined in DesktopCommandMap and appear in the UI under Settings → Skills.
The IPC contract for local skill management lives in packages/types/src/desktop-ipc.ts (lines 499–514), where commands like importSkill, installSkillTemplate, listLocalSkills, readLocalSkill, writeLocalSkill, and uninstallSkill are typed.
Marketplace (Plugin) Skills
Marketplace skills are bundled inside OpenWork plugins and stored in the cloud marketplace. They are indexed in the Den database as configObject records of type skill, discoverable through the universal search_capabilities tool, and executable via execute_capability.
Both types deliver the markdown body directly to agents without server-side code execution, making skills safe prompt templates that support $ARGUMENTS substitution when marked as command type.
Creating a Custom OpenWork Skill
Step 1: Write the Markdown File
Create a .md file with required front-matter fields (name and description). The body contains free-form instructions for the agent.
---
name: My Custom Skill
description: Summarise a pull-request with a short bullet list.
---
Provide a concise summary of the changes in the PR titled **{{title}}**.
Include:
- The main purpose
- Any breaking changes
- A suggested next step
The front-matter format matches the marketplace parser's expectations. The apps/server/src/skills.ts file implements server-side validation and index updates for local skills.
Step 2: Install the Skill Locally
Use the OpenCode CLI to register the skill in your workspace:
opencode skill install \
--project-dir . \
--name "My Custom Skill" \
--content "$(cat my-skill.md)"
This invokes the installSkillTemplate handler (defined at packages/types/src/desktop-ipc.ts lines 504–508), which writes the file to skills/, updates the local index, and returns an ExecResult.
Step 3: Import Multiple Skills (Batch)
For existing skill directories, import recursively:
opencode skill import \
--project-dir . \
--source-dir ./my-skills
The importSkill command (lines 499–502 in desktop-ipc.ts) processes each markdown file and registers it individually.
Step 4: Publish as a Marketplace Plugin
For organization-wide sharing, package skills into a plugin:
- Create plugin scaffold using OpenWork's
create-pluginskill or CLI - Add markdown files under
plugin-root/skills/ - Build the plugin with
pnpm build-plugin - Publish via OpenWork Den UI or
openwork plugin publish
The marketplace ingestion pipeline extracts skills as configObject type skill records. See docs/marketplace-capabilities-architecture.md for the indexing and search implementation.
Working with Skills Programmatically
List Local Skills
// TypeScript using the Desktop bridge
import { desktop } from "@/app/lib/desktop";
async function showLocalSkills() {
const skills = await desktop.listLocalSkills("/path/to/workspace");
console.log("Local skills:", skills);
}
This calls listLocalSkills from DesktopCommandMap, returning metadata for all skills in the workspace's skills/ directory.
Execute a Marketplace Skill
// Agent side: discover and run a shared skill
await ctx.prove("Run a shared skill", async () => {
const match = await ctx.search_capabilities({ query: "My Custom Skill" });
const skillName = match.find(m => m.name.includes("My Custom Skill"))?.name;
if (!skillName) throw new Error("Skill not found");
const result = await ctx.execute_capability({ name: skillName });
console.log("Skill content:", result.content);
});
search_capabilities queries the marketplace index; execute_capability returns the raw markdown with provenance metadata indicating the originating plugin.
Generate Skills Dynamically
await desktop.writeLocalSkill(
"/path/to/workspace",
"Dynamic Skill",
`---
name: Dynamic Skill
description: Generated at runtime.
---
Hello, this skill was generated on ${new Date().toISOString()}!`
);
The writeLocalSkill command enables runtime skill creation for adaptive workflows.
Key Implementation Files
| File | Purpose |
|---|---|
packages/types/src/desktop-ipc.ts |
Central type definitions for all skill-related IPC commands including importSkill, installSkillTemplate, listLocalSkills, readLocalSkill, writeLocalSkill, and uninstallSkill |
apps/server/src/skills.ts |
Server-side handler implementing IPC commands, markdown validation, and local skill index management |
docs/marketplace-capabilities-architecture.md |
Documentation for marketplace skill indexing, search_capabilities integration, and execute_capability response format |
ee/apps/den-web/tests/skill-crud-data.test.ts |
Unit tests verifying skill markdown round-trips through the shared format |
Summary
- OpenWork skills are markdown documents with front-matter that agents use as reusable instructions
- Local skills live in workspace
skills/folders and are managed viaDesktopCommandMapIPC commands - Marketplace skills are plugin-bundled, cloud-hosted, and discovered through
search_capabilities/execute_capability - Creating custom skills requires only markdown authoring; no code compilation or server deployment
- Publishing to marketplace requires plugin packaging but enables team-wide discovery and version control
Frequently Asked Questions
What file format do OpenWork skills use?
OpenWork skills use standard markdown with YAML front-matter. The front-matter must include name and description fields; the body contains arbitrary instructions for agents. The format is identical for local and marketplace skills, ensuring portability between scopes.
Can skills execute code on my machine?
No. Skills are pure text documents delivered to agents as prompt templates. The markdown body is returned verbatim; any code execution happens only if an agent chooses to act on the instructions. This design makes skills safe to share and audit.
How do I share a skill with my entire organization?
Package the skill in an OpenWork plugin, place it in the plugin's skills/ directory, and publish to the marketplace. Once published, anyone with viewer access to the plugin can discover the skill via search_capabilities. The skill inherits the plugin's permission grants.
What's the difference between installSkillTemplate and importSkill?
installSkillTemplate creates a single skill from inline content or a file, while importSkill recursively processes an entire directory of .md files. Both are defined in packages/types/src/desktop-ipc.ts and handled by apps/server/src/skills.ts, but importSkill is optimized for bulk migrations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →