---
title: "Skills"
description: "Load, discover, inject, and inspect domain-specific knowledge packs."
icon: "graduation-cap"
---

For the full guide, see [Skills](/guides/skills).

<Note>
Recommended progression on this page:
1. discover skills
2. inspect a skill
3. preload skills for a session
4. inject typed skills for the first turn if you do not want a session-level preload
5. inject skills for one specific turn
</Note>

## List available skills

Discover all skills from every source (project, user, filesystem, git, HTTP, stdio, embedded) with provenance and shadowing info.

<Tabs>
  <Tab title="CLI">
    ```bash
    # Human-readable table
    rkat skill list

    # Machine-readable JSON
    rkat skill list --json
    ```
  </Tab>
  <Tab title="JSON-RPC">
    ```json
    {
      "jsonrpc": "2.0", "id": 1,
      "method": "skills/list",
      "params": {}
    }
    ```
  </Tab>
  <Tab title="REST">
    ```bash
    curl http://127.0.0.1:8080/skills
    ```
  </Tab>
  <Tab title="MCP">
    ```json
    {
      "name": "meerkat_skills",
      "arguments": { "action": "list" }
    }
    ```
  </Tab>
  <Tab title="Python">
    ```python
    skills = await client.list_skills()
    for s in skills:
        key = s["key"]
        print(f"{key['source_uuid']}/{key['skill_name']}: {s['name']}")
    ```
  </Tab>
  <Tab title="TypeScript">
    ```typescript
    const skills = await client.listSkills();
    for (const s of skills) {
      const key = s.key as { source_uuid: string; skill_name: string };
      console.log(`${key.source_uuid}/${key.skill_name}: ${s.name}`);
    }
    ```
  </Tab>
  <Tab title="Rust">
    ```rust
    let entries = skill_runtime
        .list_all_with_provenance(&SkillFilter::default())
        .await?;
    for entry in &entries {
        println!("{}: active={}", entry.descriptor.key, entry.is_active);
    }
    ```
  </Tab>
</Tabs>

## Inspect a skill

View the full body and metadata of a specific skill by canonical key.

<Tabs>
  <Tab title="CLI">
    ```bash
    # Inspect the active version
    rkat skill inspect task-workflow \
      --source-uuid 00000000-0000-4b11-8111-000000000001

    # JSON output
    rkat skill inspect task-workflow \
      --source-uuid 00000000-0000-4b11-8111-000000000001 \
      --json
    ```
  </Tab>
  <Tab title="MCP">
    ```json
    {
      "name": "meerkat_skills",
      "arguments": {
        "action": "inspect",
        "skill_key": {
          "source_uuid": "00000000-0000-4b11-8111-000000000001",
          "skill_name": "task-workflow"
        },
        "source": "00000000-0000-4b11-8111-000000000001"
      }
    }
    ```
  </Tab>
  <Tab title="Rust">
    ```rust
    let key = SkillKey::new(
        SourceUuid::parse("00000000-0000-4b11-8111-000000000001")?,
        SkillName::parse("task-workflow")?,
    );
    let doc = skill_runtime
        .load_from_source(&key, Some("00000000-0000-4b11-8111-000000000001"))
        .await?;
    println!("{}", doc.body);
    ```
  </Tab>
</Tabs>

## Preload skills for a session

Use this when the skill should shape the whole session from the start.

`CLI --skill` is the preload-oriented local path. `preload_skills` is the explicit session-build surface on the APIs.

