Adding a new content type

folio-assistant is content-agnostic by design. A new content type (“others” in the supported-types list) is added by providing two things — a content adapter and a skill package — after which the lifecycle, RBAC, MCP transport, and work-plan plumbing all apply for free.

  1. What you provide
  2. Before you add one: could it be a profile instead?
  3. 1. The content adapter
  4. 2. The skill package
  5. 3. The skill schemas
  6. 4. Reuse the lifecycle
  7. Checklist

What you provide

flowchart LR
    New[New content type] --> A[Content adapter<br/>adapters/your-type/]
    New --> P[Skill package<br/>skills/authoring-your-type/]
    A --> Server[FolioServer registers adapter tools]
    P --> Schemas[schemas/skills/your-skill/*]
    P --> Manifest[package-manifest.json · Docker deps]

Before you add one: could it be a profile instead?

Two content types that share a content model and differ only in which block kinds they admit do not need two adapters. document and paper are one adapter with two profiles — nested restrictions of one vocabulary — and the paper adapter is a fifty-line subclass of the document one.

The test is whether the new type needs different code (a different resolver, different tools, a different render path) or only different rules about what its blocks may be. If it is only rules, add a profile in schemas/block-kinds.ts and a subclass; you get the whole platform for a fraction of the work, and there is one implementation to keep correct rather than two.

Adapters are for genuinely disjoint namespaces — paper and dak share no block kind at all.

1. The content adapter

Model the document adapter (adapters/document/), which is the base for prose folios, or paper (adapters/paper/) for how a specialization extends one. An adapter:

  • implements the content-adapter interface the FolioServer expects (list / validate / build, plus any type-specific tools);
  • registers its MCP tools via server.tool(...) (e.g. the paper adapter adds paper_render_pdf, lean_build, …);
  • resolves paths in the content repo, not in folio-assistant.

Wire it up by selecting it through the folio config:

{
  "contentType": "your-type",
  "adapter": "your-type",
  "adapterModule": "./adapters/your-type/index.ts"
}

2. The skill package

Create skills/authoring-your-type/package-manifest.json declaring the skills and the Docker/runtime dependencies (apt/pip/npm, setup commands, env). Follow the existing manifests (authoring-math, authoring-who-smart-guidelines):

{
  "name": "authoring-your-type",
  "version": "0.1.0",
  "description": "…",
  "skills": ["your-authoring", "your-validation"],
  "docker": { "baseImage": "ubuntu:24.04", "aptPackages": ["…"] },
  "providesCapabilities": ["…"],
  "lifecycleStages": ["plan", "author", "validate", "review", "test", "publish"]
}

3. The skill schemas

For each skill, add schemas/skills/<skill>/input.schema.json and output.schema.json (JSON Schema draft-07), and name them in the skill’s own front matter (input: schemas/skills/<skill>/input.schema.json, output: …). These are the typed contract the LLM works against; a contract no skill names is reported as unclaimed. Then regenerate the reference:

bun run scripts/gen-schema-docs.ts

Your skill pages appear automatically in the Skill schema reference.

4. Reuse the lifecycle

You do not re-implement plan/author/validate/review/test/publish — the cross-cutting content-lifecycle package already provides those stages. Your package only adds the authoring skills unique to the type.

Checklist

  • Considered a profile first — a subclass plus a kind list, not a new adapter
  • Adapter under adapters/<type>/ implementing list/validate/build + tools
  • <name>.config.json points at the adapter
  • Skill package + package-manifest.json with Docker deps
  • JSON Schemas under schemas/skills/<skill>/
  • bun run scripts/gen-schema-docs.ts regenerated
  • Capabilities probed by check_dependencies
  • Tests (bun test) and lint (bun run cat lint) green

folio-assistant — code under the Apache License 2.0, documentation under CC BY 3.0. Generated schema and API references are rebuilt from source on every push to main.

deployed b08c961 · 2026-10-23T23:11:09Z