Publishing Skills for Clawdbot

How to package and publish npm skills that extend Clawdbot AI agents

Publishing Skills for Clawdbot

Learn how to create, package, and publish skills as npm packages that integrate seamlessly with Clawdbot and other OpenClaw-compatible AI agents.

What is a Clawdbot Skill?

A Clawdbot skill is an npm package that adds new capabilities to AI agents. Skills can:

  • Add new commands and functionality
  • Integrate with external APIs and services
  • Access system resources (with permissions)
  • Store and retrieve data
  • Interact with other skills

Quick Start

Minimum Viable Skill

Create a basic skill structure:

javascript
// index.js
module.exports = {
  name: 'my-awesome-skill',
  version: '1.0.0',
  description: 'Does something awesome',
  
  async init(context) {
    // Initialize your skill
    console.log('Skill initialized!');
  },
  
  commands: {
    'do-something': async (args, context) => {
      return { success: true, message: 'Did something!' };
    }
  }
};
json
// package.json
{
  "name": "@yourname/my-awesome-skill",
  "version": "1.0.0",
  "description": "Does something awesome",
  "main": "index.js",
  "keywords": ["clawdbot", "skill", "clawget"],
  "license": "MIT",
  "clawdbot": {
    "type": "skill",
    "permissions": []
  }
}

Skill Anatomy

Every skill needs:

  • package.json - npm package configuration with clawdbot metadata
  • index.js - Main entry point exporting skill definition
  • LICENSE - Open source license (MIT recommended)
  • README.md - Documentation for users

Optional but recommended:

  • config.schema.json - JSON schema for configuration validation
  • tests/ - Unit and integration tests
  • examples/ - Usage examples

Skill Manifest

The clawdbot section in package.json defines skill metadata:

json
{
  "clawdbot": {
    "type": "skill",
    "category": "productivity",
    "permissions": [
      "network:https",
      "fs:read:~/Documents"
    ],
    "dependencies": {
      "skills": ["@clawdbot/core-tools"],
      "services": ["anthropic"]
    },
    "config": {
      "schema": "./config.schema.json",
      "required": ["apiKey"]
    }
  }
}

Key Properties

type - Always "skill" for skill packages

category - Helps with discovery:

  • productivity
  • communication
  • data
  • creative
  • dev-tools
  • home-automation
  • entertainment

permissions - Array of permission requests:

  • network:http / network:https - HTTP requests
  • fs:read:<path> - File system read access
  • fs:write:<path> - File system write access
  • exec:<command> - Execute system commands
  • clipboard - Access clipboard
  • camera - Access camera
  • location - Access location data

dependencies - Other skills or services required

config - Configuration schema and requirements

Implementing Commands

Commands are the primary way users interact with your skill:

javascript
commands: {
  'search': async (args, context) => {
    const { query, limit = 10 } = args;
    
    // Validate arguments
    if (!query) {
      throw new Error('Query is required');
    }
    
    // Do the work
    const results = await searchAPI(query, limit);
    
    // Return structured response
    return {
      success: true,
      data: results,
      message: `Found ${results.length} results`
    };
  }
}

Command Arguments

Arguments come from the user's natural language input, parsed by the agent:

javascript
// User says: "search for cats with limit 5"
// Your command receives:
{
  query: "cats",
  limit: 5
}

Context Object

Every command receives a context object with:

javascript
{
  agent: {
    id: 'agent-123',
    name: 'MyBot',
    model: 'claude-sonnet-4'
  },
  user: {
    id: 'user-456', 
    preferences: {...}
  },
  session: {
    id: 'session-789',
    history: [...]
  },
  skills: {
    get: (name) => {...},  // Access other skills
    call: (name, command, args) => {...}  // Call other skills
  },
  config: {...},  // Your skill's configuration
  storage: {  // Persistent storage
    get: (key) => {...},
    set: (key, value) => {...},
    delete: (key) => {...}
  }
}

License Validation

Integrate Clawget licensing to monetize your skill:

javascript
const ClawgetLicense = require('@clawget/license');

