> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Skill Fallbacks

> Offer a skill only when a capability is missing — graceful degradation for skills

Fallback skills are offered only when a needed tool or MCP server is absent.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent

agent = Agent(
    name="Researcher",
    instructions="Answer research questions.",
    skills=["./skills/web-via-terminal", "./skills/summarise"],
)
agent.start("Find recent papers on diffusion models.")
```

The user runs the agent; fallback skills appear in the listing only when required tools or servers are missing.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Skill Fallback Logic"
        T{Primary Tool Present?}
        T -->|Yes| H[Fallback Hidden]
        T -->|No| R{Fallback Requirements Met?}
        R -->|Yes| S[Fallback Shown]
        R -->|No| H2[Fallback Hidden]
    end

    classDef decision fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef shown fill:#10B981,stroke:#7C90A0,color:#fff
    classDef hidden fill:#8B0000,stroke:#7C90A0,color:#fff

    class T,R decision
    class S shown
    class H,H2 hidden
```

## Quick Start

**1. Declare a fallback in SKILL.md**

Add `fallback_for_tools` or `fallback_for_servers` to the SKILL.md frontmatter:

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
---
name: web-via-terminal
description: Fetch web content using terminal when no web tool is available
requires_tools: [terminal]
fallback_for_tools: [web]
---

# Web via Terminal
When the web tool is absent, use terminal commands like curl to fetch content.
```

The skill appears **only when** the `web` tool is not present, and **only when** `terminal` is available.

**2. Wire it into an Agent**

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent

agent = Agent(
    name="Researcher",
    instructions="Find information for the user",
    skills=["./skills/web-via-terminal", "./skills/web-fetch"],
)
agent.start("Look up the latest Python release")
```

* If `web-fetch` provides a `web` tool → `web-via-terminal` is hidden.
* If only `terminal` is available → `web-via-terminal` is offered.

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant Agent
    participant SkillManager
    participant Skill as web-via-terminal

    Agent->>SkillManager: get_available_skills()
    SkillManager->>Skill: check fallback_for_tools = [web]
    alt web tool present
        SkillManager-->>Agent: skill excluded (primary present)
    else web tool absent
        SkillManager->>Skill: check requires_tools = [terminal]
        alt terminal present
            SkillManager-->>Agent: skill included
        else terminal absent
            SkillManager-->>Agent: skill excluded (requires_tools not met)
        end
    end
```

| Primary tool state | Fallback `requires_*` met? | Skill offered? |
| - | - | - |
| **Present** | Any | No — primary handles it |
| **Absent** | Yes | Yes — fallback steps in |
| **Absent** | No | No — fallback can't run either |

> [!NOTE]
>
> The skill's own `requires_tools` / `requires_servers` / `requires_env` gates still apply on top of fallback eligibility. A fallback skill that can't satisfy its own requirements is still excluded.

***

## Configuration Options

| Key | Type | Default | Description |
| - | - | - | - |
| `fallback_for_tools` | `list[str]` | `[]` | Skill is offered only when none of these tool names are present. |
| `fallback_for_servers` | `list[str]` | `[]` | Skill is offered only when none of these MCP server names are present. |
| `fallback-for-tools` | `list[str]` | `[]` | Hyphenated alias of `fallback_for_tools`. |
| `fallback-for-servers` | `list[str]` | `[]` | Hyphenated alias of `fallback_for_servers`. |

Both underscore and hyphen forms are accepted. If both are set, the union is used.

***

## Common Patterns

### Web fallback via terminal

When a native `web` tool is absent, let agents use `curl` through the `terminal` tool instead:

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
---
name: web-via-terminal
requires_tools: [terminal]
fallback_for_tools: [web]
---
```

### Local search fallback when no MCP search server is configured

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
---
name: local-grep-search
description: Search local files using grep when no MCP search server is available
requires_tools: [terminal]
fallback_for_servers: [mcp-search-server]
---
```

### Multiple primary tools — fallback hidden unless all are absent

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
---
name: lightweight-pdf-reader
requires_tools: [terminal]
fallback_for_tools: [pdf_read, ocr_extract]
---
```

The fallback is hidden if **any** of `pdf_read` or `ocr_extract` is present.

***

## Best Practices

> [accordion] Pair fallback\_for\_\* with requires\_\*
>
> A fallback skill that cannot run is still excluded. Always declare the tools the fallback actually needs via `requires_tools` so the skill manager can gate it properly.
>
> ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> ---
> name: web-via-terminal
> requires_tools: [terminal]        # needs terminal to run
> fallback_for_tools: [web]         # only offered when web is absent
> ---
> ```

> [accordion] Keep fallback skill outputs self-explanatory
>
> Fallback skills run in place of a primary capability — their output should be as close as possible to what the primary would produce. Add notes in the skill body describing any known differences.

> [accordion] Don't chain fallbacks
>
> Avoid making a fallback skill declare its own `fallback_for_*` pointing to another fallback skill. The filter logic is applied once during skill discovery and chaining is not resolved automatically.

> [accordion] Test with the primary absent and present
>
> Verify both paths: that the fallback appears when the primary is absent, and that it disappears when the primary is present.
>
> ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> # Without primary tool
> agent_no_web = Agent(
>     name="Test",
>     instructions="Research topics",
>     skills=["./skills/web-via-terminal"],  # web tool not loaded
> )
>
> # With primary tool loaded — fallback should be hidden
> agent_with_web = Agent(
>     name="Test",
>     instructions="Research topics",
>     skills=["./skills/web-via-terminal", "./skills/web-fetch"],
> )
> ```

***

## Related

> [card] [Skill Capability Gates](https://praison.ai/docs/features/skill-capability-gates.md)
>
> Declare tool, server, and env requirements — the forward gates that fallbacks complement

> [card] [Agent Skills](https://praison.ai/docs/features/skills.md)
>
> Overview of the skills system and how to write skills

> [card] [Skill Invocation](https://praison.ai/docs/features/skills-invocation.md)
>
> How skills are invoked at runtime

> [card] [Skill Lifecycle](https://praison.ai/docs/features/skill-lifecycle.md)
>
> Discover, validate, and activate skills


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.