---
title: "ToolRegistry"
description: "The ToolRegistry manages all MCP tools within a scope. It provides methods for listing, finding, and subscribing to tool changes."
icon: "wrench"
keywords: ['frontmcp', 'mcp', 'model context protocol', 'sdk', 'reference', 'api', 'registry', 'registries', 'tool', 'typescript']
---

## Overview

```typescript
import { ToolRegistry } from '@frontmcp/sdk';

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

// List all tools
const allTools = tools.getTools();

// Look up a tool by its exported (resolved) name
const tool = tools.getExported('my_tool');
```

## Methods

### getTools()

Get all tools (local + adopted).

```typescript
getTools(includeHidden?: boolean): ReadonlyArray<ToolEntry>
```

| Parameter       | Type      | Default | Description                     |
| --------------- | --------- | ------- | ------------------------------- |
| `includeHidden` | `boolean` | `false` | Include hidden tools in results |

**Example:**

```typescript
// Get all visible tools
const tools = registry.getTools();

// Include hidden tools
const allTools = registry.getTools(true);
```

### getToolsForListing()

Get tools appropriate for MCP listing with elicitation support filtering.

```typescript
getToolsForListing(supportsElicitation?: boolean): ReadonlyArray<ToolEntry>
```

| Parameter             | Type      | Default | Description                         |
| --------------------- | --------- | ------- | ----------------------------------- |
| `supportsElicitation` | `boolean` | `false` | Whether client supports elicitation |

**Example:**

```typescript
// For clients that support elicitation
const tools = registry.getToolsForListing(true);

// For clients that don't support elicitation
const tools = registry.getToolsForListing(false);
```

### getExported()

Lookup a tool by its exported (resolved) name.

```typescript
getExported(name: string, opts?: { ignoreCase?: boolean }): ToolEntry | undefined
```

**Example:**

```typescript
// Case-sensitive lookup
const tool = registry.getExported('Search_Tool');

// Case-insensitive lookup
const tool = registry.getExported('search_tool', { ignoreCase: true });
```

### exportResolvedNames()

Produce unique, conflict-aware exported names for all tools.

```typescript
exportResolvedNames(opts?: ExportNameOptions): Array<{ name: string; instance: ToolEntry }>
```

**Example:**

```typescript
const exportedNames = registry.exportResolvedNames();
for (const { name, instance } of exportedNames) {
  console.log(`${name} → ${instance.qualifiedId}`);
}
// Output:
// search → app1:search
// app2_search → app2:search (conflict resolved with prefix)
```

### getInlineTools()

Get tools defined inline in this registry (local only, not adopted).

```typescript
getInlineTools(): ReadonlyArray<ToolEntry>
```

### listAllInstances()

List all tool instances (locals + adopted).

```typescript
listAllInstances(): ReadonlyArray<ToolEntry>
```

### listByOwner()

List tools by owner path.

```typescript
listByOwner(ownerPath: string): ReadonlyArray<ToolEntry>
```

**Example:**

```typescript
// Get all tools owned by 'my-app'
const appTools = registry.listByOwner('my-app');
```

### registerToolInstance()

Register a pre-constructed ToolInstance directly.

```typescript
registerToolInstance(tool: ToolEntry): void
```

<Note>
This is typically used internally for agent-scoped or remote tools.
</Note>

### subscribe()

Subscribe to tool change events.

```typescript
subscribe(
  opts: { immediate?: boolean; filter?: (i: ToolEntry) => boolean },
  cb: (event: ToolChangeEvent) => void
): () => void
```

**Returns:** Unsubscribe function.

**Example:**

```typescript
const unsubscribe = registry.subscribe({}, (event) => {
  console.log(`Tool change: ${event.kind} (v${event.version})`);
});

// Later: stop listening
unsubscribe();
```

### getCapabilities()

Get MCP capabilities for tools.

```typescript
getCapabilities(): Partial<ServerCapabilities>
```

**Example:**

```typescript
const caps = registry.getCapabilities();
// { tools: { listChanged: true } }
```

### hasAny()

Check if any tools exist in the registry.

```typescript
hasAny(): boolean
```

### adoptFromChild()

Adopt tools from a child registry.

```typescript
adoptFromChild(child: ToolRegistry, _childOwner: EntryOwnerRef): void
```

<Note>
References are shared (not cloned). Changes in the child registry automatically propagate to the parent.
</Note>

## Change Events

The registry emits events when tools are added, updated, or removed:

```typescript
interface ToolChangeEvent {
  kind: 'added' | 'updated' | 'removed' | 'reset';
  changeScope: 'global' | 'session';
  version: number;
  snapshot: ReadonlyArray<ToolEntry>;
  sessionId?: string;
  relatedRequestId?: string;
}
```

## Indexes

The registry maintains O(1) lookup indexes:

| Index               | Key             | Description                            |
| ------------------- | --------------- | -------------------------------------- |
| `byQualifiedId`     | `qualifiedId`   | Unique identifier lookup               |
| `byName`            | `name`          | Base name lookup (may return multiple) |
| `byOwnerAndName`    | `owner:name`    | Scoped name lookup                     |
| `byProviderAndName` | `provider:name` | Provider-scoped lookup                 |
| `byOwner`           | `ownerPath`     | All tools by owner                     |

## Related

- [Tool Decorator](/frontmcp/sdk-reference/decorators/tool)
- [ToolContext](/frontmcp/sdk-reference/contexts/tool-context)
- [Registries Overview](/frontmcp/sdk-reference/registries/overview)