module.exports = {
  async init(context) {
    const license = new ClawgetLicense({
      skillId: 'my-awesome-skill',
      apiKey: context.config.clawgetApiKey
    });
    
    // Validate license on startup
    const valid = await license.validate();
    if (!valid.success) {
      throw new Error(`License invalid: ${valid.error}`);
    }
    
    // Store for later checks
    context.license = license;
  },
  
  commands: {
    'premium-feature': async (args, context) => {
      // Check license before premium features
      const check = await context.license.check('premium');
      if (!check.allowed) {
        return {
          success: false,
          error: 'This feature requires a premium license',
          upgradeUrl: 'https://clawget.io/skills/my-awesome-skill'
        };
      }
      
      // Feature code here
    }
  }
};

License Tiers

Implement different functionality based on license tier:

javascript
const features = {
  free: ['basic-search'],
  personal: ['basic-search', 'advanced-search'],
  team: ['basic-search', 'advanced-search', 'bulk-export'],
  enterprise: ['basic-search', 'advanced-search', 'bulk-export', 'custom-api']
};

const tierFeatures = features[license.tier] || features.free;

if (!tierFeatures.includes(command)) {
  return { 
    error: `Upgrade to ${license.requiredTier(command)} for this feature` 
  };
}

Configuration

Allow users to configure your skill:

javascript
// config.schema.json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "apiKey": {
      "type": "string",
      "description": "API key for the service",
      "minLength": 20
    },
    "endpoint": {
      "type": "string", 
      "format": "uri",
      "default": "https://api.service.com"
    },
    "maxResults": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "default": 10
    }
  },
  "required": ["apiKey"]
}

Users configure via ~/.clawdbot/skills/my-awesome-skill/config.json or environment variables.

Testing

Unit Tests

javascript
// test/commands.test.js
const skill = require('../index');

describe('search command', () => {
  it('should search and return results', async () => {
    const context = {
      config: { apiKey: 'test-key' },
      storage: new Map()
    };
    
    await skill.init(context);
    
    const result = await skill.commands.search(
      { query: 'test', limit: 5 },
      context
    );
    
    expect(result.success).toBe(true);
    expect(result.data.length).toBeLessThanOrEqual(5);
  });
});

Integration Tests

Test your skill in a real Clawdbot environment:

bash
clawdbot test-skill ./my-skill --verbose

Publishing to npm

Prepare for Publishing

Before publishing:

bash
# Run tests
npm test

# Check package
npm pack --dry-run

# Verify files included
tar -tzf *.tgz

Publish

bash
# Login to npm (one-time)
npm login

# Publish package
npm publish --access public

# Or for scoped packages
npm publish --access public

Versioning

Follow semantic versioning:

  • 1.0.0 - Major version (breaking changes)
  • 1.1.0 - Minor version (new features, backward compatible)
  • 1.0.1 - Patch version (bug fixes)

Update version before each publish:

bash
npm version patch  # 1.0.0 -> 1.0.1
npm version minor  # 1.0.1 -> 1.1.0
npm version major  # 1.1.0 -> 2.0.0

Listing on Clawget

After publishing to npm, create a marketplace listing:

bash
clawget create-listing \
  --package @yourname/my-awesome-skill \
  --category productivity \
  --price-personal 10 \
  --price-team 50

Or use the web interface at clawget.io/creator/new-listing.

Listing Requirements

To list on Clawget marketplace:

  • Published to npm registry
  • License validation integrated
  • Documentation complete (README + examples)
  • Passing automated security scan
  • Screenshots or demo video
  • Support contact provided

Best Practices

Code Quality

  • Use TypeScript for better developer experience
  • Include comprehensive error handling
  • Validate all inputs
  • Write unit tests
  • Document all functions and commands

User Experience

  • Provide clear error messages
  • Return structured, consistent responses
  • Support natural language arguments
  • Include usage examples in README
  • Offer sensible defaults

Security

  • Never store sensitive data in code
  • Use environment variables or secure config
  • Validate all external inputs
  • Request minimum necessary permissions
  • Audit dependencies regularly

Performance

  • Cache API responses when appropriate
  • Implement rate limiting for external calls
  • Use async/await properly
  • Clean up resources in cleanup hooks

Example Skills

Check out these example skills for reference:

Support & Resources

Next Steps

Start building and publishing your skills today! 🚀