<Tabs>
  <Tab title="CLI">
    ```bash
    rkat run "Extract emails" \
      --skill email-extractor \
      --skill markdown-formatter
    ```
  </Tab>
  <Tab title="JSON-RPC">
    ```json
    {
      "jsonrpc": "2.0", "id": 1,
      "method": "session/create",
      "params": {
        "prompt": "Extract emails",
        "preload_skills": [
          {
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "email-extractor"
          },
          {
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "markdown-formatter"
          }
        ]
      }
    }
    ```
  </Tab>
  <Tab title="REST">
    ```bash
    curl -X POST http://127.0.0.1:8080/sessions \
      -H "Content-Type: application/json" \
      -d '{
        "prompt": "Extract emails",
        "preload_skills": [
          {
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "email-extractor"
          },
          {
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "markdown-formatter"
          }
        ]
      }'
    ```
  </Tab>
  <Tab title="MCP">
    ```json
    {
      "name": "meerkat_run",
      "arguments": {
        "prompt": "Extract emails",
        "preload_skills": [
          {
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "email-extractor"
          },
          {
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "markdown-formatter"
          }
        ]
      }
    }
    ```
  </Tab>
  <Tab title="Python">
    ```python
    from meerkat import SkillKey

    result = await client.create_session(
        "Extract emails",
        preload_skills=[
            SkillKey(
                source_uuid="dc256086-0d2f-4f61-a307-320d4148107f",
                skill_name="email-extractor",
            ),
            SkillKey(
                source_uuid="dc256086-0d2f-4f61-a307-320d4148107f",
                skill_name="markdown-formatter",
            ),
        ],
    )
    ```
  </Tab>
  <Tab title="TypeScript">
    ```typescript
    const result = await client.createSession("Extract emails", {
      preloadSkills: [
        {
          sourceUuid: "dc256086-0d2f-4f61-a307-320d4148107f",
          skillName: "email-extractor",
        },
        {
          sourceUuid: "dc256086-0d2f-4f61-a307-320d4148107f",
          skillName: "markdown-formatter",
        },
      ],
    });
    ```
  </Tab>
  <Tab title="Rust">
    ```rust
    let build_opts = SessionBuildOptions {
        preload_skills: Some(vec![
            SkillKey::new(
                SourceUuid::parse("dc256086-0d2f-4f61-a307-320d4148107f")?,
                SkillName::parse("email-extractor")?,
            ),
            SkillKey::new(
                SourceUuid::parse("dc256086-0d2f-4f61-a307-320d4148107f")?,
                SkillName::parse("markdown-formatter")?,
            ),
        ]),
        ..Default::default()
    };
    ```
  </Tab>
</Tabs>

## First-turn skill injection

Use `skill_refs` when the skill should be injected for the first turn rather than preloaded into the session system prompt.

<Tabs>
  <Tab title="JSON-RPC">
    ```json
    {
      "jsonrpc": "2.0", "id": 1,
      "method": "session/create",
      "params": {
        "prompt": "Extract emails",
        "skill_refs": [
          {
            "kind": "structured",
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "email-extractor"
          },
          {
            "kind": "structured",
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "markdown-formatter"
          }
        ]
      }
    }
    ```
  </Tab>
  <Tab title="REST">
    ```bash
    curl -X POST http://127.0.0.1:8080/sessions \
      -H "Content-Type: application/json" \
      -d '{
        "prompt": "Extract emails",
        "skill_refs": [
          {
            "kind": "structured",
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "email-extractor"
          },
          {
            "kind": "structured",
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "markdown-formatter"
          }
        ]
      }'
    ```
  </Tab>
  <Tab title="MCP">
    ```json
    {
      "name": "meerkat_run",
      "arguments": {
        "prompt": "Extract emails",
        "skill_refs": [
          {
            "kind": "structured",
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "email-extractor"
          },
          {
            "kind": "structured",
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "markdown-formatter"
          }
        ]
      }
    }
    ```
  </Tab>
  <Tab title="Python">
    ```python
    from meerkat import SkillKey

    result = await client.create_session(
        "Extract emails",
        skill_refs=[
            SkillKey(
                source_uuid="dc256086-0d2f-4f61-a307-320d4148107f",
                skill_name="email-extractor",
            ),
            SkillKey(
                source_uuid="dc256086-0d2f-4f61-a307-320d4148107f",
                skill_name="markdown-formatter",
            ),
        ],
    )
    ```
  </Tab>
  <Tab title="TypeScript">
    ```typescript
    const result = await client.createSession("Extract emails", {
      skillRefs: [
        {
          sourceUuid: "dc256086-0d2f-4f61-a307-320d4148107f",
          skillName: "email-extractor",
        },
        {
          sourceUuid: "dc256086-0d2f-4f61-a307-320d4148107f",
          skillName: "markdown-formatter",
        },
      ],
    });
    ```
  </Tab>
  <Tab title="Rust">
    ```rust
    let request = CreateSessionRequest {
        model: "claude-sonnet-4-6".into(),
        prompt: "Extract emails".into(),
        system_prompt: None,
        max_tokens: None,
        event_tx: None,
        render_metadata: None,
        skill_references: Some(vec![
            SkillKey {
                source_uuid: SourceUuid::parse("dc256086-0d2f-4f61-a307-320d4148107f")?,
                skill_name: SkillName::parse("email-extractor")?,
            },
            SkillKey {
                source_uuid: SourceUuid::parse("dc256086-0d2f-4f61-a307-320d4148107f")?,
                skill_name: SkillName::parse("markdown-formatter")?,
            },
        ]),
        initial_turn: InitialTurnPolicy::RunImmediately,
        deferred_prompt_policy: DeferredPromptPolicy::Discard,
        build: None,
        labels: None,
    };
    let result = service.create_session(request).await?;
    ```
  </Tab>
