# How OpenHuman Discovers, Installs, and Executes Skills: A Complete Technical Guide

> Learn how OpenHuman discovers, installs, and executes SKILL.md bundles using JSON-RPC APIs. Explore its idempotent installs and sandboxed runtime for efficient skill management.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: how-to-guide
- Published: 2026-08-30

---

**OpenHuman uses a three-stage lifecycle—discovery, installation, and execution—to manage SKILL.md bundles through JSON-RPC APIs, with idempotent installs and sandboxed runtime environments.**

The [tinyhumansai/openhuman](https://github.com/tinyhumansai/openhuman) project implements a fully-featured **skill system** that allows users to extend the desktop application and embedded Rust core with custom abilities packaged as SKILL.md bundles. This architecture separates the concerns of locating available skills, securely installing them into the workspace, and running them in isolated sandboxes with proper permission controls.

## Skill Discovery: Catalog Loading and Metadata Parsing

Discovery begins when the core loads a **catalog** of available skills from built-in sources, remote HTTP endpoints, or the user's local `skills/` directory. The system walks the directory tree, parses Markdown front-matter from each [`SKILL.md`](https://github.com/tinyhumansai/openhuman/blob/main/SKILL.md) file, and registers metadata including the skill's name, namespace, required tools, and capabilities.

### Core Discovery Modules

The discovery orchestration happens in [`src/openhuman/skills/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/ops.rs), which delegates to [`src/openhuman/skills/ops_discover.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/ops_discover.rs) for the actual directory walking and remote source fetching. The data model defined in [`src/openhuman/skills/types.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/types.rs) represents each skill as a `SkillEntry` struct containing the parsed metadata.

Remote catalogs are handled by [`src/openhuman/skills/catalog/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/catalog/ops.rs), which fetches entries from sources like GitHub or ClawHub and caches them in the workspace's `skill_cache/` folder. Subsequent discovery calls reuse this cache unless the source URL changes or the user triggers an explicit refresh.

### Discovery RPC Methods

The system exposes three primary JSON-RPC methods for browsing available skills:

- **`openhuman.skill_registry_sources`** – Returns a list of configured remote sources and local paths
- **`openhuman.skill_registry_browse`** – Lists skill entries from a specific source with name, description, and capabilities  
- **`openhuman.skill_registry_search`** – Filters the catalog by keyword to find specific functionality

```rust
// Discover remote skill sources
let sources = core_rpc_client
    .call("openhuman.skill_registry_sources", json!({}))
    .await?;
// Returns: [{"url":"https://github.com/tinyhumansai/openhuman-skills","paths":["skills"]}]

// Browse a specific source for available skills
let browse = core_rpc_client
    .call("openhuman.skill_registry_browse", json!({"source_id":"github"}))
    .await?;
// Returns array of skill objects with name, namespace, and description fields

```

## Skill Installation: Idempotent Bundle Management

Once a user selects a skill, the **installation** process copies the skill's files into the workspace's `skills/` folder, validates the bundle against its JSON schema, and updates the internal **skill registry**. The operation is **idempotent**—re-installing an existing skill returns success without creating duplicates if the manifest matches the incoming bundle.

### Installation Architecture

The `openhuman.skill_registry_install` RPC method is implemented in [`src/openhuman/skills/ops_install.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/ops_install.rs). This handler:
1. Validates the skill bundle structure
2. Copies files to `<workspace>/skills/<skill_name>/`
3. Writes a [`skill.toml`](https://github.com/tinyhumansai/openhuman/blob/main/skill.toml) manifest  
4. Updates [`src/openhuman/skills/registry.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/registry.rs), which persists the installed skill list to [`skills/registry.json`](https://github.com/tinyhumansai/openhuman/blob/main/skills/registry.json)
5. Publishes events via [`src/openhuman/skills/bus.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/bus.rs) to notify the frontend of install/uninstall state changes

```rust
// Install a chosen skill from a remote source
let install = core_rpc_client
    .call("openhuman.skill_registry_install", json!({
        "source_id": "github",
        "entry_id": "gmail"
    }))
    .await?;
// Response: {"new_skills": ["gmail"]} - files now located at <workspace>/skills/gmail/

```

The registry enforces idempotency by checking the target path before copying. If the skill folder exists and the [`skill.toml`](https://github.com/tinyhumansai/openhuman/blob/main/skill.toml) manifest matches the incoming bundle, the operation returns an empty `new_skills` array, as verified by the E2E test `skill_registry_install (duplicate)`.

## Skill Execution: Runtime Sandbox and Sub-Agent Invocation

Execution supports two invocation modes: **tool-based** (e.g., `skill.run_workflow`) and **sub-agent** execution via `skill_executor`. The runtime reads the skill's [`SKILL.md`](https://github.com/tinyhumansai/openhuman/blob/main/SKILL.md) to construct the execution prompt, then runs the workflow in an isolated sandbox supporting Node, Python, or native environments.

### Execution Flow

The entry point in [`src/openhuman/skills/runtime/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/runtime/ops.rs) launches the skill run and establishes the sandbox environment. The `skill_executor` sub-agent, located in [`src/openhuman/skills/runtime/agent/skill_executor/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/runtime/agent/skill_executor/mod.rs), interprets the workflow steps defined in the SKILL.md, invokes any required tools through adapters in [`src/openhuman/skills/runtime/tools.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/runtime/tools.rs), and streams results back to the caller.

```rust
// Execute a skill as a workflow tool
let run = core_rpc_client
    .call("openhuman.skill_run_workflow", json!({
        "skill_id": "gmail",
        "input": {"prompt":"Send a draft email to Alice"}
    }))
    .await?;
// Results stream back as text, files, or nested tool calls

```

## Security, Permissions, and Caching

Before execution, the core validates the skill's declared `SkillPermission` level against the current **autonomy tier**. Skills requesting network or file-write permissions trigger the **approval gate**, which may prompt the user for explicit consent. The runtime sandbox ([`src/openhuman/skills/runtime/stub.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/runtime/stub.rs) and platform-specific implementations) isolates the skill's process, enforcing declared limits on resource access.

Discovered remote catalogs utilize the workspace's `skill_cache/` directory to avoid redundant network requests. The cache invalidation logic checks source URL changes against stored metadata to determine when fresh fetches are required.

All skill-related RPC schemas are defined in [`src/openhuman/skills/schemas/controller_schemas.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/schemas/controller_schemas.rs) and advertised to the frontend via the JSON-RPC `/schema` endpoint, ensuring type-safe client generation.

## Summary

- **Discovery** walks local directories and remote sources to parse [`SKILL.md`](https://github.com/tinyhumansai/openhuman/blob/main/SKILL.md) front-matter into `SkillEntry` structs, with caching in `skill_cache/` handled by [`src/openhuman/skills/catalog/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/catalog/ops.rs)
- **Installation** via `openhuman.skill_registry_install` is idempotent, writing bundles to `skills/` and updating the registry persisted in [`skills/registry.json`](https://github.com/tinyhumansai/openhuman/blob/main/skills/registry.json) through [`src/openhuman/skills/ops_install.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/ops_install.rs)
- **Execution** runs skills in isolated sandboxes through `skill_executor` sub-agents in [`src/openhuman/skills/runtime/agent/skill_executor/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/runtime/agent/skill_executor/mod.rs) that interpret workflows and invoke tools via adapters
- **Security** enforces `SkillPermission` levels against autonomy tiers, with approval gates for sensitive operations and process isolation via sandbox stubs
- All operations route through the JSON-RPC layer ([`src/openhuman/core/jsonrpc.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/core/jsonrpc.rs)) and client ([`src/openhuman/api/client.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/api/client.rs)) using schemas from [`src/openhuman/skills/schemas/controller_schemas.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/schemas/controller_schemas.rs)

## Frequently Asked Questions

### How does OpenHuman handle duplicate skill installations?

OpenHuman treats installation as an idempotent operation. When `openhuman.skill_registry_install` is called, the system checks if the target skill folder already exists in the workspace's `skills/` directory and validates the existing [`skill.toml`](https://github.com/tinyhumansai/openhuman/blob/main/skill.toml) manifest against the incoming bundle. If they match, the operation returns success with an empty `new_skills` array without modifying files, as implemented in [`src/openhuman/skills/ops_install.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/ops_install.rs) and verified by the `skill_registry_install (duplicate)` E2E test.

### What file formats does OpenHuman use to define skills?

Skills are defined by **SKILL.md** files containing YAML front-matter that specifies metadata, required tools, and capabilities, accompanied by a matching JSON schema for validation. Upon installation, the system generates a [`skill.toml`](https://github.com/tinyhumansai/openhuman/blob/main/skill.toml) manifest in the skill's directory to track installed state and version information, while the registry maintains the global list in [`skills/registry.json`](https://github.com/tinyhumansai/openhuman/blob/main/skills/registry.json).

### Can OpenHuman skills access the network or filesystem?

Access depends on the skill's declared `SkillPermission` level and the system's current **autonomy tier**. Skills requesting network or file-write permissions must pass through the **approval gate**, which may prompt the user for explicit consent before execution. The runtime enforces these limits through platform-specific sandbox implementations in [`src/openhuman/skills/runtime/stub.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/skills/runtime/stub.rs) that isolate the skill's process from host resources.

### Where does OpenHuman cache remote skill catalogs?

Remote catalogs are cached in the workspace's `skill_cache/` folder after the first discovery request. The system reuses this cached data for subsequent `openhuman.skill_registry_browse` or `openhuman.skill_registry_sources` calls unless the source URL changes or the user explicitly triggers a refresh, reducing network overhead for repeated operations.