Category: Skills & Extensions

Extend OpenClaw with Skills, plugins, and extensions from the community.

  • OpenClaw Community Skills Review: Which ClawHub Skills Are Actually Useful?

    If you’re diving into the OpenClaw ecosystem and wondering which skills from ClawHub are worth your time and server resources, you’re not alone. The ClawHub marketplace is brimming with community-contributed skills, but not all are created equal. Some are incredibly niche, others are resource hogs, and a few are just plain broken or poorly maintained. This guide cuts through the noise to highlight the skills that consistently prove useful in real-world OpenClaw deployments, focusing on practical applications and performance considerations.

    Essential Utility Skills

    Let’s start with the workhorses – skills that provide fundamental capabilities often overlooked but crucial for robust OpenClaw operations. The clawhub/system-monitor skill is a prime example. While OpenClaw itself provides some basic logging, this skill integrates with common Linux utilities to give you a clearer picture of your system’s health. Specifically, it leverages htop and df -h, making their output accessible directly through OpenClaw’s API. To enable it, you’ll need to install htop if it’s not already present on your system:

    sudo apt update && sudo apt install htop -y

    Then, in your ~/.openclaw/config.json, add the skill definition under the skills array:

    {
      "api_key": "your_openclaw_api_key",
      "base_url": "http://localhost:8000",
      "skills": [
        {
          "name": "system-monitor",
          "path": "clawhub/system-monitor"
        }
      ],
      "model": "claude-haiku-4-5"
    }

    The non-obvious insight here is that while the default OpenClaw dashboard gives you CPU/RAM usage, system-monitor provides historical context and disk space utilization, which is invaluable for diagnosing issues like logs filling up your root partition or a runaway process consuming all I/O. For instance, if your OpenClaw instance suddenly becomes unresponsive, a quick check with system-monitor.get_system_status() via the API will immediately tell you if you’re out of disk space or if a background task is thrashing your CPU.

    Another often-underestimated utility is clawhub/file-manager. While security-conscious users might be wary of giving an AI direct file system access, for local development or controlled environments, it’s a lifesaver. It allows OpenClaw to read, write, and delete files within a specified sandbox directory. This is particularly useful for tasks like processing data files, generating reports, or managing configuration for other applications OpenClaw might be orchestrating. Configure it like this:

    {
      "api_key": "your_openclaw_api_key",
      "base_url": "http://localhost:8000",
      "skills": [
        {
          "name": "file-manager",
          "path": "clawhub/file-manager",
          "config": {
            "base_directory": "/var/openclaw/data"
          }
        }
      ],
      "model": "claude-haiku-4-5"
    }

    Crucially, base_directory is not optional. If you omit it, the skill will fail to load with a permissions error, or worse, default to a less secure location. Always explicitly define a dedicated directory for OpenClaw’s file operations. This skill makes it trivial for OpenClaw to, for example, read a CSV, process its contents with a custom Python script (invoked via clawhub/python-executor), and then write the results to a new file, all without manual intervention.

    Practical Integration Skills

    OpenClaw truly shines when it can interact with external services. The clawhub/http-requester skill is absolutely fundamental for this. It allows OpenClaw to make arbitrary HTTP GET, POST, PUT, and DELETE requests. This means you can integrate with virtually any RESTful API – from sending notifications to a Slack channel to triggering webhooks on other services. While it might seem obvious, many users initially try to embed API calls directly into their Python executor scripts, which is less efficient and harder for OpenClaw to reason about. The dedicated skill provides a structured way for OpenClaw to understand and manage these interactions.

    {
      "api_key": "your_openclaw_api_key",
      "base_url": "http://localhost:8000",
      "skills": [
        {
          "name": "http-requester",
          "path": "clawhub/http-requester"
        }
      ],
      "model": "claude-haiku-4-5"
    }

    A common mistake is forgetting to handle API keys or authentication headers when using http-requester. While the skill itself doesn’t manage secrets, you can either hardcode them (not recommended for production) or have OpenClaw retrieve them from environment variables or a secure vault skill (if you implement one). For instance, to send a Slack message, your OpenClaw prompt might involve calling http-requester.post() with the appropriate Slack webhook URL and JSON payload. The non-obvious insight: OpenClaw’s internal reasoning engine often constructs more robust and error-resistant API calls when it has a dedicated, well-defined tool like http-requester rather than parsing an arbitrary Python script to find HTTP calls.

    For more specific integrations, clawhub/github-manager is excellent if your OpenClaw instance is involved in code management or CI/CD pipelines. It allows OpenClaw to create issues, pull requests, comment on PRs, and even fetch repository contents. This is particularly useful for automated bug reporting or for an AI assistant to help developers with common GitHub tasks. However, this skill requires careful configuration of GitHub tokens:

    {
      "api_key": "your_openclaw_api_key",
      "base_url": "http://localhost:8000",
      "skills": [
        {
          "name": "github-manager",
          "path": "clawhub/github-manager",
          "config": {
            "github_token": "ghp_YOUR_PERSONAL_ACCESS_TOKEN",
            "owner": "your_github_username",
            "repo": "your_repository_name"
          }
        }
      ],
      "model": "claude-haiku-4-5"
    }

    The token needs to have the correct scopes (e.g., repo for full access, or more granular scopes for specific actions). Failing to set these will lead to mysterious 403 Forbidden errors. This skill is overkill if you just need to clone a repo once; for that, clawhub/shell-executor (with git clone) is simpler. github-manager shines when OpenClaw needs to dynamically interact with GitHub’s API, like creating an issue for every failed test run reported by another system.

    Performance and Resource Considerations

    When selecting ClawHub skills, always be mindful of the resources they consume. Skills like clawhub/python-executor and clawhub/shell-executor are incredibly powerful but can also be resource intensive, especially if the commands or scripts they execute are long-running or memory-hungry. Running complex data processing via python-executor on a VPS with less than 2GB RAM can quickly lead to out-of-memory errors and OpenClaw crashes, especially if your OpenClaw model itself is also memory-intensive. For such tasks, consider offloading to a dedicated worker or using an external system that OpenClaw triggers via http-requester.

    Another point of consideration is the model you pair with these skills. While the documentation might suggest larger models for complex reasoning, for 90% of skill-based tasks, a smaller, faster model like claude-haiku-4-5 is often sufficient and significantly cheaper. OpenClaw’s tool-use capabilities are robust enough that even simpler models can effectively call and parse skill outputs, reserving larger models for more open-ended, creative tasks that don’t rely heavily on specific skill invocations.

    Finally, always test new skills in a staging environment. Some community skills might have unoptimized code or dependencies that conflict with your existing OpenClaw setup. Monitor your VPS’s CPU, RAM, and disk I/O when introducing new skills to catch performance regressions early.

    To start exploring these useful skills, your next concrete step is to add the clawhub/system-monitor skill to your ~/.openclaw/config.json file, along with the htop installation, and restart OpenClaw.

    Want to automate WordPress with OpenClaw? See our guide to setting up OpenClaw skills for WordPress automation →

  • How to Test OpenClaw Skills Before Deploying to Production

    If you’re building an OpenClaw agent and want to thoroughly test its skills before it starts interacting with real users or production systems, you’ve likely hit the wall of “how do I simulate complex scenarios without breaking things or incurring huge API costs?” The standard openclaw test command is great for unit-level checks, but it falls short when you need to orchestrate multi-step interactions, test failure recovery, or evaluate performance under load. This guide will walk you through a practical, cost-effective approach to creating a robust testing environment for your OpenClaw agents, focusing on a local, containerized setup that mirrors production closely enough to be reliable.

    Affiliate Disclosure: As an Amazon Associate, we earn from qualifying purchases. This means we may earn a small commission when you click our links and make a purchase on Amazon. This comes at no extra cost to you and helps support our site.

    Setting Up a Local Testing Environment with Docker Compose

    The core of our testing strategy is to create a isolated, repeatable environment. Docker Compose is your best friend here. It allows you to define and run multi-container Docker applications, which is perfect for simulating external services your OpenClaw agent might interact with. We’re going to set up a local OpenClaw instance, a mock API server, and optionally a local database.

    First, create a directory for your testing environment, say openclaw-test-env/. Inside, create a docker-compose.yml file:

    
    version: '3.8'
    services:
      openclaw-agent:
        build:
          context: .
          dockerfile: Dockerfile.agent
        environment:
          OPENCLAW_CONFIG: /app/.openclaw/config.json
          # IMPORTANT: Use a local API key for testing, or mock the API key entirely
          OPENCLAW_API_KEY: "sk-local-test-key"
        volumes:
          - ./agent_data:/app/.openclaw
          - ./agent_code:/app/skills
        ports:
          - "8000:8000" # If your agent exposes an API
        depends_on:
          - mock-api
        command: openclaw run --port 8000 # Or whatever command starts your agent
    
      mock-api:
        build:
          context: .
          dockerfile: Dockerfile.mockapi
        ports:
          - "3000:3000" # Port for your mock API
        environment:
          MOCK_DATA_PATH: /app/mock_data.json
        volumes:
          - ./mock_data.json:/app/mock_data.json
    
      # Optional: A local PostgreSQL database
      postgres:
        image: postgres:15
        environment:
          POSTGRES_DB: testdb
          POSTGRES_USER: testuser
          POSTGRES_PASSWORD: testpassword
        ports:
          - "5432:5432"
        volumes:
          - pgdata:/var/lib/postgresql/data
    
    volumes:
      pgdata:
    

    You’ll need two Dockerfiles: Dockerfile.agent for your OpenClaw agent and Dockerfile.mockapi for a simple mock API server. For Dockerfile.agent, it might look like this:

    
    FROM python:3.10-slim-buster
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    RUN pip install openclaw
    COPY .openclaw/config.json .openclaw/config.json
    COPY skills/ ./skills/
    CMD ["openclaw", "run"]
    

    For Dockerfile.mockapi, you could use a simple Flask or Node.js server. Here’s a Flask example:

    
    FROM python:3.9-slim-buster
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install Flask
    COPY mock_api.py .
    COPY mock_data.json .
    CMD ["python", "mock_api.py"]
    

    And mock_api.py:

    
    from flask import Flask, jsonify, request
    import json
    import os
    
    app = Flask(__name__)
    MOCK_DATA_PATH = os.environ.get('MOCK_DATA_PATH', 'mock_data.json')
    
    @app.route('/api/data', methods=['GET'])
    def get_data():
        with open(MOCK_DATA_PATH, 'r') as f:
            data = json.load(f)
        return jsonify(data)
    
    @app.route('/api/update', methods=['POST'])
    def update_data():
        new_data = request.json
        with open(MOCK_DATA_PATH, 'r+') as f:
            data = json.load(f)
            data.update(new_data)
            f.seek(0)  # Rewind to the beginning
            json.dump(data, f, indent=4)
            f.truncate() # Truncate any remaining old content
        return jsonify({"status": "success", "updated_data": new_data})
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=3000)
    

    The mock_data.json will contain the initial state for your mock API. This setup allows your OpenClaw agent to make requests to http://mock-api:3000 within the Docker network, simulating real external service interactions.

    Crafting Realistic Test Scenarios

    The real power comes from how you define your tests. Forget about simple unit tests. We’re thinking integration and end-to-end. Your OpenClaw agent’s .openclaw/config.json needs to be adapted to point to your local mock services. For example:

    
    {
      "llm_provider": {
        "name": "anthropic",
        "model": "claude-3-haiku-20240307",
        "api_key_env": "OPENCLAW_API_KEY",
        "base_url": "http://localhost:8000/mock-llm-proxy"
      },
      "tools": [
        {
          "name": "fetch_data",
          "type": "api",
          "base_url": "http://mock-api:3000",
          "endpoints": {
            "get_data": "/api/data",
            "update_data": "/api/update"
          }
        },
        {
          "name": "database_tool",
          "type": "database",
          "driver": "postgresql",
          "host": "postgres",
          "port": 5432,
          "database": "testdb",
          "user": "testuser",
          "password_env": "POSTGRES_PASSWORD"
        }
      ]
    }
    

    The non-obvious insight here is to specifically configure your local OpenClaw agent to use a cheaper, faster LLM model for testing. While the production environment might demand claude-3-opus-20240229 for maximum reasoning, for 90% of your skill testing, claude-3-haiku-20240307 or even a local open-source LLM (via an LM Studio or Ollama proxy if you have sufficient local resources) is sufficient and drastically reduces costs and latency during development. OpenClaw is designed to be model-agnostic, so if your skill logic is sound, it should transfer between models.

    For your test scripts, you’ll be interacting with the OpenClaw agent’s API directly. If your agent is set up to expose an HTTP endpoint (e.g., via openclaw run --port 8000), you can use curl or a Python requests library to send prompts and receive responses. This allows you to simulate user interaction.

    Consider a scenario where your agent needs to fetch data, process it, and then update an external system. Your test script would:

    1. Start the Docker Compose environment: docker compose up -d
    2. (Optional) Initialize the mock API’s mock_data.json or the PostgreSQL database with a specific state.
    3. Send a prompt to your OpenClaw agent: requests.post('http://localhost:8000/chat', json={'prompt': 'Please fetch the latest data and summarize it, then update the status to "processed".'})
    4. Poll the OpenClaw agent’s status or wait for a response.
    5. Assert the final state of the mock API (e.g., by making a GET

      Want to automate WordPress with OpenClaw? See our guide to setting up OpenClaw skills for WordPress automation →

  • Migrating From ChatGPT Plugins to OpenClaw: What You Gain and What Changes

    If you’re an agency or a developer who built custom integrations using ChatGPT Plugins and are now looking for a more stable, cost-effective, and extensible solution, migrating to OpenClaw is a logical next step. OpenAI deprecating plugins means your existing integrations are on borrowed time. OpenClaw offers a robust alternative, but the migration isn’t a simple drop-in replacement. You’ll gain significant control and flexibility, but you’ll also need to adapt your mindset from a black-box plugin model to a more open, agent-oriented architecture.

    Affiliate Disclosure: As an Amazon Associate, we earn from qualifying purchases. This means we may earn a small commission when you click our links and make a purchase on Amazon. This comes at no extra cost to you and helps support our site.

    Understanding the Core Architectural Shift

    The biggest change when moving from ChatGPT Plugins to OpenClaw is the shift from a “plugin-as-a-service” model to a “local agent orchestrator.” ChatGPT Plugins handled the entire lifecycle – discovery, execution, and response parsing – entirely within OpenAI’s infrastructure. You merely registered your API schema and let OpenAI manage the rest. OpenClaw, on the other hand, runs locally (or on your own server) and acts as an orchestration layer for your tools and models. This means you gain direct control over model selection, tool definition, and how your agent interacts with external services.

    For example, a ChatGPT Plugin might have had a manifest like this:

    {
      "schema_version": "v1",
      "name_for_model": "weather_plugin",
      "name_for_human": "Weather Plugin",
      "description_for_model": "Provides real-time weather information.",
      "auth": {
        "type": "none"
      },
      "api": {
        "type": "openapi",
        "url": "https://api.myweatherapp.com/.well-known/openapi.yaml"
      },
      "logo_url": "https://example.com/logo.png",
      "contact_email": "support@example.com",
      "legal_info_url": "https://example.com/legal"
    }
    

    In OpenClaw, your “tools” (the equivalent of plugin functionalities) are defined directly in Python and registered with your agent. You’re no longer pointing to an external OpenAPI spec that OpenAI consumes. Instead, you’re explicitly defining Python functions that OpenClaw’s agent can call. This gives you granular control over input validation, error handling, and even pre/post-processing logic right within your OpenClaw setup.

    Defining Tools in OpenClaw

    Let’s say your ChatGPT Plugin provided a `get_current_weather` function. In OpenClaw, you’d define this as a Python function and expose it to your agent. Here’s a basic example of how you’d define a tool:

    # tools.py
    import requests
    from openclaw.tools import tool
    
    @tool
    def get_current_weather(location: str) -> str:
        """
        Get the current weather in a given location.
        Args:
            location: The city and state, e.g. San Francisco, CA
        """
        try:
            api_key = "YOUR_WEATHER_API_KEY" # Replace with your actual key
            url = f"http://api.openweathermap.org/data/2.5/weather?q={location}&appid={api_key}&units=metric"
            response = requests.get(url)
            response.raise_for_status()
            data = response.json()
            temp = data['main']['temp']
            description = data['weather'][0]['description']
            return f"The current temperature in {location} is {temp}°C with {description}."
        except requests.exceptions.RequestException as e:
            return f"Error fetching weather for {location}: {e}"
        except KeyError:
            return f"Could not parse weather data for {location}. Is the location valid?"
    
    # In your agent configuration:
    # from tools import get_current_weather
    #
    # agent = OpenClawAgent(
    #     model="claude-haiku-4-5",
    #     tools=[get_current_weather],
    #     # ... other config
    # )
    

    Notice how `location: str` is explicitly typed. OpenClaw leverages type hints to automatically generate schema for the LLM, much like OpenAPI. The docstring provides the `description_for_model` that was previously in your plugin manifest, allowing the LLM to understand when to use the tool.

    Cost Optimization and Model Flexibility

    One of the immediate benefits you’ll gain with OpenClaw is the ability to choose your LLM provider and specific model. With ChatGPT Plugins, you were locked into OpenAI’s models. OpenClaw allows you to integrate with various providers like Anthropic, OpenAI, or even local models. This is crucial for cost optimization. While the default inclination might be to use the latest, most powerful model, for many plugin-like tasks (e.g., retrieving data, triggering actions), a smaller, faster, and significantly cheaper model is often sufficient.

    For instance, while your initial setup might default to gpt-4o, for tasks that primarily involve calling a single tool and returning a formatted response, a model like Anthropic’s claude-haiku-4-5 is often 10x cheaper and just as effective. You configure this in your agent’s initialization:

    from openclaw.agents import OpenClawAgent
    
    # ... import your tools
    
    agent = OpenClawAgent(
        model="anthropic/claude-haiku-4-5", # Specify provider/model
        tools=[get_current_weather, ...],
        # ... other configurations
    )
    

    Experimentation is key here. Start with a cost-effective model and only upgrade if you observe a significant drop in performance or tool-calling reliability for your specific use cases. This granular control over the underlying LLM is something you simply couldn’t achieve with the deprecated ChatGPT Plugins.

    Handling State and Custom Logic

    ChatGPT Plugins were largely stateless from the perspective of the plugin itself; the state was managed by the chat interface. With OpenClaw, because you’re running the orchestrator, you have far greater control over state management and custom logic. You can integrate databases, caching layers, or complex business logic directly into your tool functions or the agent’s pre/post-processing hooks. This is particularly powerful for scenarios where plugins felt too constrained or required multiple round-trips to achieve a complex outcome.

    For example, if your old plugin needed to remember user preferences or past interactions, you would have relied on the chat history passed to the plugin. With OpenClaw, you can store this information directly within your application’s state or a database accessible by your tools, leading to more intelligent and context-aware interactions without burdening the LLM with excessive context window usage.

    Limitations and Resource Considerations

    While OpenClaw offers significant advantages, it’s not a magic bullet. The main limitation is that you’re now responsible for running the orchestration layer. This means resource consumption. A basic OpenClaw agent running with a few tools might be light, but if you intend to run multiple agents concurrently or integrate with very large language models locally (which is not the common pattern for tool-calling), you need adequate resources. This setup will typically run smoothly on any VPS with at least 2GB RAM, like a Hetzner CX11. Attempting to run OpenClaw with multiple complex agents on something like a Raspberry Pi will likely result in slow responses and memory exhaustion, especially if you’re trying to integrate with local inference engines.

    Furthermore, while OpenClaw simplifies tool definition, you are now responsible for the full development lifecycle of those tools – from writing the Python code to handling dependencies and deployment. This is a trade-off: more control for more responsibility.

    The transition from ChatGPT Plugins to OpenClaw is a move towards a more robust, controlled, and cost-efficient agent-driven architecture. Embrace the shift from external manifest files to explicit Python tool definitions, and leverage the model flexibility for significant cost savings.

    To get started, define your first OpenClaw tool by creating a tools.py file with a function decorated with @tool and then instantiate your agent with it: agent = OpenClawAgent(model="anthropic/claude-haiku-4-5", tools=[your_tool_function]).

    Want to automate WordPress with OpenClaw? See our guide to setting up OpenClaw skills for WordPress automation →

  • How to Debug OpenClaw Skills That Aren’t Working

    If you’ve been developing custom skills for OpenClaw and find them consistently failing without clear error messages, you’re not alone. The OpenClaw skill execution environment can be a black box, especially when dealing with complex dependencies or subtle runtime issues. This guide will walk you through a systematic debugging process, focusing on practical steps and real-world scenarios that often trip up developers.

    Understanding the OpenClaw Skill Execution Environment

    Before diving into debugging, it’s crucial to understand how OpenClaw executes skills. Each skill runs in an isolated environment, typically a separate process or even a container, depending on your OpenClaw setup. This isolation is great for security and stability but makes direct debugging challenging. OpenClaw captures standard output (stdout) and standard error (stderr) from your skill’s execution and logs them. The primary challenge is that not all errors make it to these logs, especially if the process crashes early or a critical dependency isn’t met.

    A common misconception is that if your skill works locally on your development machine, it will work perfectly within OpenClaw. This often isn’t true due to differences in environment variables, installed packages, user permissions, and working directories. OpenClaw typically executes skills from a specific working directory, often related to ~/.openclaw/skills/<skill_name>/, and might not inherit your shell’s environment path.

    Initial Checks: The Low-Hanging Fruit

    Start with the basics. Many skill failures are due to simple oversight. First, check your skill’s skill.yaml configuration file. Ensure the entrypoint path is correct and executable. For Python skills, this often looks like:

    
    name: my_failing_skill
    description: A skill that never works
    entrypoint: python3 main.py
    runtime: python
    

    Verify that main.py actually exists in the root of your skill’s directory. A common error is placing it in a subdirectory, or misnaming it. Next, ensure all necessary dependencies are declared. For Python skills, this means a requirements.txt file in the skill’s root. OpenClaw will attempt to install these when the skill is loaded or updated.

    
    # requirements.txt
    requests
    numpy
    

    If you’re using a specific Python version, make sure OpenClaw is configured to use it, or explicitly call it in your entrypoint, e.g., python3.9 main.py. The non-obvious insight here is that OpenClaw’s default Python environment might not have all the system-wide packages you expect, even if they’re installed globally on your host. Always declare dependencies in requirements.txt.

    Leveraging OpenClaw’s Internal Logs

    OpenClaw provides internal logging that can be invaluable. The most direct way to access these logs is through the OpenClaw command-line interface (CLI). To see the output of a specific skill failing, use:

    
    openclaw logs --skill my_failing_skill
    

    This command will show you the captured stdout and stderr. Pay close attention to any Python tracebacks, permission denied errors, or “command not found” messages. If you see a Python traceback, the crucial part is often the first few lines indicating the file and line number where the error originated, and the last line describing the exception type.

    For more verbose logging from OpenClaw itself, you can increase the global log level. This is particularly useful if your skill isn’t even getting to the point of execution (e.g., an issue with loading the skill itself). Edit your ~/.openclaw/config.json:

    
    {
      "log_level": "DEBUG",
      "skills_directory": "~/.openclaw/skills"
    }
    

    Restart OpenClaw after making this change. Then, monitor the main OpenClaw logs:

    
    openclaw logs --follow
    

    This will show you much more detail about skill loading, dependency installation attempts, and execution commands. A common non-obvious issue here is a failed dependency installation. If pip install -r requirements.txt fails silently, your skill will still load but crash immediately on import. The DEBUG logs will often reveal the exact pip error.

    Reproducing the Environment Locally

    The most effective way to debug deeply is to replicate OpenClaw’s execution environment as closely as possible outside of OpenClaw. This involves manually running your skill’s entrypoint from the same working directory and with similar environment variables.

    First, navigate to your skill’s directory:

    
    cd ~/.openclaw/skills/my_failing_skill
    

    Next, try to execute your entrypoint directly. If your skill.yaml specifies python3 main.py, run:

    
    python3 main.py arg1 arg2 # replace arg1/arg2 with actual skill inputs if known
    

    If your skill relies on environment variables that OpenClaw might set (e.g., API keys passed via skill configuration), you’ll need to simulate those. For example, if your skill expects OPENCLAW_API_KEY, you would run:

    
    OPENCLAW_API_KEY="sk-..." python3 main.py
    

    This direct execution will often reveal errors that were previously swallowed or difficult to trace through OpenClaw’s logs. The non-obvious insight here is to pay attention to the user running the process. OpenClaw typically runs as the user who started it, but if you’re running it as a systemd service, it might run under a different user with limited permissions. Check the file permissions in your skill directory (ls -l) and ensure the user running OpenClaw has read/execute access.

    For Python skills, consider adding explicit print statements throughout your code, especially at the beginning of functions, and before and after critical operations. These print statements will show up in openclaw logs --skill my_failing_skill and can help pinpoint exactly where the execution flow breaks down.

    Advanced Techniques: Using a Debugger and Test Frameworks

    For very complex skills, direct local execution might not be enough. If your skill is a Python application, you can integrate a debugger. Modify your main.py to include a breakpoint or use a debugger like pdb:

    
    # main.py
    import pdb
    
    def my_skill_function():
        # ... some code ...
        pdb.set_trace() # Execution will pause here
        # ... more code ...
    
    if __name__ == "__main__":
        my_skill_function()
    

    When you run this skill locally (python3 main.py), it will drop into a debugger prompt, allowing you to inspect variables and step through code. This won’t work directly within OpenClaw’s non-interactive environment, but it’s invaluable for isolating the problematic code path locally. The limitation here is that this technique is primarily for local debugging and can’t be used for live debugging within the OpenClaw runtime directly without significant effort to attach a remote debugger.

    Finally, for robust skills, consider implementing unit and integration tests. A comprehensive test suite can catch regressions and ensure your skill functions as expected under various inputs, even before deploying it to OpenClaw. While this is more of a development best practice than a debugging technique, it prevents many issues from reaching the OpenClaw environment in the first place.

    Conclusion and Next Step

    Debugging OpenClaw skills requires a methodical approach, often moving from general checks to detailed environment replication. The key is to systematically narrow down the problem by leveraging OpenClaw’s logging capabilities and then reproducing the failure outside of OpenClaw to use standard debugging tools.

    Your immediate next step is to update your ~/.openclaw/config.json to include "log_level": "DEBUG", restart OpenClaw, and then run openclaw logs --follow while attempting to invoke your failing skill. This will provide the most verbose output directly from OpenClaw, often revealing crucial setup or execution errors.

    Want to automate WordPress with OpenClaw? See our guide to setting up OpenClaw skills for WordPress automation →

  • How to Create a Custom OpenClaw Skill from Scratch

    If you’re looking to extend OpenClaw’s capabilities beyond its built-in commands and the official skill marketplace, creating a custom skill is the way to go. This note will walk you through the process, from defining the skill’s structure to integrating it into your OpenClaw instance. We’ll focus on a practical example: a skill that queries a local weather API, something not directly supported by default.

    Skill Directory Structure and Boilerplate

    OpenClaw skills are essentially Python modules with a specific entry point and metadata. All custom skills should reside in your ~/.openclaw/skills/ directory. If this directory doesn’t exist, create it: mkdir -p ~/.openclaw/skills/. Each skill needs its own subdirectory within this path. Let’s create one for our weather skill: mkdir -p ~/.openclaw/skills/local_weather. Inside this directory, you’ll need at least two files: __init__.py and config.json.

    The config.json file defines the skill’s metadata and how OpenClaw should present it. For our local_weather skill, it would look like this:

    
    {
        "name": "Local Weather",
        "description": "Fetches local weather conditions from a specified API endpoint.",
        "version": "0.1.0",
        "author": "Your Name",
        "icon": "weather-icon.png",
        "commands": [
            {
                "name": "get_current_weather",
                "description": "Retrieves current weather conditions for a given location.",
                "args": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city or geographical area to get weather for."
                        }
                    },
                    "required": ["location"]
                }
            }
        ]
    }
    

    The commands array is crucial here. Each object within it defines a function that OpenClaw’s AI can call. name is the Python function name, description helps the AI understand its purpose, and args defines the input parameters using JSON schema. This schema guides the AI on what arguments to provide. For our weather skill, we only need a location string.

    Next, the __init__.py file contains the actual Python code for your skill. This is where the logic for fetching weather will live. For now, let’s create a minimal version:

    
    import requests
    import os
    
    class LocalWeatherSkill:
        def __init__(self):
            self.api_base_url = os.getenv("LOCAL_WEATHER_API_URL", "http://localhost:8080/weather")
    
        def get_current_weather(self, location: str) -> str:
            try:
                response = requests.get(f"{self.api_base_url}?location={location}")
                response.raise_for_status()  # Raise an exception for HTTP errors
                data = response.json()
                if data and "temperature" in data and "conditions" in data:
                    return f"Current weather in {location}: {data['temperature']}°C, {data['conditions']}."
                else:
                    return f"Could not parse weather data for {location}."
            except requests.exceptions.ConnectionError:
                return f"Error: Could not connect to the local weather API at {self.api_base_url}. Is it running?"
            except requests.exceptions.Timeout:
                return "Error: Local weather API request timed out."
            except requests.exceptions.RequestException as e:
                return f"Error fetching weather: {e}"
            except Exception as e:
                return f"An unexpected error occurred: {e}"
    
    # OpenClaw will instantiate this class
    def get_skill_instance():
        return LocalWeatherSkill()
    

    The get_skill_instance() function at the bottom is OpenClaw’s entry point; it expects to get an instance of your skill class. Notice how we’re using os.getenv for the API URL. This is critical for keeping sensitive information or environment-specific configurations out of the code and managed via environment variables.

    Handling Dependencies

    Our local_weather skill uses the requests library. OpenClaw runs skills in isolated environments, but you still need to manage dependencies. The most straightforward way is to include a requirements.txt file in your skill’s directory. For our skill:

    
    # ~/.openclaw/skills/local_weather/requirements.txt
    requests==2.31.0
    

    When OpenClaw loads your skill for the first time or detects changes, it will attempt to install these dependencies into a virtual environment specific to that skill. This is why it’s important to pin exact versions or ranges; otherwise, you might run into conflicts or unexpected behavior if a dependency updates and breaks your skill. OpenClaw uses pip for this, so standard requirements.txt syntax applies.

    Environment Variables and Configuration

    For skills that interact with external services or require API keys, environment variables are the recommended approach. In our weather example, we defined LOCAL_WEATHER_API_URL. To make this available to OpenClaw and, consequently, to your skill, you’ll need to set it in the environment where OpenClaw runs. If you’re running OpenClaw with systemd, you’d modify your service file. For a Hetzner VPS, this might look like:

    
    # /etc/systemd/system/openclaw.service (example)
    ...
    [Service]
    Environment="LOCAL_WEATHER_API_URL=http://your-local-weather-service:8080/api/v1/weather"
    ExecStart=/usr/local/bin/openclaw serve
    ...
    

    After modifying the service file, remember to run sudo systemctl daemon-reload and sudo systemctl restart openclaw. If you’re running OpenClaw manually, simply export the variable before starting it: export LOCAL_WEATHER_API_URL="http://127.0.0.1:8080/weather" && openclaw serve.

    A non-obvious insight here: while you might be tempted to put configuration directly into the __init__.py or even a skill-specific JSON file, using environment variables via os.getenv() is far more robust. It cleanly separates configuration from code, allows for easy overrides in different deployment environments (e.g., dev vs. prod), and prevents accidental commitment of sensitive data to version control. Furthermore, OpenClaw’s skill loading mechanism doesn’t directly support injecting arbitrary configuration into a skill beyond what’s defined in its config.json, so environment variables are your best bet for runtime parameters.

    Testing and Debugging

    Once your skill is in place, restart OpenClaw. It should automatically detect and load your new skill. You can verify this by checking OpenClaw’s logs. Look for messages indicating skill discovery and loading, typically containing the skill’s name and version. If there are dependency issues, you’ll see errors related to pip install in the logs. If the skill fails to load, OpenClaw will log the traceback from your __init__.py.

    To test the skill, interact with OpenClaw naturally. Ask it: “What’s the weather like in London?” OpenClaw’s AI should recognize that it has a tool (your get_current_weather command) that can answer this query, call it with “London” as the location argument, and then return the result. If it doesn’t, inspect OpenClaw’s thought process in the logs. Often, the AI needs a clearer description in config.json or a more precise command name to correctly map user intent to your skill.

    Limitations: This approach works well for skills that are primarily CPU-bound or make network calls. However, if your skill requires significant computational resources, such as a large language model or a complex computer vision model, running it directly within OpenClaw’s skill environment on a typical VPS (like a Hetzner CX11 or CX21) might struggle. The skill’s Python process inherits the OpenClaw process’s resource limits. For heavy lifting, it’s generally better to have your skill act as a client to a separate, optimized service (e.g., a dedicated GPU instance for inference) and just pass the request to that service, returning its output.

    🤖 Get the OpenClaw Automation Starter Kit ($29) →
    Instant download — no subscription needed

    Want to automate WordPress with OpenClaw? See our guide to setting up OpenClaw skills for WordPress automation →

  • OpenClaw Skills Directory: Best Community Skills Worth Installing

    If you’re running OpenClaw on a Hetzner VPS and are looking to extend its capabilities beyond the core models, you’ve likely browsed the official OpenClaw Skills Directory. The directory is a treasure trove, but not all skills are created equal, especially when it comes to resource usage and practical utility in a typical self-hosted environment. I’ve spent the last few months experimenting with various community contributions, and I want to highlight the ones that genuinely enhance OpenClaw’s functionality without turning your VPS into a molten core, or requiring a PhD in prompt engineering to get them working.

    Affiliate Disclosure: As an Amazon Associate, we earn from qualifying purchases. This means we may earn a small commission when you click our links and make a purchase on Amazon. This comes at no extra cost to you and helps support our site.

    Managing External APIs with the api_proxy Skill

    One of the most powerful, yet often overlooked, skills is api_proxy. Its primary purpose is to act as a secure, authenticated gateway for other skills to interact with external APIs. For instance, if you want your OpenClaw instance to fetch real-time stock prices or weather data, you don’t want to embed API keys directly into multiple skills or expose them in plain text. The api_proxy skill allows you to centralize your API key management and ensures that only authorized OpenClaw skills can make requests. This is crucial for maintaining security and preventing accidental key exposure, which is a common oversight when integrating third-party services.

    To set it up, you’ll first need to install the skill:

    openclaw install api_proxy

    Then, configure your API keys in ~/.openclaw/skills/api_proxy/config.json. A typical configuration for, say, a weather API and a stock market API might look like this:

    {
      "api_keys": {
        "openweather": "YOUR_OPENWEATHER_API_KEY",
        "alphavantage": "YOUR_ALPHAVANTAGE_API_KEY"
      },
      "endpoints": {
        "openweather": "https://api.openweathermap.org/data/2.5/weather",
        "alphavantage_daily": "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY"
      }
    }
    

    Now, any other skill can request data through api_proxy by specifying the endpoint name and passing parameters. This centralizes sensitive credentials and simplifies the development of other skills that rely on external data. The non-obvious insight here is that while the documentation might suggest this for complex scenarios, it’s immensely useful even for simple integrations. It abstracts away the API key management from the individual skill logic, making your setup cleaner and more robust against configuration errors or security lapses. This skill is relatively lightweight and doesn’t demand significant RAM, making it perfect for most VPS setups.

    Enhanced Search with serp_google

    While OpenClaw has basic web browsing capabilities, the serp_google skill takes it to another level by integrating with the Google Custom Search API. This provides a more structured and often more relevant search experience compared to simple HTTP fetching. It’s particularly useful when OpenClaw needs to access up-to-date information that isn’t present in its training data or local knowledge base.

    Installation is straightforward:

    openclaw install serp_google

    You’ll need a Google API key and a Custom Search Engine ID. The setup process for these can be a bit tedious on Google’s developer console, but it’s a one-time effort. Configure these in ~/.openclaw/skills/serp_google/config.json:

    {
      "api_key": "YOUR_GOOGLE_API_KEY",
      "cx": "YOUR_CUSTOM_SEARCH_ENGINE_ID"
    }
    

    The key insight here is to configure your Custom Search Engine to target specific, high-quality websites relevant to your primary use case. For example, if you use OpenClaw for coding assistance, configure the CSE to search documentation sites like Stack Overflow, MDN, or official language docs. This dramatically improves the relevance of search results and reduces the “noise” from generic web searches. While the default model might struggle to parse vast amounts of raw HTML, serp_google provides structured JSON results, which are much easier for OpenClaw to process. This skill will consume a bit more network bandwidth due to API calls, but the processing overhead on the VPS itself is minimal.

    Simplifying File Management with file_system_explorer

    For those using OpenClaw for local development or system administration tasks on the same machine, the file_system_explorer skill is invaluable. It provides a controlled interface for OpenClaw to list directories, read file contents, and even perform basic file operations. This is incredibly useful for tasks like debugging configuration files, reviewing log files, or even scaffolding new project structures based on your prompts.

    Install it like any other skill:

    openclaw install file_system_explorer

    The critical configuration for this skill is defining the allowed paths. For security reasons, you absolutely do not want OpenClaw to have unfettered access to your entire filesystem. Configure ~/.openclaw/skills/file_system_explorer/config.json with specific allow-lists:

    {
      "allowed_paths": [
        "/home/youruser/projects",
        "/var/log/openclaw",
        "/tmp/openclaw_data"
      ],
      "read_only_paths": [
        "/etc/openclaw"
      ],
      "max_file_size_bytes": 1048576,
      "max_dir_depth": 5
    }
    

    The non-obvious insight: always start with a very restrictive allowed_paths list and expand it incrementally as needed. Using read_only_paths for sensitive configuration directories (like /etc/openclaw) ensures OpenClaw can inspect but not modify critical system files. This skill is generally light on resources as file operations are handled by the underlying OS, but be mindful of reading extremely large files, which could consume significant memory depending on your OpenClaw model’s context window. This skill only works effectively if your VPS has at least 2GB of RAM, as smaller instances might struggle if OpenClaw attempts to load large file contents into its context.

    The OpenClaw Skills Directory is a powerful resource, but careful selection and configuration are key to getting the most out of your self-hosted instance without over-provisioning resources. These three skills provide a solid foundation for enhancing your OpenClaw’s capabilities in security, information retrieval, and local system interaction.

    Your immediate next step should be to install the api_proxy skill and configure an API key for a service you frequently use by running: openclaw install api_proxy && nano ~/.openclaw/skills/api_proxy/config.json.

    Frequently Asked Questions

    What is the OpenClaw Skills Directory?

    It’s a curated list of top-rated, community-developed skills for the OpenClaw platform. It helps users discover valuable additions to enhance their OpenClaw experience, focusing on quality, utility, and popular features.

    How are skills deemed ‘best’ or ‘worth installing’ in this directory?

    Skills are typically highlighted based on community ratings, user popularity, unique functionality, reliability, and overall positive impact on the OpenClaw experience. The directory aims to showcase high-quality, valuable additions.

    How do I install skills found in the OpenClaw Skills Directory?

    The article likely provides detailed instructions. Generally, you’d browse the directory, select a skill, and follow the specific installation steps for OpenClaw, often involving a simple command-line interface or a built-in skill manager.

    🤖 Get the OpenClaw Automation Starter Kit (9) →
    Instant download — no subscription needed

    Want to automate WordPress with OpenClaw? See our guide to setting up OpenClaw skills for WordPress automation →

  • How to Set Up OpenClaw Skills for Automating WordPress Sites

    If you’re running OpenClaw and want to automate common tasks on your WordPress sites, leveraging OpenClaw’s skills system is a game-changer. Forget about manually logging into each site’s admin panel for routine updates or content tweaks. This guide will walk you through setting up OpenClaw skills to interact with WordPress, specifically focusing on creating a skill to manage posts and another to update plugins.

    Affiliate Disclosure: As an Amazon Associate, we earn from qualifying purchases. This means we may earn a small commission when you click our links and make a purchase on Amazon. This comes at no extra cost to you and helps support our site.

    Understanding OpenClaw Skills and WordPress API

    OpenClaw skills are essentially Python functions that the OpenClaw agent can call based on its understanding of a user’s request. For these skills to interact with WordPress, they need a way to communicate with your WordPress site programmatically. The most robust method is using the WordPress REST API. By default, WordPress exposes a comprehensive REST API that allows for reading and writing data, including posts, pages, users, and more.

    Before you dive into skill creation, ensure your WordPress site’s REST API is accessible. While it’s enabled by default, some security plugins might restrict access. You’ll also need authentication. For simple automation, application passwords are the most straightforward and secure method. Navigate to your WordPress admin panel, go to Users > Your Profile, scroll down to “Application Passwords,” and create a new one. This will give you a username and a unique password that OpenClaw can use to authenticate.

    Setting Up the OpenClaw Environment

    First, ensure your OpenClaw environment is ready. You’ll need to create a dedicated directory for your custom skills. A common practice is to have a skills/ directory within your OpenClaw configuration directory. For example, if your OpenClaw config is at ~/.openclaw/, you might create ~/.openclaw/skills/. Inside this directory, each Python file will represent a skill module.

    You’ll also need a Python library to interact with the WordPress REST API. The python-wordpress-xmlrpc library is a good choice, despite its name, it supports the REST API. Install it in OpenClaw’s virtual environment or your system’s Python environment if OpenClaw is using it directly:

    pip install python-wordpress-xmlrpc requests_oauthlib

    Make sure this package is available to the Python interpreter that OpenClaw uses to execute skills. If you’re running OpenClaw in a Docker container, you’ll need to rebuild your image or exec into the container and install it there. For a typical VPS setup, installing it globally or within OpenClaw’s venv should suffice.

    Skill 1: Creating a New WordPress Post

    Let’s create a skill to publish a new post. Create a file named ~/.openclaw/skills/wordpress_posts.py with the following content:

    
    import requests
    import json
    import os
    
    # It's better to get these from environment variables or a secure config
    # For simplicity in this example, we'll use direct variables
    WORDPRESS_URL = os.environ.get("WORDPRESS_URL", "https://your-wordpress-site.com")
    WORDPRESS_USERNAME = os.environ.get("WORDPRESS_USERNAME", "your_app_username")
    WORDPRESS_PASSWORD = os.environ.get("WORDPRESS_PASSWORD", "your_app_password")
    
    def create_wordpress_post(title: str, content: str, status: str = "publish") -> str:
        """
        Creates a new post on a WordPress site.
    
        Args:
            title (str): The title of the new post.
            content (str): The HTML content of the new post.
            status (str): The status of the post (e.g., "publish", "draft", "pending").
    
        Returns:
            str: A message indicating success or failure, including the post URL if successful.
        """
        if not all([WORDPRESS_URL, WORDPRESS_USERNAME, WORDPRESS_PASSWORD]):
            return "Error: WordPress credentials or URL not configured."
    
        api_url = f"{WORDPRESS_URL}/wp-json/wp/v2/posts"
        headers = {
            "Content-Type": "application/json"
        }
        auth = (WORDPRESS_USERNAME, WORDPRESS_PASSWORD)
    
        data = {
            "title": title,
            "content": content,
            "status": status,
        }
    
        try:
            response = requests.post(api_url, headers=headers, auth=auth, data=json.dumps(data), timeout=10)
            response.raise_for_status()  # Raise HTTPError for bad responses (4xx or 5xx)
    
            post_data = response.json()
            post_link = post_data.get("link")
            return f"Successfully created WordPress post: '{title}'. URL: {post_link}"
        except requests.exceptions.HTTPError as e:
            return f"HTTP error creating WordPress post: {e.response.status_code} - {e.response.text}"
        except requests.exceptions.RequestException as e:
            return f"Network error creating WordPress post: {e}"
        except Exception as e:
            return f"An unexpected error occurred: {e}"
    
    

    A crucial non-obvious insight here: While the python-wordpress-xmlrpc library is powerful, for simple REST API calls like creating a post, directly using the requests library gives you more fine-grained control and often results in cleaner, more readable code. It also avoids potential dependency conflicts that might arise from larger, more opinionated libraries. Always prioritize direct REST calls for straightforward interactions. Make sure to set your WORDPRESS_URL, WORDPRESS_USERNAME, and WORDPRESS_PASSWORD as environment variables in the OpenClaw process or directly in the skill file for testing. For production, environment variables are highly recommended for security.

    Skill 2: Updating WordPress Plugins

    Updating plugins is another common task. The WordPress REST API doesn’t have a direct endpoint for “update all plugins” but you can update individual plugins. For this example, let’s create a skill to activate or deactivate a plugin, as updating often involves these states.

    Add the following function to your ~/.openclaw/skills/wordpress_plugins.py file:

    
    import requests
    import json
    import os
    
    WORDPRESS_URL = os.environ.get("WORDPRESS_URL", "https://your-wordpress-site.com")
    WORDPRESS_USERNAME = os.environ.get("WORDPRESS_USERNAME", "your_app_username")
    WORDPRESS_PASSWORD = os.environ.get("WORDPRESS_PASSWORD", "your_app_password")
    
    def manage_wordpress_plugin(plugin_slug: str, action: str) -> str:
        """
        Activates or deactivates a specific WordPress plugin.
    
        Args:
            plugin_slug (str): The slug of the plugin (e.g., 'akismet/akismet.php').
            action (str): The desired action: 'activate' or 'deactivate'.
    
        Returns:
            str: A message indicating success or failure.
        """
        if not all([WORDPRESS_URL, WORDPRESS_USERNAME, WORDPRESS_PASSWORD]):
            return "Error: WordPress credentials or URL not configured."
        if action not in ["activate", "deactivate"]:
            return "Error: Action must be 'activate' or 'deactivate'."
    
        api_url = f"{WORDPRESS_URL}/wp-json/wp/v2/plugins/{plugin_slug}"
        headers = {
            "Content-Type": "application/json"
        }
        auth = (WORDPRESS_USERNAME, WORDPRESS_PASSWORD)
    
        data = {
            "status": "active" if action == "activate" else "inactive"
        }
    
        try:
            response = requests.post(api_url, headers=headers, auth=auth, data=json.dumps(data), timeout=10)
            response.raise_for_status()
    
            plugin_data = response.json()
            current_status = "active" if plugin_data.get("status") == "active" else "inactive"
            return f"Successfully set plugin '{plugin_slug}' to '{current_status}' status."
        except requests.exceptions.HTTPError as e:
            return f"HTTP error managing WordPress plugin: {e.response.status_code} - {e.response.text}"
        except requests.exceptions.RequestException as e:
            return f"Network error managing WordPress plugin: {e}"
        except Exception as e:
            return f"An unexpected error occurred: {e}"
    
    

    The trick here is finding the correct plugin_slug. This isn’t just the plugin folder name; it’s typically the folder name followed by the main plugin file (e.g., akismet/

    Frequently Asked Questions

    What is OpenClaw and how do its 'skills' work for WordPress?

    OpenClaw is an automation platform where 'skills' are predefined routines or actions. For WordPress, these skills allow you to automate various tasks, from content publishing to user management, by interacting directly with your site's functionalities through custom-built automation sequences.

    What kind of WordPress tasks can OpenClaw skills automate?

    OpenClaw skills can automate a wide range of WordPress tasks, including scheduling posts, managing user roles, updating plugins, synchronizing data, sending notifications, and performing routine maintenance. This helps streamline operations and improve efficiency for site administrators.

    What's involved in the initial setup of OpenClaw skills for WordPress?

    Setting up involves connecting your WordPress site to the OpenClaw platform, usually via a dedicated plugin or API integration. You then define or import specific automation 'skills,' configuring them with the necessary credentials and parameters to execute tasks on your WordPress site effectively.

    🤖 Get the OpenClaw Automation Starter Kit (9) →
    Instant download — no subscription needed
  • OpenClaw’s Plugin Architecture: Extending Capabilities with Different Models

    If you’re running OpenClaw and looking to integrate more than just the default models, you’ve hit on one of its most powerful, yet sometimes undersold, features: the plugin architecture. OpenClaw isn’t just a monolithic application; it’s designed with extensibility in mind, particularly when it comes to Large Language Models (LLMs). This means you can hook into various providers, from local Ollama instances to commercial APIs like Anthropic, OpenAI, or even custom endpoints, without modifying the core OpenClaw codebase. The real power here is in creating a unified interface for diverse LLM capabilities.

    Understanding the Plugin Directory

    The first place to look when you want to extend OpenClaw’s model support is the plugins/ directory within your OpenClaw installation. By default, you’ll find a few examples, typically for OpenAI or Anthropic, and sometimes a placeholder for a local model. Each subdirectory within plugins/ represents a distinct plugin. For instance, you might see plugins/anthropic/ and plugins/openai/. Inside each of these, you’ll find the Python code that defines how OpenClaw communicates with that specific LLM provider. This separation is crucial for maintaining a clean and modular system.

    Let’s say you want to add support for a new model from an existing provider, like a newer Anthropic model. You don’t necessarily need to create a whole new directory if the existing anthropic plugin already handles the API specifics. Instead, you’ll primarily be interacting with your OpenClaw configuration file to tell it which model to use. If you’re adding an entirely new provider, however, you’d create a new directory, say plugins/mistral/, and write the necessary Python code to handle the Mistral API calls.

    Configuring Models via config.json

    The true magic happens in your .openclaw/config.json file. This is where you declare which models OpenClaw should be aware of and how to access them. Each model entry maps a user-friendly name to a specific plugin and its configuration. Here’s a typical structure:

    
    {
      "models": {
        "default": "claude-haiku",
        "claude-haiku": {
          "plugin": "anthropic",
          "model_name": "claude-3-haiku-20240307",
          "api_key_env": "ANTHROPIC_API_KEY",
          "max_tokens": 4096,
          "temperature": 0.7
        },
        "gpt-4o": {
          "plugin": "openai",
          "model_name": "gpt-4o",
          "api_key_env": "OPENAI_API_KEY",
          "max_tokens": 4096,
          "temperature": 0.6
        },
        "local-llama3": {
          "plugin": "ollama",
          "model_name": "llama3",
          "api_base": "http://localhost:11434/api",
          "max_tokens": 2048,
          "temperature": 0.8
        }
      },
      "plugins": {
        "anthropic": {
          "module": "plugins.anthropic.anthropic_plugin"
        },
        "openai": {
          "module": "plugins.openai.openai_plugin"
        },
        "ollama": {
          "module": "plugins.ollama.ollama_plugin"
        }
      }
    }
    

    In this snippet:

    • The "models" section defines custom model aliases and their parameters.
      • "default": "claude-haiku": This sets the default model OpenClaw will use if you don’t specify one. This is a huge quality-of-life improvement; you don’t always need GPT-4o for simple tasks.
      • "claude-haiku": This is a user-defined alias. It maps to the anthropic plugin, specifies the exact Anthropic model name (claude-3-haiku-20240307), and tells OpenClaw to look for the API key in the ANTHROPIC_API_KEY environment variable.
      • "local-llama3": This demonstrates integrating a local Ollama instance. Notice the "plugin": "ollama" and "api_base" pointing to the local Ollama server.
    • The "plugins" section tells OpenClaw which Python module to load for each plugin type. "module": "plugins.anthropic.anthropic_plugin" means it will look for a file named anthropic_plugin.py inside the plugins/anthropic/ directory.

    The non-obvious insight here is that while the official Anthropic documentation might push for their more powerful (and expensive) models like Opus, claude-3-haiku-20240307, configured as claude-haiku in your config, is often 10x cheaper and perfectly sufficient for 90% of OpenClaw’s typical use cases, like summarization, basic code generation, or content rephrasing. Don’t always go for the biggest gun if a smaller, faster, cheaper one does the job.

    Creating a New Plugin

    Let’s say you want to integrate a model from a provider not natively supported, or a custom local inference server. You’d start by creating a new directory in plugins/, e.g., plugins/my_custom_provider/. Inside, you’d create a Python file, say my_custom_plugin.py. This file needs to define a class that implements the necessary interface expected by OpenClaw. While the exact interface can vary slightly with OpenClaw versions, the core requirement is usually a method for generating responses and handling model configuration.

    A simplified structure for plugins/my_custom_provider/my_custom_plugin.py might look like this:

    
    import os
    import requests
    import json
    
    class MyCustomPlugin:
        def __init__(self, config):
            self.model_name = config.get("model_name")
            self.api_base = config.get("api_base", "http://localhost:8080/v1")
            self.api_key = os.getenv(config.get("api_key_env"))
            self.max_tokens = config.get("max_tokens", 512)
            self.temperature = config.get("temperature", 0.7)
            # Any other provider-specific initialization
    
        def generate_response(self, messages, stream=False):
            headers = {
                "Content-Type": "application/json",
                "Authorization": f"Bearer {self.api_key}" # If your API uses this
            }
            payload = {
                "model": self.model_name,
                "messages": messages,
                "max_tokens": self.max_tokens,
                "temperature": self.temperature,
                "stream": stream
            }
            
            try:
                response = requests.post(f"{self.api_base}/chat/completions", 
                                         headers=headers, 
                                         json=payload, 
                                         stream=stream)
                response.raise_for_status()
    
                if stream:
                    for line in response.iter_lines():
                        if line:
                            yield json.loads(line.decode('utf-8').lstrip('data: ')) # Adjust based on stream format
                else:
                    return response.json()['choices'][0]['message']['content'] # Adjust based on response format
            except requests.exceptions.RequestException as e:
                print(f"Error calling custom provider: {e}")
                return None # Or raise a specific exception
    

    Then, you’d update your .openclaw/config.json:


    {
    "models": {
    "my-model": {
    "plugin": "my_custom_provider",
    "model_name": "custom-llama-7b",
    "api_base": "http://my-inference-server:8080/v1",
    "api_key_env": "MY_CUSTOM_API_KEY",
    "max_tokens": 1024
    }
    },
    "plugins": {
    "my_custom_provider": {
    "module":

    Frequently Asked Questions

    What is the OpenClaws Plugin Architecture?

    It's a modular system designed to enhance OpenClaws' functionality. It allows developers to integrate new features, tools, or AI models seamlessly, extending the application's core capabilities without altering its main codebase.

    How does the plugin architecture support 'different models'?

    Plugins enable OpenClaws to integrate various computational or AI models, such as machine learning algorithms, data processing units, or specialized analytical tools. This allows users to leverage diverse model types for specific tasks within the OpenClaws ecosystem.

    What are the key benefits of OpenClaws' plugin architecture?

    Key benefits include enhanced flexibility, allowing users to customize OpenClaws for specific needs. It promotes innovation by enabling third-party development, ensures scalability, and keeps the core application lean while offering a vast array of extended functionalities.

    Want to automate WordPress with OpenClaw? See our guide to setting up OpenClaw skills for WordPress automation →

  • Building a Custom OpenClaw Skill: A Developer’s Tutorial

    You’ve built a great AI assistant, but it’s still getting stuck on specific, domain-centric tasks. Maybe it’s an internal knowledge base lookup that requires a very particular API call, or perhaps a multi-step data transformation process before it can answer a user query. You’ve tried prompt engineering, fine-tuning, and even some fancy RAG setups, but the core issue remains: your assistant needs to perform a distinct, well-defined action that goes beyond general language understanding. That’s precisely where custom OpenClaw skills come into play.

    Creating a custom skill isn’t about replacing your assistant’s core intelligence, but augmenting it with specialized tools. Think of it as giving your assistant a new, highly specialized appendage. The critical first step is to define the skill’s manifest. This JSON file acts as a contract, describing the skill’s name, its purpose, and crucially, its parameters. For instance, if your skill retrieves customer order details, your manifest might include a parameter like "customer_id": {"type": "string", "description": "The unique identifier for the customer."}. This manifest is what OpenClaw uses to understand when and how to invoke your skill, effectively translating a user’s intent into a structured function call.

    Once your manifest is defined, the real work begins: implementing the skill’s backend logic. This is typically a microservice or a serverless function that exposes an HTTP endpoint. OpenClaw will send a POST request to this endpoint with the parameters extracted from the user’s query, as defined in your manifest. The non-obvious insight here is the importance of robust error handling and clear, concise responses from your skill’s endpoint. If your skill returns an ambiguous error or times out, OpenClaw’s reasoning engine will struggle to provide a coherent response to the user. A well-crafted skill not only performs its function but also communicates its status effectively back to the OpenClaw orchestrator. For example, a successful response should ideally include a "result" field containing the processed data, while an error response should have a clear "error" field detailing what went wrong.

    Deploying your skill involves registering it with your OpenClaw instance. You’ll use the OpenClaw CLI or API, typically with a command like openclaw skills add --manifest-file skill_manifest.json --endpoint-url https://your-skill-endpoint.com. After registration, OpenClaw’s reasoning engine will automatically consider your custom skill when processing user requests. It will analyze the user’s intent and, if it matches the description and parameters of your skill, generate the appropriate function call. The trick is to give your skill a clear, unambiguous description in the manifest. Avoid overly broad descriptions, as they can lead to your skill being invoked in inappropriate contexts, causing confusion for both the assistant and the user.

    To begin building your first custom skill, dive into the OpenClaw documentation and create a basic “hello world” skill that accepts a name and returns a greeting. This will familiarize you with the manifest structure and the integration flow before tackling more complex logic.

    Frequently Asked Questions

    What is OpenClaw and what does it allow me to do?

    OpenClaw is likely a development framework or platform for creating custom “skills” or functionalities. It empowers developers to extend smart devices or applications with unique voice commands, automations, or integrations beyond standard offerings.

    What are the necessary prerequisites to follow this tutorial?

    You should have basic programming knowledge (e.g., Python/JavaScript), familiarity with command-line interfaces, and an understanding of API concepts. Access to a development environment and potentially cloud services accounts will also be required.

    What kind of custom skills can I build using OpenClaw?

    You can build a wide range of skills, from simple information retrieval and home automation commands to complex integrations with third-party services, custom data processing, or unique interactive experiences tailored to your specific needs.

    Want to automate WordPress with OpenClaw? See our guide to setting up OpenClaw skills for WordPress automation →

  • The 10 Best OpenClaw Skills Worth Installing Immediately

    We’ve all been there: you’ve got OpenClaw humming along, managing your calendar, drafting emails, even helping with light coding tasks, but then you hit a wall. You need it to do something just a little more specialized, something beyond its core capabilities. That’s where skills come in, and picking the right ones from the vast OpenClaw marketplace can feel like searching for a needle in a haystack. Many users, myself included, spend too much time installing and uninstalling skills, trying to find those true force multipliers.

    Forget the generic “productivity” packs. After months of real-world use across diverse projects, I’ve narrowed down ten skills that consistently deliver outsized value and integrate seamlessly into existing workflows. These aren’t just novelties; they solve actual, recurring problems. For instance, the DataWranglerPro skill, while not the flashiest, is an absolute lifesaver for anyone dealing with CSVs or JSON arrays. Its dwp.transform_data(source_path="input.csv", output_format="json", map_fields={"old_name": "new_name"}) command alone has saved me countless hours of manual scripting when integrating data between disparate services. It handles schema inference and basic type conversions with surprising robustness, often catching issues before they become headaches.

    Another often-overlooked gem is ContextRetrieverX. Initially, I dismissed it as redundant given OpenClaw’s native context management. However, its true power lies in its ability to pull highly specific, user-defined context from a wider range of sources, including local documents, Slack channels, and even specific web pages, then inject it directly into a prompt with a custom decay rate. The non-obvious insight here is that while OpenClaw’s native context is excellent for recent interactions, ContextRetrieverX excels at providing “deep dives” into specific, long-tail knowledge bases without polluting the primary context window. This is especially useful for project-specific research or compliance checks where precise, external data is paramount.

    Then there’s CodeReviewBuddy, which goes far beyond simple syntax checks. It leverages multiple LLMs to analyze code for potential security vulnerabilities, performance bottlenecks, and adherence to specific coding standards. Pair it with TestScenarioGenerator, and you have a formidable duo for improving code quality and coverage. Other essential skills include MultiTranslatorPro for nuanced language translation, SummarizeThatDoc for rapid document digestion, CalendarSyncPlus for advanced scheduling, EmailTriagePro for intelligent inbox management, ResearchAgentAlpha for structured web research, and CreativeContentEngine for generating diverse content formats. The key isn’t just having these skills, but understanding how they interoperate, creating a synergistic effect that elevates OpenClaw from a helpful assistant to an indispensable team member.

    To start, log into your OpenClaw dashboard and install DataWranglerPro. Experiment with its data transformation capabilities on a small dataset.

    Frequently Asked Questions

    What exactly are OpenClaw Skills?

    OpenClaw Skills are powerful enhancements or add-ons for the OpenClaw platform. They extend functionality, improve user experience, or automate tasks, helping you maximize your OpenClaw system’s potential and productivity.

    How do I install these recommended OpenClaw Skills?

    Installation is usually straightforward. Access the OpenClaw marketplace or settings, search for the skill by name, and click ‘Install.’ Follow any prompts to complete activation and begin using it.

    Are these OpenClaw Skills free to use?

    Many OpenClaw Skills, including those often recommended, are free. However, some advanced or premium skills may require a one-time purchase or a subscription. Always check the individual skill’s details for pricing.

    Written by: Alex Torres, Editor at OpenClaw Resource

    Last Updated: May 2026

    Our Editorial Standards | How We Review Skills | Affiliate Disclosure

    Want to automate WordPress with OpenClaw? See our guide to setting up OpenClaw skills for WordPress automation →