KS
Killer-Skills

add-vocab — how to use add-vocab how to use add-vocab, what is add-vocab, add-vocab alternative, add-vocab vs fedify, add-vocab install, add-vocab setup guide, ActivityPub server framework, TypeScript vocabulary management, fediverse development tools

v1.0.0
GitHub

About this Skill

Ideal for TypeScript-based AI Agents requiring customized vocabulary extensions for ActivityPub server frameworks add-vocab is a skill for adding vocabulary to @fedify/vocab package using YAML definition files and code generation in a TypeScript environment.

Features

Creates YAML definition files in packages/vocab/src/
Utilizes code generation for new vocabulary types
Requires human review for vocabulary definitions
Ensures wire compatibility with existing software in the fediverse
Supports ActivityPub server framework in TypeScript
Integrates with technologies like Bun, Deno, and NodeJS

# Core Topics

fedify-dev fedify-dev
[947]
[95]
Updated: 2/28/2026

Quality Score

Top 5%
47
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add fedify-dev/fedify/add-vocab

Agent Capability Analysis

The add-vocab MCP Server by fedify-dev is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for how to use add-vocab, what is add-vocab, add-vocab alternative.

Ideal Agent Persona

Ideal for TypeScript-based AI Agents requiring customized vocabulary extensions for ActivityPub server frameworks

Core Value

Empowers agents to seamlessly integrate new vocabulary types into the @fedify/vocab package using YAML definition files and code generation, ensuring wire compatibility with existing software in the fedi ecosystem through careful human review of vocabulary definitions

Capabilities Granted for add-vocab MCP Server

Extending vocabulary for ActivityPub server frameworks
Creating custom YAML definition files for @fedify/vocab
Reviewing and merging new vocabulary definitions

! Prerequisites & Limits

  • Requires human review of vocabulary definitions
  • TypeScript environment necessary
  • Compatibility issues may arise if vocabulary definitions contain errors
Project
SKILL.md
15.8 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8
SKILL.md
Readonly

Adding vocabulary to @fedify/vocab

To add a new vocabulary type to the @fedify/vocab package, create a YAML definition file in packages/vocab/src/, then run code generation.

Human review requirement

Vocabulary definitions must always be reviewed carefully by a human before being merged. Errors in vocabulary definitions are difficult to fix after release because they break wire compatibility with existing software in the fediverse. Specifically, verify:

  • The type URI and property URIs match the spec exactly (a single character difference causes silent interoperability failures)
  • The defaultContext is complete and all terms compact correctly (see “Ensuring Complete Compaction Coverage” below)
  • The entity flag is correct — getting this wrong changes the entire async/sync interface contract
  • The functional flag is correct — marking a multi-valued property as functional silently drops values
  • Every property range entry is accurate — wrong range types produce incorrect TypeScript types
  • The spec document (FEP or W3C spec) has been read in full, not just skimmed

Do not rely solely on automated checks (mise run check)—they verify only TypeScript compilation, not semantic correctness of the vocabulary.

Workflow

  1. Read the spec document (FEP, W3C spec, or informal documentation) carefully
  2. Identify the type's URI, JSON-LD context, and properties
  3. Check whether the JSON-LD context URL is already preloaded in packages/vocab-runtime/src/contexts.ts
  4. Create the YAML file at packages/vocab/src/<typename-lowercase>.yaml
  5. If a new context URL is needed, add it to packages/vocab-runtime/src/contexts.ts
  6. Run mise run codegen to generate TypeScript classes
  7. Run mise run check to verify everything compiles
  8. Ask the user to review the YAML definition and generated code carefully before committing

The generated TypeScript class is automatically exported from @fedify/vocab via packages/vocab/src/vocab.ts (generated) and packages/vocab/src/mod.ts.

YAML file format

Every YAML file must begin with the schema reference:

yaml
1$schema: ../../vocab-tools/schema.yaml

Top-level fields

FieldRequiredDescription
nameyesTypeScript class name (PascalCase, e.g. Note)
uriyesFully qualified RDF type URI
entityyestrue for entity types (async property accessors); false for value types (sync accessors). Must be consistent across the inheritance chain.
descriptionyesJSDoc string. May use {@link ClassName} for cross-references.
propertiesyesArray of property definitions (can be empty [])
compactNamenoShort name in compact JSON-LD (e.g. "Note"). Omit if the type has no compact representation.
extendsnoURI of the parent type. Omit for root types.
typelessnoIf true, @type is omitted when serializing to JSON-LD. Used for anonymous structures like Endpoints or Source.
defaultContextnoJSON-LD context used by toJsonLd(). See below.

Entity vs. value type (entity flag):

  • entity: true — property accessors are async and can fetch remote objects
  • entity: false — property accessors are synchronous; used for embedded value objects (e.g. Endpoints, Source, Hashtag)

