# API Reference
Complete reference for all hooks, components, and utilities in `@mcp-fe/react-tools`.
## Hooks
### `useMCPTool(options)`
Main hook for registering MCP tools with automatic lifecycle management.
#### Parameters
```typescript
interface UseMCPToolOptions {
name: string; // Unique tool name (required)
description?: string; // Description for AI (optional)
inputSchema: object; // JSON Schema for inputs (required)
outputSchema?: object; // JSON Schema for outputs (optional)
handler: ToolHandler; // Handler function (required)
// Meta information (optional)
annotations?: {
title?: string; // Human-readable title
readOnlyHint?: boolean; // Tool only reads data
destructiveHint?: boolean; // Performs destructive actions
idempotentHint?: boolean; // Multiple calls have same effect
openWorldHint?: boolean; // May access external systems
};
execution?: {
taskSupport?: 'optional' | 'required' | 'forbidden'; // Task-based execution support
};
_meta?: Record<string, unknown>; // Custom metadata
icons?: Array<{ // Tool icons
src: string;
mimeType?: string;
sizes?: string[];
theme?: 'light' | 'dark';
}>;
title?: string; // Display title
autoRegister?: boolean; // Auto-register on mount (default: true)
autoUnregister?: boolean; // Auto-unregister on unmount (default: true)
}
```
#### Returns
```typescript
interface UseMCPToolResult {
isRegistered: boolean; // Is tool currently registered?
register: () => Promise<void>; // Manual registration
unregister: () => Promise<void>; // Manual unregistration
refCount: number; // Number of components using this tool
}
```
#### Example
```tsx
const { isRegistered, refCount } = useMCPTool({
name: 'my_tool',
description: 'My custom tool',
inputSchema: {
type: 'object',
properties: {
param: { type: 'string' }
},
required: ['param']
},
outputSchema: {
type: 'object',
properties: {
result: { type: 'string' }
}
},
handler: async (args: { param: string }) => {
// Your logic here
return {
content: [{
type: 'text',
text: `Result: ${args.param}`
}]
};
},
// Optional meta information
annotations: {
title: 'My Custom Tool',
readOnlyHint: true, // This tool only reads data
idempotentHint: true // Safe to call multiple times
},
icons: [{
src: '/icons/my-tool.svg',
theme: 'light'
}]
});
```
#### Example: Destructive Action with Hints
```tsx
useMCPTool({
name: 'delete_user',
description: 'Delete a user account permanently',
inputSchema: {
type: 'object',
properties: {
userId: { type: 'string' }
},
required: ['userId']
},
handler: async (args) => {
await api.deleteUser(args.userId);
return {
content: [{
type: 'text',
text: `User ${args.userId} deleted`
}]
};
},
annotations: {
destructiveHint: true, // Warns AI about destructive action
idempotentHint: false // Can't safely retry
}
});
```
#### Structured Output
When `outputSchema` is defined, return JSON string in text format. MCPController automatically adds `structuredContent`:
```tsx
// ✅ Correct - with outputSchema
useMCPTool({
name: 'get_user',
outputSchema: {
type: 'object',
properties: {
id: { type: 'string' },
name: { type: 'string' }
}
},
handler: async () => {
const data = { id: '123', name: 'John' };
// Return as JSON string
return {
content: [{
type: 'text',
text: JSON.stringify(data)
}]
};
}
});
// AI receives both versions:
// {
// content: [{ type: 'text', text: '{"id":"123","name":"John"}' }],
// structuredContent: { id: '123', name: 'John' }
// }
// ❌ Legacy - without outputSchema
useMCPTool({
name: 'get_data',
handler: async () => ({
content: [{
type: 'text',
text: JSON.stringify({ value: 42 })
}]
})
});
// AI receives only: { content: [...] }
```
---
### `useMCPGetter(name, description, getter)`
Simplified hook for getter tools (no inputs required).
#### Parameters
```typescript
useMCPGetter(
name: string, // Tool name
description: string, // Tool description
getter: () => any // Function that returns data
)
```
#### Returns
Same as `useMCPTool`.
#### Example
```tsx
function UserProfile() {
const user = useUser();
useMCPGetter(
'get_user_profile',
'Get current user profile',
() => ({
userId: user.id,
name: user.name
})
);
}
```
---
### `useMCPAction(name, description, properties, action)`
Hook for action tools that accept inputs and perform operations.
#### Parameters
```typescript
useMCPAction(
name: string, // Tool name
description: string, // Tool description
properties: Record<string, any>, // JSON Schema properties
action: (args: any) => Promise<any> // Action handler
)
```
#### Returns
Same as `useMCPTool`.
#### Example
```tsx
function TodoManager() {
const [todos, setTodos] = useState([]);
useMCPAction(
'add_todo',
'Add a new todo',
{
text: { type: 'string', description: 'Todo text' },
priority: { type: 'number', default: 0 }
},
async (args: { text: string; priority: number }) => {
const newTodo = {
id: Date.now(),
text: args.text,
priority: args.priority
};
setTodos([...todos, newTodo]);
return { success: true, todo: newTodo };
}
);
}
```
---
## Context API
### `MCPToolsProvider`
Provider component for centralized management and monitoring of MCP tools.
#### Props
```typescript
interface MCPToolsProviderProps {
children: React.ReactNode;
autoInit?: boolean; // Auto-initialize on mount (default: true)
backendWsUrl?: string; // Backend WebSocket URL (default: 'ws://localhost:3001')
authToken?: string | null; // Authentication token for MCP server
initOptions?: WorkerClientInitOptions; // Custom initialization options
onInitialized?: () => void; // Callback when initialized
onInitError?: (error: Error) => void; // Callback on init error
}
```
#### Example
```tsx
function App() {
return (
<MCPToolsProvider
backendWsUrl="ws://localhost:3001"
authToken="your-auth-token"
onInitialized={() => console.log('MCP Tools ready!')}
onInitError={(err) => console.error('Init failed:', err)}
>
<YourApp />
</MCPToolsProvider>
);
}
```
#### Example: With Dynamic Auth Token
```tsx
function App() {
const [token, setToken] = useState<string>();
useEffect(() => {
// Token automatically updates when state changes
authService.getToken().then(setToken);
}, []);
return (
<MCPToolsProvider
backendWsUrl="ws://localhost:3001"
authToken={token}
>
<YourApp />
</MCPToolsProvider>
);
}
```
#### Example: Manual Initialization
```tsx
function App() {
return (
<MCPToolsProvider autoInit={false}>
<YourApp />
</MCPToolsProvider>
);
}
function YourApp() {
const { initialize } = useMCPToolsContext();
return (
<button onClick={() => initialize({ backendWsUrl: 'ws://localhost:3001' })}>
Initialize MCP
</button>
);
}
```
---
### `useMCPToolsContext(strict?)`
Hook to access MCP Tools context state and methods.
#### Parameters
```typescript
useMCPToolsContext(strict?: boolean) // default: false
```
If `strict` is `true`, throws an error when used outside `MCPToolsProvider`.
#### Returns
```typescript
interface MCPToolsContextValue {
isInitialized: boolean; // Whether worker client is initialized
isConnected: boolean; // Whether connected to MCP server
registeredTools: string[]; // List of currently registered tool names
initialize: (options?: WorkerClientInitOptions) => Promise<void>;
getConnectionStatus: () => Promise<boolean>;
}
```
#### Example
```tsx
function StatusBar() {
const { isConnected, registeredTools } = useMCPToolsContext();
return (
<div>
<p>Status: {isConnected ? '🟢 Connected' : '🔴 Disconnected'}</p>
<p>Active Tools: {registeredTools.length}</p>
</div>
);
}
```
---
### `useHasMCPProvider()`
Check if component is rendered within `MCPToolsProvider`.
#### Returns
```typescript
boolean // true if provider exists
```
#### Example
```tsx
function MyComponent() {
const hasProvider = useHasMCPProvider();
if (!hasProvider) {
console.log('Running in standalone mode');
}
return <div>Component</div>;
}
```
---
## Utility Functions
### `isToolRegistered(name)`
Check if a tool is currently registered.
#### Parameters
```typescript
isToolRegistered(name: string): boolean
```
#### Example
```tsx
import { isToolRegistered } from '@mcp-fe/react-tools';
if (isToolRegistered('my_tool')) {
console.log('Tool is registered');
}
```
---
### `getRegisteredTools()`
Get list of all registered tool names.
#### Returns
```typescript
string[] // Array of tool names
```
#### Example
```tsx
import { getRegisteredTools } from '@mcp-fe/react-tools';
const tools = getRegisteredTools();
console.log('Registered tools:', tools);
// Output: ['get_user_profile', 'add_todo', 'search_users']
```
---
### `getToolInfo(name)`
Get basic registration information about a specific tool.
#### Parameters
```typescript
getToolInfo(name: string): ToolInfo | null
```
#### Returns
```typescript
interface ToolInfo {
refCount: number; // Number of active references
isRegistered: boolean; // Registration status
}
```
#### Example
```tsx
import { getToolInfo } from '@mcp-fe/react-tools';
const info = getToolInfo('my_tool');
if (info) {
console.log(`Tool is used by ${info.refCount} component(s)`);
console.log(`Is registered: ${info.isRegistered}`);
}
```
---
### `getToolDetails(name)`
Get complete tool definition including description, schema, annotations, and metadata.
#### Parameters
```typescript
getToolDetails(name: string): ToolDetails | null
```
#### Returns
```typescript
interface ToolDetails extends ToolDefinition {
refCount: number; // Number of active references
isRegistered: boolean; // Registration status
}
// ToolDefinition includes:
// - name: string
// - description?: string
// - inputSchema: Record<string, unknown>
// - outputSchema?: Record<string, unknown>
// - annotations?: { readOnlyHint?, destructiveHint?, ... }
// - execution?: { taskSupport?: 'optional' | 'required' | 'forbidden' }
// - icons?: Array<{ src, mimeType?, ... }>
// - title?: string
// - _meta?: Record<string, unknown>
```
#### Example
```tsx
import { getToolDetails } from '@mcp-fe/react-tools';
const details = getToolDetails('my_tool');
if (details) {
console.log('Name:', details.name);
console.log('Description:', details.description);
console.log('Ref count:', details.refCount);
console.log('Input schema:', details.inputSchema);
console.log('Is read-only:', details.annotations?.readOnlyHint);
console.log('Icons:', details.icons);
}
```
#### Example: Building Tool Monitor
```tsx
import { getRegisteredTools, getToolDetails } from '@mcp-fe/react-tools';
function ToolMonitor() {
const tools = getRegisteredTools();
return (
<div>
<h3>Active Tools: {tools.length}</h3>
<ul>
{tools.map(name => {
const details = getToolDetails(name);
return (
<li key={name}>
<strong>{name}</strong> - {details?.description}
<br />
<small>Refs: {details?.refCount}</small>
</li>
);
})}
</ul>
</div>
);
}
```
---
## Types
### `ToolHandler`
```typescript
type ToolHandler = (args: any) => Promise<ToolCallResult>;
interface ToolCallResult {
content: Array<{
type: 'text' | 'image' | 'resource';
text?: string;
data?: string;
mimeType?: string;
// ... other content types
}>;
isError?: boolean;
}
```
### `WorkerClientInitOptions`
```typescript
interface WorkerClientInitOptions {
backendWsUrl?: string;
workerType?: 'service' | 'shared';
workerUrl?: string;
// ... other options
}
```
---
## Next Steps
- **[Guides](./guides.md)** - Learn advanced usage patterns
- **[Examples](./examples.md)** - See real-world implementations
- **[Architecture](./architecture.md)** - Understand how it works internally