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

# SkillRegistry

> The SkillRegistry manages all MCP skills within a scope. Skills are reusable prompts/instructions that can be searched, loaded, and optionally synced to external storage.

## Overview

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { SkillRegistry } from '@frontmcp/sdk';

// Access via scope
const skills = scope.skills;

// List all skills
const allSkills = skills.getSkills();

// Search skills
const results = await skills.search('data analysis');

// Load a skill
const skill = await skills.loadSkill('data-pipeline');
```

## Methods

### getSkills()

Get all skills with optional filtering.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
getSkills(options?: GetSkillsOptions): ReadonlyArray<SkillEntry>
```

| Option          | Type                        | Description           |
| --------------- | --------------------------- | --------------------- |
| `includeHidden` | `boolean`                   | Include hidden skills |
| `visibility`    | `'mcp' \| 'http' \| 'both'` | Filter by visibility  |

**Example:**

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Get all visible skills
const skills = registry.getSkills();

// Get skills visible via HTTP
const httpSkills = registry.getSkills({ visibility: 'http' });
```

### search()

Search skills using TF-IDF text matching.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
search(query: string, options?: SearchOptions): Promise<SearchResult[]>
```

| Option       | Type                        | Description               |
| ------------ | --------------------------- | ------------------------- |
| `limit`      | `number`                    | Maximum results to return |
| `minScore`   | `number`                    | Minimum relevance score   |
| `visibility` | `'mcp' \| 'http' \| 'both'` | Filter by visibility      |

**Example:**

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const results = await registry.search('data analysis', {
  limit: 10,
  minScore: 0.5,
});

for (const result of results) {
  console.log(`${result.skill.name}: ${result.score}`);
}
```

### loadSkill()

Load skill content by ID/name with tool validation.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
loadSkill(skillId: string): Promise<LoadedSkill>
```

**Example:**

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const skill = await registry.loadSkill('data-pipeline');
console.log(skill.content); // Full skill content
console.log(skill.tools);   // Validated tool references
```

### listSkills()

List skills with pagination support.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
listSkills(options?: ListOptions): Promise<SkillListResult>
```

| Option       | Type                        | Description          |
| ------------ | --------------------------- | -------------------- |
| `offset`     | `number`                    | Starting index       |
| `limit`      | `number`                    | Maximum results      |
| `visibility` | `'mcp' \| 'http' \| 'both'` | Filter by visibility |

**Example:**

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const page = await registry.listSkills({
  offset: 0,
  limit: 20,
});

console.log(`Total: ${page.total}`);
console.log(`Skills: ${page.items.length}`);
```

### count()

Get total skill count.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
count(options?: CountOptions): Promise<number>
```

### findByName()

Find a skill by its base name.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
findByName(name: string): SkillEntry | undefined
```

### findByQualifiedName()

Find a skill by its fully qualified name.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
findByQualifiedName(qualifiedName: string): SkillEntry | undefined
```

### getInlineSkills()

Get skills defined inline (local only).

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
getInlineSkills(): ReadonlyArray<SkillEntry>
```

### validateAllTools()

Validate all skills' tool references against the ToolRegistry.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
validateAllTools(): ValidationResult
```

**Example:**

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const result = registry.validateAllTools();
if (!result.valid) {
  for (const error of result.errors) {
    console.error(`${error.skill}: Missing tool ${error.tool}`);
  }
}
```

### subscribe()

Subscribe to skill change events.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
subscribe(
  opts: SubscribeOptions,
  cb: (event: SkillChangeEvent) => void
): () => void
```

**Returns:** Unsubscribe function.

### getCapabilities()

Get MCP capabilities for skills.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
getCapabilities(): { listChanged: boolean }
```

### hasAny()

Check if any skills exist.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
hasAny(): boolean
```

### adoptFromChild()

Adopt skills from a child registry.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
adoptFromChild(child: SkillRegistry, childOwner: Owner): void
```

## External Storage

Skills can be synced to external storage for persistence:

### setExternalProvider()

Configure an external storage provider.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
setExternalProvider(provider: ExternalSkillProviderBase): void
```

### syncToExternal()

Sync local skills to external storage.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
syncToExternal(): Promise<SyncResult>
```

**Example:**

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// Configure Redis-based storage
registry.setExternalProvider(new RedisSkillProvider(redisClient));

// Sync skills
const result = await registry.syncToExternal();
console.log(`Synced ${result.count} skills`);
```

### hasExternalProvider()

Check if external provider is configured.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
hasExternalProvider(): boolean
```

### getExternalProvider()

Get the configured external provider.

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
getExternalProvider(): ExternalSkillProviderBase | undefined
```

## Change Events

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
interface SkillChangeEvent {
  kind: 'added' | 'updated' | 'removed' | 'reset';
  changeScope: 'global' | 'session';
  version: number;
  snapshot: ReadonlyArray<SkillEntry>;
  entry?: SkillEntry;
  sessionId?: string;
  relatedRequestId?: string;
}
```

## SkillEntry Accessors

Each skill in the registry is a `SkillEntry` with these accessor methods:

| Method               | Return Type                           | Description                                 |
| -------------------- | ------------------------------------- | ------------------------------------------- |
| `getDescription()`   | `string`                              | Skill description                           |
| `getToolRefs()`      | `SkillToolRef[]`                      | Normalized tool references                  |
| `getToolNames()`     | `string[]`                            | Tool name strings                           |
| `getTags()`          | `string[]`                            | Categorization tags                         |
| `getPriority()`      | `number`                              | Search ranking priority                     |
| `isHidden()`         | `boolean`                             | Whether hidden from discovery               |
| `getLicense()`       | `string \| undefined`                 | License (per Agent Skills spec)             |
| `getCompatibility()` | `string \| undefined`                 | Compatibility notes (per Agent Skills spec) |
| `getSpecMetadata()`  | `Record<string, string> \| undefined` | Arbitrary metadata (per Agent Skills spec)  |
| `getAllowedTools()`  | `string \| undefined`                 | Pre-approved tools (per Agent Skills spec)  |
| `getResources()`     | `SkillResources \| undefined`         | Bundled resource directories                |

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
const skill = registry.findByName('review-pr');
if (skill) {
  console.log(skill.getLicense());       // 'MIT'
  console.log(skill.getCompatibility()); // 'Requires git CLI'
  console.log(skill.getResources());     // { scripts: '...', references: '...' }
}
```

## Skill Visibility

Skills can have different visibility modes:

| Visibility | Description                     |
| ---------- | ------------------------------- |
| `mcp`      | Available only via MCP protocol |
| `http`     | Available only via HTTP API     |
| `both`     | Available via both MCP and HTTP |

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@Skill({
  name: 'internal-task',
  visibility: 'mcp', // Only for MCP clients
})
class InternalTask extends SkillContext { }

@Skill({
  name: 'public-api',
  visibility: 'http', // Only for HTTP clients
})
class PublicAPI extends SkillContext { }
```

## Tool Validation

Skills can reference tools that must exist in the registry:

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@Skill({
  name: 'data-pipeline',
  tools: ['fetch_data', 'transform', 'save_results'],
})
class DataPipeline extends SkillContext { }
```

Validation modes:

* **strict**: Fail if any tool is missing
* **warn**: Log warning for missing tools
* **ignore**: Skip validation

## Related

* [Skill Decorator](/frontmcp/sdk-reference/decorators/skill)
* [SkillContext](/frontmcp/sdk-reference/contexts/skill-context)
* [Registries Overview](/frontmcp/sdk-reference/registries/overview)