</Tabs>

## Per-turn skill injection

Inject skills into a specific turn on an existing session. The skill content is added to the context for that turn only. On the CLI, `--skill` remains the preload-style runtime-local path; the typed per-turn surface is `skill_refs`.

<Tabs>
  <Tab title="CLI">
    ```bash
    rkat run --resume <session-id> "Now format the output" \
      --skill markdown-formatter
    ```
  </Tab>
  <Tab title="JSON-RPC">
    ```json
    {
      "jsonrpc": "2.0", "id": 2,
      "method": "turn/start",
      "params": {
        "session_id": "019467d9-7e3a-7000-8000-000000000000",
        "prompt": "Now format the output",
        "skill_refs": [
          {
            "kind": "structured",
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "markdown-formatter"
          }
        ]
      }
    }
    ```
  </Tab>
  <Tab title="REST">
    ```bash
    curl -X POST http://localhost:8080/sessions/019467d9-7e3a.../messages \
      -H "Content-Type: application/json" \
      -d '{
        "prompt": "Now format the output",
        "skill_refs": [
          {
            "kind": "structured",
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "markdown-formatter"
          }
        ]
      }'
    ```
  </Tab>
  <Tab title="MCP">
    ```json
    {
      "name": "meerkat_resume",
      "arguments": {
        "session_id": "019467d9-7e3a-7000-8000-000000000000",
        "prompt": "Now format the output",
        "skill_refs": [
          {
            "kind": "structured",
            "source_uuid": "dc256086-0d2f-4f61-a307-320d4148107f",
            "skill_name": "markdown-formatter"
          }
        ]
      }
    }
    ```
  </Tab>
  <Tab title="Python">
    ```python
    from meerkat import SkillKey

    result = await session.turn(
        "Now format the output",
        skill_refs=[
            SkillKey(
                source_uuid="dc256086-0d2f-4f61-a307-320d4148107f",
                skill_name="markdown-formatter",
            )
        ],
    )
    ```
  </Tab>
  <Tab title="TypeScript">
    ```typescript
    const result = await session.turn("Now format the output", {
      skillRefs: [
        {
          sourceUuid: "dc256086-0d2f-4f61-a307-320d4148107f",
          skillName: "markdown-formatter",
        },
      ],
    });
    ```
  </Tab>
  <Tab title="Rust">
    ```rust
    let result = service.start_turn(&session_id, StartTurnRequest {
        prompt: "Now format the output".into(),
        system_prompt: None,
        event_tx: None,
        runtime: StartTurnRuntimeSemantics::new(
            None,
            HandlingMode::Queue,
            Some(vec![SkillKey {
                source_uuid: SourceUuid::parse("dc256086-0d2f-4f61-a307-320d4148107f")?,
                skill_name: SkillName::parse("markdown-formatter")?,
            }]),
            None,
            Vec::new(),
            None,
        ),
    }).await?;
    ```
  </Tab>
</Tabs>

<Note>
If you need the deeper source/precedence model, continue to the main [Skills guide](/guides/skills).
</Note>

## Next step

- [Examples: Tools](/examples/tools)
- [Examples: Memory](/examples/memory)