defaultContext format

The defaultContext field specifies the JSON-LD @context written when toJsonLd() is called. It can be:

A single context URL:

yaml
1defaultContext: "https://www.w3.org/ns/activitystreams"

An array of URLs and/or embedded context objects:

yaml
1defaultContext: 2 - "https://www.w3.org/ns/activitystreams" 3 - "https://w3id.org/security/data-integrity/v1" 4 - toot: "http://joinmastodon.org/ns#" 5 Emoji: "toot:Emoji" 6 sensitive: "as:sensitive" 7 featured: 8 "@id": "toot:featured" 9 "@type": "@id"

Embedded context entries are YAML mappings where:

  • String value "prefix:term" or "https://..." defines a simple term alias
  • Object value with "@id" and optionally "@type": "@id" defines a term that should be treated as an IRI (linked resource)

Ensuring complete compaction coverage

The defaultContext must cover every term that appears in the JSON-LD document produced by toJsonLd(), including:

  1. The type's own compactName — if the type has a compactName, the context must map that name to the type's URI.

  2. All own property compactNames — every property defined directly on this type must have its compactName (or full URI fallback) resolvable via the context.

  3. Inherited properties — properties from parent types are usually covered by the parent's context URL (e.g., https://www.w3.org/ns/activitystreams covers all core ActivityStreams properties). Verify that the parent's context URL is included.

  4. Properties of embedded types — when a property's value is an object type that is serialized inline (not just referenced by URL), the context must also cover all of that embedded type's properties. This is the most commonly missed case.

    Common embedded types and the context URLs that cover them:

    Embedded typeContext URL to include
    DataIntegrityProof (from proof)https://w3id.org/security/data-integrity/v1
    Key (from publicKey)https://w3id.org/security/v1
    Multikey (from assertionMethod)https://w3id.org/security/multikey/v1
    DidService (from service)https://www.w3.org/ns/did/v1
    PropertyValue (from attachment)schema.org terms in embedded context
  5. Redundant property compactNames — if a property has redundantProperties, all their compactNames must also be defined in the context.

Practical rule: look at an existing type with similar embedded relationships as a reference. For example, Note and Article include "https://w3id.org/security/data-integrity/v1" because they embed DataIntegrityProof objects via the proof property. Person additionally includes security and DID contexts because it embeds Key, Multikey, and DidService objects inline.

Omitting a required context causes silent compaction failure: the property appears in expanded form ("https://example.com/ns#term": [...]) rather than compact form ("term": ...) in the output.

Property definitions

Each entry in properties is one of two kinds:

Non-functional property (multiple values)

Generates get<PluralName>() async iterable and optionally a singular accessor.

yaml
1- pluralName: attachments # accessor: getAttachments() / attachments 2 singularName: attachment # used if singularAccessor: true 3 singularAccessor: true # also generate getAttachment() / attachment 4 compactName: attachment # JSON-LD compact key 5 uri: "https://www.w3.org/ns/activitystreams#attachment" 6 description: | 7 Identifies a resource attached or related to an object. 8 range: 9 - "https://www.w3.org/ns/activitystreams#Object" 10 - "https://www.w3.org/ns/activitystreams#Link"

Required: pluralName, singularName, uri, description, range

Optional: singularAccessor (default false), compactName, subpropertyOf, container ("graph" or "list"), embedContext, untyped

Functional property (exactly one value)

Generates a single get<SingularName>() / <singularName> accessor.

yaml
1- singularName: published 2 functional: true 3 compactName: published 4 uri: "https://www.w3.org/ns/activitystreams#published" 5 description: The date and time at which the object was published. 6 range: 7 - "http://www.w3.org/2001/XMLSchema#dateTime"

Required: singularName, functional: true, uri, description, range

Optional: compactName, subpropertyOf, redundantProperties, untyped, embedContext

Redundant properties (functional only)

When a property has equivalent URIs from multiple vocabularies, use redundantProperties to write all aliases on serialization and try them in order on deserialization:

yaml
1- singularName: quoteUrl 2 functional: true 3 compactName: quoteUrl 4 uri: "https://www.w3.org/ns/activitystreams#quoteUrl" 5 redundantProperties: 6 - compactName: _misskey_quote 7 uri: "https://misskey-hub.net/ns#_misskey_quote" 8 - compactName: quoteUri 9 uri: "http://fedibird.com/ns#quoteUri" 10 description: The URI of the quoted ActivityStreams object. 11 range: 12 - "fedify:url"

The embedContext field

Use embedContext when a nested object should carry its own @context (e.g., proof graphs in Data Integrity):

yaml
1embedContext: 2 compactName: proof # key under which the context is embedded 3 inherit: true # use the same context as the enclosing document

The untyped field

When untyped: true, the serialized value will not have a @type field. Requires exactly one type in range. Used for embedded anonymous structures:

