Skip to content

For Developers

Doable is open source and pluggable from every angle. Whether you're a workspace member tinkering with custom skills or an external contributor sending a PR, this section covers extending Doable from the outside. For the platform's internal architecture, see Architecture. For day-to-day usage, see the User Guide.

What can you extend?

Doable was built so that almost every layer is replaceable or extensible:

Surface What it is Where to add it
Skills Reusable instructions the AI auto-invokes when a task matches Workspace UI, or via the API
MCP servers External tool servers speaking the Model Context Protocol Workspace Settings → Connectors
Knowledge bases Markdown context files the AI reads on every interaction Workspace Settings → Knowledge
AI providers Anthropic, OpenAI, Copilot CLI, your own LLM Code (PR to the doable repo)
Integrations Linear, Gmail, Stripe, GitHub, any third-party API Code (PR to the doable repo)
Templates Starter projects users can fork Marketplace

The first three you can add without touching Doable's source code; they're configured per workspace. The last three are pull requests to the doable repo.

The shipping mental model

Every Doable extension is two things:

  1. Code: a JavaScript/TypeScript module, a process that speaks MCP, a markdown file, or just a config object.
  2. A manifest: a description the AI reads to decide when and how to use your extension.

Manifests are the single most important piece. The AI doesn't grep your code; it reads the manifest's name, description, and parameter schema and decides on that basis. A well-described extension is one the AI uses; a vague one sits unused.

Scope determines reach:

  • User-scoped: only you see it.
  • Project-scoped: only this project gets it.
  • Workspace-scoped: every member of the workspace.
  • Platform-wide: shipped in the doable repo, available to every install.

The same scope ladder applies to skills, MCP connectors, and rules.

Quick walkthrough: your first custom skill

Skills are the cheapest extension to ship. They're markdown files with YAML frontmatter plus optional companion files, materialized on disk and handed to the AI as one of its skillDirectories. The AI's host (the Copilot SDK) discovers them and auto-invokes when a user request matches the description.

Let's build a tiny skill that teaches the AI your team's commit message convention.

1. Open the workspace Skills panel

In the editor sidebar, click Skills. Each section header (Workspace / Project / Personal) has a + button.

Hit + next to Workspace.

2. Fill in the form

Field Value
Name Commit messages
Description Use this when writing git commits. Apply our team's commit message style.
Auto-invoke ✅ (the default)

In the body:

# Commit Messages

Our team writes commits in this format:
():

- `type` is one of: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`.
- `scope` is the package or module touched (e.g. `api`, `web`, `db`).
- `subject` is imperative, present tense, under 70 chars.
- Add a body paragraph if the *why* isn't obvious from the diff.

## Examples
feat(api): rate-limit /chat to 60 req/min per workspace fix(web): preview iframe leaks scroll position on navigation

### 3. Save The skill is now in the database (`context_skills` table) and materialized to disk under `$DOABLE_PROJECTS_DIR/.skills-cache//workspace/commit-messages/SKILL.md` on the next chat session. See [`services/api/src/ai/skills-materializer.ts`](https://github.com/doable-me/doable/blob/main/services/api/src/ai/skills-materializer.ts) for the materialization logic. ### 4. Try it Open chat and ask: > *"Write a commit message for the changes I just made to apps/web."* The AI's host will surface your skill and inject the markdown into the system prompt before responding. You should see the AI emit a commit in your team's exact format. !!! tip "Frontmatter is added for you" If your markdown doesn't start with `---\nname: ...\n---`, the materializer adds it from the name + description fields. You can also write your own frontmatter if you want fine-grained control; Doable preserves it untouched. That's the entire loop: **define, save, AI uses**. No restart, no deploy, no PR. ## Where to go next | If you want to... | Read | |---|---| | Write more advanced skills (multi-file, scoped) | [Custom Skills](custom-skills.md) | | Connect an external tool server (MCP) | [MCP Servers](mcp-servers.md) | | Curate the knowledge the AI sees | [Knowledge Bases](knowledge-bases.md) | | Add an LLM provider or third-party integration to the codebase | [Contributing Providers & Integrations](contributing-providers-and-integrations.md) | !!! note "Security model" Every workspace-scoped extension is created by a workspace admin and runs with the workspace's credentials, never your personal user account's secrets. See [Security Model](../security/security-model.md) for the boundary between workspace, user, and platform scope. When in doubt, **start with a skill**. If a skill isn't enough (you need to call an external API, read a database, or perform a stateful operation), graduate to an MCP server. If even that isn't enough, contribute a first-class integration or AI provider in the codebase.