# How the MCP Server Exposes Skills to AI Agents via Progressive Disclosure

> Learn how the MCP server uses progressive disclosure to expose skills to AI agents. Discover the three step workflow: search_skills, read_skill, and fetch_skill_files for efficient data delivery.

- Repository: [TechLeads.club 💎/agent-skills](https://github.com/tech-leads-club/agent-skills)
- Tags: architecture
- Published: 2026-05-18

---

**The agent-skills MCP server implements a three-step progressive disclosure workflow—`search_skills`, `read_skill`, and `fetch_skill_files`—to expose only the minimal skill data an AI agent needs at each stage, preventing full catalog downloads and protecting context windows.**

The `tech-leads-club/agent-skills` repository provides an MCP (Model Context Protocol) server that acts as a lightweight, on-demand gateway between AI clients and the Agent Skills catalog. Rather than forcing agents to download the entire skill library upfront, the server leverages **progressive disclosure** to transfer data incrementally, ensuring that only relevant skills and their specific assets are retrieved based on the agent's immediate intent.

## The Three-Step Progressive Disclosure Workflow

The MCP server exposes skills through a strictly sequenced workflow defined in [`packages/mcp/src/main.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/main.ts), where each step gates the next to enforce minimal data transfer.

### Step 1: Search Skills via Fuzzy Matching

The `search_skills` tool, implemented in [`packages/mcp/src/tools/search-tool.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/tools/search-tool.ts), performs fuzzy matching against the full catalog without downloading it entirely. On startup, the server builds a Fuse.js index (`Indexes` type in [`packages/mcp/src/types.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/types.ts)) that stores skill metadata with weighted fields: **name** (45%), **triggers** (30%), **description** (20%), and **category** (5%).

When an agent submits a query, the tool returns up to **5 high-relevance skill summaries** containing only metadata—no full instructions. The catalog JSON is cached locally with a **15-minute TTL**, ensuring searches execute against memory rather than repeated CDN hits.

```json
{
  "tool": "search_skills",
  "args": { "query": "react component testing" }
}

```

```json
[
  {
    "name": "react-testing-patterns",
    "description": "Best‑practice patterns for testing React components with Jest + Testing Library.",
    "category": "testing",
    "score": 92,
    "match_quality": "strong"
  }
]

```

### Step 2: Read the Selected Skill

After the agent selects a skill from the search results, the `read_skill` tool ([`packages/mcp/src/tools/skill-tool.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/tools/skill-tool.ts)) fetches the canonical [`SKILL.md`](https://github.com/tech-leads-club/agent-skills/blob/main/SKILL.md) file. This tool validates the skill name against the in-memory index and aborts on CDN failures.

Crucially, the response includes two distinct parts: the full skill instructions and a **whitelist of reference files** (`scripts/`, `references/`, `assets/`). The agent cannot arbitrarily request files; it must use the paths explicitly returned by this step.

```json
{
  "tool": "read_skill",
  "args": { "skill_name": "react-testing-patterns" }
}

```

The tool constructs CDN URLs via [`packages/mcp/src/utils.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/utils.ts), targeting `https://cdn.jsdelivr.net/gh/tech-leads-club/agent-skills@latest/<skill-path>/<file>`.

### Step 3: Fetch Reference Files On Demand

The final optional step, `fetch_skill_files` ([`packages/mcp/src/tools/fetcher-tool.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/tools/fetcher-tool.ts)), downloads only the specific supporting assets the skill instructions require. The tool enforces two critical constraints:

- **Maximum 5 files per call** to prevent context window flooding
- **Path validation** against the whitelist returned in Step 2

If individual files fail to download, the tool returns partial results rather than failing entirely.

```json
{
  "tool": "fetch_skill_files",
  "args": {
    "skill_name": "react-testing-patterns",
    "file_paths": [
      "references/testing-library.md",
      "scripts/setup.sh"
    ]
  }
}

```

## Core Implementation and Validation Logic

### FastMCP Tool Registration

In [`packages/mcp/src/main.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/main.ts), each tool is registered with `fastmcp` using description strings that explicitly label the step number. This guides downstream agents through the intended sequence and prevents out-of-order execution.

### Strict Input Validation

The progressive disclosure architecture relies on three validation layers:

- **`search_skills`** refuses empty queries to prevent unnecessary index scans
- **`read_skill`** validates skill names against the in-memory index before CDN requests
- **`fetch_skill_files`** validates every requested path against the Step 2 whitelist and blocks directory traversal attempts

### End-to-End Integration Example

The following TypeScript demonstrates the complete workflow an MCP client implements:

```typescript
async function runMcpWorkflow(task: string) {
  const search = await mcp.call('search_skills', { query: task });
  const best = search[0].name;
  
  const { main, references } = await mcp.call('read_skill', { skill_name: best });
  console.log('Skill instructions:', main);

  const needed = references.filter(p => p.endsWith('.sh')).slice(0, 5);
  if (needed.length) {
    const files = await mcp.call('fetch_skill_files', {
      skill_name: best,
      file_paths: needed
    });
    console.log('Fetched helper scripts:', files);
  }
}

```

## Summary

- The **progressive disclosure** workflow isolates data exposure into three sequential steps: `search_skills`, `read_skill`, and `fetch_skill_files`
- **No full catalog download** occurs; only metadata searches execute against the local Fuse.js index ([`packages/mcp/src/types.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/types.ts))
- **Path whitelisting** in [`packages/mcp/src/tools/fetcher-tool.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/tools/fetcher-tool.ts) prevents agents from accessing unauthorized files outside the skill directory
- **CDN integration** via [`packages/mcp/src/utils.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/utils.ts) serves files from `jsdelivr.net` with strict URL construction
- **Validation at each layer** ensures agents learn only what they explicitly request, protecting token budgets and context windows

## Frequently Asked Questions

### What is progressive disclosure in the context of MCP servers?

**Progressive disclosure** is a data transfer pattern where the server exposes information incrementally rather than all at once. In the agent-skills MCP server, this means an AI agent first searches metadata, then retrieves only the selected skill's instructions, and finally fetches specific reference files if needed. This approach minimizes token usage and prevents context window overflow by ensuring agents never receive skill data they haven't explicitly requested.

### How does the MCP server prevent agents from accessing unauthorized skill files?

The server implements **path whitelisting** in [`packages/mcp/src/tools/fetcher-tool.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/tools/fetcher-tool.ts). When an agent calls `fetch_skill_files`, the tool validates every requested path against the whitelist returned by the previous `read_skill` call. Agents cannot guess or construct arbitrary paths; they must use the exact file references provided in Step 2, effectively sandboxing file access to the specific skill's directory.

### What happens if the CDN is unavailable when fetching skill files?

According to the implementation in [`packages/mcp/src/tools/skill-tool.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/tools/skill-tool.ts), the `read_skill` tool aborts entirely on CDN failures to prevent serving stale or incomplete instructions. However, [`packages/mcp/src/tools/fetcher-tool.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/tools/fetcher-tool.ts) handles failures in the optional file fetching step by returning **partial results**—successfully retrieved files are returned even if individual assets fail, allowing the agent to proceed with available resources.

### How many skills can the search tool return per query?

The `search_skills` tool in [`packages/mcp/src/tools/search-tool.ts`](https://github.com/tech-leads-club/agent-skills/blob/main/packages/mcp/src/tools/search-tool.ts) returns **up to 5 high-relevance skill summaries** per query. This limit protects the context window from being flooded with irrelevant options while still providing sufficient choice for the agent to identify the most appropriate skill for the user's intent.