yaml
1- singularName: source 2 functional: true 3 compactName: source 4 uri: "https://www.w3.org/ns/activitystreams#source" 5 description: The source from which the content markup was derived. 6 untyped: true 7 range: 8 - "https://www.w3.org/ns/activitystreams#Source"

Range type reference

XSD scalar types → TypeScript types

Range URITypeScript type
http://www.w3.org/2001/XMLSchema#stringstring
http://www.w3.org/2001/XMLSchema#booleanboolean
http://www.w3.org/2001/XMLSchema#integernumber
http://www.w3.org/2001/XMLSchema#nonNegativeIntegernumber
http://www.w3.org/2001/XMLSchema#floatnumber
http://www.w3.org/2001/XMLSchema#anyURIURL (stored as @id)
http://www.w3.org/2001/XMLSchema#dateTimeTemporal.Instant
http://www.w3.org/2001/XMLSchema#durationTemporal.Duration
http://www.w3.org/1999/02/22-rdf-syntax-ns#langStringLanguageString

Security scalar types

Range URITypeScript type
https://w3id.org/security#cryptosuiteString"eddsa-jcs-2022"
https://w3id.org/security#multibaseUint8Array

Fedify internal types

Range URITypeScript typeNotes
fedify:langTagIntl.LocaleBCP 47 language tag as plain string
fedify:urlURLURL stored as @value (not @id)
fedify:publicKeyCryptoKeyPEM SPKI-encoded public key
fedify:multibaseKeyCryptoKeyMultibase-encoded key (Ed25519)
fedify:proofPurpose"assertionMethod" | "authentication" | ...Proof purpose string
fedify:units"cm" | "feet" | "inches" | "km" | "m" | "miles"Place units

Vocabulary types

Any uri from another YAML vocabulary file can be used as a range. The TypeScript type will be the corresponding generated class (e.g., "https://www.w3.org/ns/activitystreams#Object"Object).

Adding preloaded JSON-LD contexts

When defaultContext references a URL not already in packages/vocab-runtime/src/contexts.ts, add it to preloadedContexts.

Check existing keys in that file first by searching for the URL. If missing, fetch the actual context document from its canonical URL and add an entry:

typescript
1"https://example.com/ns/v1": { 2 "@context": { 3 // ... paste actual context content here ... 4 }, 5},

The keys of preloadedContexts must match the URL strings used in YAML defaultContext fields. This enables offline JSON-LD processing.

Complete minimal example

yaml
1$schema: ../../vocab-tools/schema.yaml 2name: Move 3compactName: Move 4uri: "https://www.w3.org/ns/activitystreams#Move" 5extends: "https://www.w3.org/ns/activitystreams#Activity" 6entity: true 7description: | 8 Indicates that the actor has moved object from origin to target. 9 If the origin or target are not specified, either can be determined by 10 context. 11defaultContext: 12 - "https://www.w3.org/ns/activitystreams" 13 - "https://w3id.org/security/data-integrity/v1" 14properties: []

Complete extended example (new vocabulary type)

When implementing a new type from a FEP (e.g. a new Interaction type with custom properties from a hypothetical https://example.com/ns# namespace):

yaml
1$schema: ../../vocab-tools/schema.yaml 2name: Interaction 3compactName: Interaction 4uri: "https://example.com/ns#Interaction" 5extends: "https://www.w3.org/ns/activitystreams#Activity" 6entity: true 7description: | 8 Represents a generic interaction with an object. 9 See [FEP-xxxx](https://w3id.org/fep/xxxx). 10defaultContext: 11 - "https://www.w3.org/ns/activitystreams" 12 - "https://w3id.org/security/data-integrity/v1" 13 - example: "https://example.com/ns#" 14 Interaction: "example:Interaction" 15 interactionCount: 16 "@id": "example:interactionCount" 17 "@type": "http://www.w3.org/2001/XMLSchema#nonNegativeInteger" 18 19properties: 20 - singularName: interactionCount 21 functional: true 22 compactName: interactionCount 23 uri: "https://example.com/ns#interactionCount" 24 description: The number of interactions recorded. 25 range: 26 - "http://www.w3.org/2001/XMLSchema#nonNegativeInteger" 27 28 - pluralName: participants 29 singularName: participant 30 singularAccessor: true 31 compactName: participant 32 uri: "https://example.com/ns#participant" 33 description: Actors who participated in this interaction. 34 range: 35 - "https://www.w3.org/ns/activitystreams#Person" 36 - "https://www.w3.org/ns/activitystreams#Group" 37 - "https://www.w3.org/ns/activitystreams#Organization" 38 - "https://www.w3.org/ns/activitystreams#Service" 39 - "https://www.w3.org/ns/activitystreams#Application"

Related Skills

Looking for an alternative to add-vocab or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication