Custom Tool Development for LLM-MCP
This comprehensive guide covers the process of developing, testing, and deploying custom tools for the LLM Platform Model Context Protocol (LLM-MCP). Custom tools extend the platform's capabilities by providing specialized functionality that can be orchestrated through the LLM-MCP server.
Table of Contentsโ
- Introduction
- Tool Architecture
- Tool Development Lifecycle
- Creating a Basic Tool
- Advanced Tool Development
- Tool Testing
- Tool Registration
- Tool Deployment
- Tool Versioning
- Best Practices
- Troubleshooting
- Examples
Introductionโ
What are LLM-MCP Tools?โ
LLM-MCP tools are modular, reusable components that provide specific functionality that can be invoked by AI models or other services. Tools can perform a wide range of actions, from simple data retrieval to complex data processing and external API interactions.
Types of Toolsโ
- System Tools: Core tools provided by LLM-MCP for basic operations
- Integration Tools: Tools that integrate with other services
- Custom Tools: User-developed tools for specialized functionality
- Composite Tools: Tools that combine multiple tools into workflows
Tool Capabilitiesโ
LLM-MCP tools can:
- Access external APIs and services
- Process and transform data
- Interact with databases and vector stores
- Execute code in controlled environments
- Provide UI interactions
- Implement complex business logic
Tool Architectureโ
Tool Component Structureโ
graph TD;
A[Tool Definition] --> B[Tool Schema];
A --> C[Tool Handler];
A --> D[Tool Configuration];
B --> E[Input Schema];
B --> F[Output Schema];
C --> G[Execute Method];
C --> H[Validation Logic];
D --> I[Default Parameters];
D --> J[Resource Limits];
Core Componentsโ
- Tool Definition: Metadata about the tool
- Tool Schema: Definition of inputs and outputs
- Tool Handler: Implementation of tool functionality
- Tool Configuration: Settings and parameters
Tool Interfaceโ
All tools must implement the McpTool
interface:
interface McpTool {
name: string;
description: string;
version: string;
schema: ToolSchema;
execute(params: any): Promise<any>;
validate?(params: any): boolean | Promise<boolean>;
}
interface ToolSchema {
input: JSONSchema;
output: JSONSchema;
}
Tool Development Lifecycleโ
The typical development lifecycle for a custom LLM-MCP tool includes:
- Planning: Define the tool's purpose and capabilities
- Development: Implement the tool functionality
- Testing: Unit and integration testing
- Registration: Register the tool with LLM-MCP
- Deployment: Deploy the tool in production
- Monitoring: Monitor tool usage and performance
- Updates: Update the tool as needed
Creating a Basic Toolโ
Step 1: Create Tool Definitionโ
Create a new file for your tool (e.g., my-custom-tool.ts
):
import { McpTool, ToolSchema } from '@llm-mcp/tool-sdk';
export class MyCustomTool implements McpTool {
name = 'my-custom-tool';
description = 'A custom tool that performs a specific function';
version = '1.0.0';
schema: ToolSchema = {
input: {
type: 'object',
properties: {
param1: {
type: 'string',
description: 'First parameter description'
},
param2: {
type: 'number',
description: 'Second parameter description'
}
},
required: ['param1']
},
output: {
type: 'object',
properties: {
result: {
type: 'string',
description: 'Result description'
}
}
}
};
async execute(params: any): Promise<any> {
// Implement your tool functionality here
const { param1, param2 = 0 } = params;
// Example processing
const result = `Processed [param1] with value [param2]`;
return [result];
}
validate(params: any): boolean {
// Optional validation beyond schema validation
if (params.param2 && params.param2 < 0) {
return false;
}
return true;
}
}
Step 2: Test Your Toolโ
Create a test file for your tool (e.g., my-custom-tool.test.ts
):
import [MyCustomTool] from './my-custom-tool';
describe('MyCustomTool', () => {
let tool: MyCustomTool;
beforeEach(() => {
tool = new MyCustomTool();
});
test('should have correct metadata', () => {
expect(tool.name).toBe('my-custom-tool');
expect(tool.version).toBe('1.0.0');
expect(tool.description).toBeDefined();
});
test('should have valid schema', () => {
expect(tool.schema.input).toBeDefined();
expect(tool.schema.output).toBeDefined();
});
test('should execute successfully with valid parameters', async () => {
const result = await tool.execute({ param1: 'test', param2: 5 });
expect(result).toHaveProperty('result');
expect(result.result).toContain('test');
expect(result.result).toContain('5');
});
test('should execute successfully with only required parameters', async () => {
const result = await tool.execute({ param1: 'test' });
expect(result).toHaveProperty('result');
});
test('validation should reject negative param2', () => {
expect(tool.validate({ param1: 'test', param2: -5 })).toBe(false);
expect(tool.validate({ param1: 'test', param2: 5 })).toBe(true);
});
});
Step 3: Register Your Toolโ
Register your tool with LLM-MCP:
import [McpClient] from '@llm-mcp/client';
import [MyCustomTool] from './my-custom-tool';
async function registerTool() {
const client = new McpClient({
url: 'http://localhost:3001',
apiKey: 'your-api-key'
});
const tool = new MyCustomTool();
try {
const registrationResult = await client.registerTool(tool);
console.log('Tool registered successfully:', registrationResult);
} catch (error) {
console.error('Failed to register tool:', error);
}
}
registerTool();
Advanced Tool Developmentโ
Using External Servicesโ
Tools often need to interact with external services:
import axios from 'axios';
import { McpTool, ToolSchema } from '@llm-mcp/tool-sdk';
export class WeatherTool implements McpTool {
name = 'weather-tool';
description = 'Get current weather for a location';
version = '1.0.0';
schema: ToolSchema = {
input: {
type: 'object',
properties: {
location: {
type: 'string',
description: 'City name or zip code'
}
},
required: ['location']
},
output: {
type: 'object',
properties: {
temperature: {
type: 'number',
description: 'Current temperature in Celsius'
},
conditions: {
type: 'string',
description: 'Weather conditions'
}
}
}
};
async execute(params: any): Promise<any> [const { location] = params;
try {
// Replace with your actual weather API
const response = await axios.get(
`https://api.weather.example.com/current?location=[encodeURIComponent(location)]`,
{
headers: {
'Authorization': `Bearer [process.env.WEATHER_API_KEY]`
}
}
);
return {
temperature: response.data.temperature,
conditions: response.data.conditions
};
} catch (error) {
throw new Error(`Failed to get weather data: [error.message]`);
}
}
}
Handling Authenticationโ
For tools that require authentication:
import { McpTool, ToolSchema, ToolAuth } from '@llm-mcp/tool-sdk';
export class AuthenticatedTool implements McpTool {
name = 'authenticated-tool';
description = 'Tool that requires authentication';
version = '1.0.0';
// Define authentication requirements
auth: ToolAuth = {
type: 'oauth2',
description: 'Authentication required for ExampleService',
scopes: ['read', 'write']
};
schema: ToolSchema = [// Schema definition...];
async execute(params: any, context: any): Promise<any> [// The context object contains authentication information
const { auth] = context;
if (!auth || !auth.token) {
throw new Error('Authentication required');
}
// Use auth.token for authenticated requests
// ...
return { result: 'Authenticated operation completed' };
}
}
Stateful Toolsโ
For tools that need to maintain state:
import { McpTool, ToolSchema } from '@llm-mcp/tool-sdk';
export class CounterTool implements McpTool {
name = 'counter-tool';
description = 'Maintains a counter state';
version = '1.0.0';
private counters: Map<string, number> = new Map();
schema: ToolSchema = {
input: {
type: 'object',
properties: {
counterId: {
type: 'string',
description: 'Unique counter ID'
},
operation: {
type: 'string',
enum: ['increment', 'decrement', 'reset', 'get'],
description: 'Operation to perform'
}
},
required: ['counterId', 'operation']
},
output: {
type: 'object',
properties: {
value: {
type: 'number',
description: 'Current counter value'
}
}
}
};
async execute(params: any): Promise<any> {
const { counterId, operation } = params;
if (!this.counters.has(counterId)) {
this.counters.set(counterId, 0);
}
let value = this.counters.get(counterId);
switch (operation) {
case 'increment':
value++;
break;
case 'decrement':
value--;
break;
case 'reset':
value = 0;
break;
case 'get':
// Just return current value
break;
default:
throw new Error(`Unknown operation: [operation]`);
}
this.counters.set(counterId, value);
return Value;
}
}
Vector Operationsโ
For tools that work with vector embeddings:
import { McpTool, ToolSchema } from '@llm-mcp/tool-sdk';
import [VectorService] from '@llm-mcp/vector-service';
export class VectorSearchTool implements McpTool {
name = 'vector-search-tool';
description = 'Search for similar vectors';
version = '1.0.0';
private vectorService: VectorService;
constructor() {
this.vectorService = new VectorService({
// Vector service configuration
});
}
schema: ToolSchema = {
input: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'Query text to search for'
},
collection: {
type: 'string',
description: 'Vector collection name'
},
limit: {
type: 'number',
description: 'Maximum number of results',
default: 5
}
},
required: ['query', 'collection']
},
output: {
type: 'object',
properties: {
results: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'string' },
score: { type: 'number' },
metadata: { type: 'object' }
}
},
description: 'Search results'
}
}
}
};
async execute(params: any): Promise<any> {
const { query, collection, limit = 5 } = params;
// Get vector embedding for the query
const embedding = await this.vectorService.getEmbedding(query);
// Search for similar vectors
const results = await this.vectorService.search({
collection,
vector: embedding,
limit
});
return [results];
}
}
Tool Testingโ
Unit Testingโ
Basic unit testing for tools:
import [MyCustomTool] from './my-custom-tool';
import [mockExternalService] from './test-utils';
// Mock external dependencies
jest.mock('axios');
describe('MyCustomTool', () => {
let tool: MyCustomTool;
beforeEach(() => {
tool = new MyCustomTool();
mockExternalService();
});
// Test cases...
});
Integration Testingโ
Testing tool integration with LLM-MCP:
import [McpClient] from '@llm-mcp/client';
import [MyCustomTool] from './my-custom-tool';
describe('MyCustomTool Integration', () => {
let client: McpClient;
let tool: MyCustomTool;
beforeAll(async () => {
// Set up a test LLM-MCP instance
client = new McpClient({
url: 'http://localhost:3001',
apiKey: 'test-api-key'
});
tool = new MyCustomTool();
// Register tool for testing
await client.registerTool(tool);
});
test('should execute tool through MCP', async () => {
const result = await client.executeTool('my-custom-tool', {
param1: 'test',
param2: 5
});
expect(result).toHaveProperty('result');
expect(result.result).toContain('test');
});
afterAll(async () => {
// Clean up
await client.unregisterTool('my-custom-tool');
});
});
Performance Testingโ
Testing tool performance:
import [MyCustomTool] from './my-custom-tool';
describe('MyCustomTool Performance', () => {
let tool: MyCustomTool;
beforeEach(() => {
tool = new MyCustomTool();
});
test('should execute within time limit', async () => {
const start = Date.now();
await tool.execute({ param1: 'test', param2: 5 });
const duration = Date.now() - start;
expect(duration).toBeLessThan(100); // Should execute in less than 100ms
});
test('should handle concurrent executions', async () => {
const executions = Array(100).fill(null).map((_, i) =>
tool.execute({ param1: `test-[i]`, param2: i })
);
const results = await Promise.all(executions);
expect(results.length).toBe(100);
results.forEach((result, i) => {
expect(result.result).toContain(`test-[i]`);
});
});
});
Tool Registrationโ
Automatic Registrationโ
Register tools automatically at startup:
import [McpClient] from '@llm-mcp/client';
import [ToolA] from './tools/tool-a';
import [ToolB] from './tools/tool-b';
import [ToolC] from './tools/tool-c';
async function registerTools() {
const client = new McpClient({
url: process.env.LLM-MCP_URL,
apiKey: process.env.LLM-MCP_API_KEY
});
const tools = [
new ToolA(),
new ToolB(),
new ToolC()
];
for (const tool of tools) {
try {
await client.registerTool(tool);
console.log(`Registered tool: [tool.name]`);
} catch (error) {
console.error(`Failed to register tool [tool.name]:`, error);
}
}
}
registerTools();
Dynamic Tool Registrationโ
Register tools dynamically based on configuration:
import [McpClient] from '@llm-mcp/client';
import * as fs from 'fs';
import * as path from 'path';
async function loadAndRegisterTools() {
const client = new McpClient({
url: process.env.LLM-MCP_URL,
apiKey: process.env.LLM-MCP_API_KEY
});
// Load tool configuration
const config = JSON.parse(
fs.readFileSync(path.join(__dirname, 'tool-config.json'), 'utf8')
);
for (const toolConfig of config.tools) {
if (!toolConfig.enabled) continue;
try {
// Dynamically import tool module
const ToolClass = require(`./tools/[toolConfig.file]`).default;
const tool = new ToolClass(toolConfig.options);
await client.registerTool(tool);
console.log(`Registered tool: [tool.name]`);
} catch (error) {
console.error(`Failed to register tool [toolConfig.name]:`, error);
}
}
}
loadAndRegisterTools();
Tool Deploymentโ
Standalone Tool Serviceโ
Deploy tools as a standalone service:
import express from 'express';
import [McpClient] from '@llm-mcp/client';
import [ToolA] from './tools/tool-a';
import [ToolB] from './tools/tool-b';
async function startToolService() {
const app = express();
const port = process.env.PORT || 3000;
const client = new McpClient({
url: process.env.LLM-MCP_URL,
apiKey: process.env.LLM-MCP_API_KEY
});
const tools = [
new ToolA(),
new ToolB()
];
// Register all tools
for (const tool of tools) {
await client.registerTool(tool);
console.log(`Registered tool: [tool.name]`);
}
// Health check endpoint
app.get('/health', (req, res) => {
res.status(200).json({ status: 'ok' });
});
// Start server
app.listen(port, () => {
console.log(`Tool service running on port 3000`);
});
// Handle graceful shutdown
process.on('SIGTERM', async () => {
console.log('Shutting down...');
for (const tool of tools) {
await client.unregisterTool(tool.name);
console.log(`Unregistered tool: [tool.name]`);
}
process.exit(0);
});
}
startToolService();
Container Deploymentโ
Docker configuration for tool deployment:
FROM node:18-alpine
WORKDIR /app
# Copy package files
COPY package*.json ./
RUN npm ci --only=production
# Copy application code
COPY . .
# Set environment variables
ENV NODE_ENV=production
ENV LLM-MCP_URL=http://llm-mcp:3001
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
# Start the service
CMD ["node", "src/index.js"]
Kubernetes Deploymentโ
Kubernetes configuration for tool deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: custom-tools
labels:
app: custom-tools
spec:
replicas: 2
selector:
matchLabels:
app: custom-tools
template:
metadata:
labels:
app: custom-tools
spec:
containers:
- name: custom-tools
image: your-registry/custom-tools:latest
ports:
- containerPort: 3000
env:
- name: LLM-MCP_URL
value: "http://llm-mcp-service:3001"
- name: LLM-MCP_API_KEY
valueFrom:
secretKeyRef:
name: llm-mcp-credentials
key: api-key
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "100m"
memory: "128Mi"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
Tool Versioningโ
Versioning Strategyโ
Implement proper versioning for your tools:
import { McpTool, ToolSchema } from '@llm-mcp/tool-sdk';
export class VersionedTool implements McpTool {
name = 'versioned-tool';
description = 'Tool with proper versioning';
version = '2.0.0'; // Major version change indicates breaking changes
// Support previous version
aliases = ['versioned-tool@1']; // Allow explicit version reference
schema: ToolSchema = {
// Current schema version
input: {
type: 'object',
properties: {
newParam: { type: 'string' } // New parameter in v2
}
},
output: {
type: 'object',
properties: {
result: { type: 'string' }
}
}
};
// Schema for v1 compatibility
legacySchemas = {
'1': {
input: {
type: 'object',
properties: {
oldParam: { type: 'string' } // Old parameter in v1
}
},
output: {
type: 'object',
properties: {
result: { type: 'string' }
}
}
}
};
async execute(params: any, context: any): Promise<any> {
// Check if using legacy version
const requestedVersion = context.requestedVersion || this.version;
if (requestedVersion.startsWith('1.')) {
// Handle v1 request format
const { oldParam } = params;
return { result: `Legacy result with [oldParam]` };
}
// Handle current version
const [newParam] = params;
return { result: `New result with [newParam]` };
}
}
Version Migrationโ
Guide for migrating between tool versions:
- Add version compatibility: Support older versions while introducing new ones
- Deprecation notices: Clearly mark deprecated versions
- Migration guide: Provide clear documentation for migration
- Testing: Test all supported versions
Best Practicesโ
Development Best Practicesโ
- Clear purpose: Each tool should have a single, well-defined purpose
- Input validation: Validate all inputs thoroughly
- Error handling: Handle errors gracefully and provide clear error messages
- Documentation: Document the tool's purpose, inputs, outputs, and behavior
- Testing: Write comprehensive tests for your tools
- Performance: Optimize for performance, especially for frequently used tools
- Security: Follow security best practices, especially for tools that access external services
- Statelessness: Prefer stateless tools when possible for easier scaling
- Idempotency: Ensure operations are idempotent when appropriate
- Versioning: Use semantic versioning for your tools
Security Best Practicesโ
- Input sanitization: Sanitize all inputs to prevent injection attacks
- Credential management: Never hardcode credentials
- Principle of least privilege: Request only the permissions you need
- Resource limits: Implement resource limits to prevent abuse
- Secure dependencies: Keep dependencies updated and scan for vulnerabilities
Performance Best Practicesโ
- Minimize external calls: Reduce the number of external API calls
- Implement caching: Cache results when appropriate
- Connection pooling: Use connection pooling for database connections
- Asynchronous operations: Use asynchronous operations for I/O-bound tasks
- Resource cleanup: Properly close connections and free resources
Troubleshootingโ
Common Issuesโ
-
Tool registration fails:
- Check that the tool implements the
McpTool
interface correctly - Verify that the tool name is unique
- Check for network connectivity issues
- Check that the tool implements the
-
Tool execution fails:
- Check input validation
- Verify external service availability
- Check for permission issues
-
Performance issues:
- Look for blocking operations
- Check for memory leaks
- Monitor external service performance
Debugging Toolsโ
import { McpTool, ToolSchema } from '@llm-mcp/tool-sdk';
import * as fs from 'fs';
export class DebugTool implements McpTool {
name = 'debug-tool';
description = 'Tool for debugging purposes';
version = '1.0.0';
schema: ToolSchema = {
// Schema definition...
};
async execute(params: any, context: any): Promise<any> {
// Log execution details for debugging
const debugInfo = {
timestamp: new Date().toISOString(),
params,
context,
environment: process.env
};
// Write to debug log
fs.appendFileSync(
'debug-logs.json',
JSON.stringify(debugInfo, null, 2) + ',\n'
);
// Continue with normal execution
// ...
return { result: 'Debug information logged' };
}
}
Examplesโ
Web API Integration Toolโ
import { McpTool, ToolSchema } from '@llm-mcp/tool-sdk';
import axios from 'axios';
export class WeatherApiTool implements McpTool {
name = 'weather-api-tool';
description = 'Get weather information for a location';
version = '1.0.0';
schema: ToolSchema = {
input: {
type: 'object',
properties: {
location: {
type: 'string',
description: 'City name or zip code'
},
units: {
type: 'string',
enum: ['metric', 'imperial'],
default: 'metric',
description: 'Units for temperature (metric = Celsius, imperial = Fahrenheit)'
}
},
required: ['location']
},
output: {
type: 'object',
properties: {
temperature: {
type: 'number',
description: 'Current temperature'
},
conditions: {
type: 'string',
description: 'Weather conditions'
},
humidity: {
type: 'number',
description: 'Humidity percentage'
},
windSpeed: {
type: 'number',
description: 'Wind speed'
}
}
}
};
async execute(params: any): Promise<any> {
const { location, units = 'metric' } = params;
try {
const response = await axios.get(
'https://api.weather.example.com/current',
{
params: {
location,
units
},
headers: {
'Authorization': `Bearer [process.env.WEATHER_API_KEY]`
}
}
);
return {
temperature: response.data.current.temperature,
conditions: response.data.current.conditions,
humidity: response.data.current.humidity,
windSpeed: response.data.current.wind_speed
};
} catch (error) {
throw new Error(`Weather API error: [error.message]`);
}
}
}
Database Integration Toolโ
import { McpTool, ToolSchema } from '@llm-mcp/tool-sdk';
import [Pool] from 'pg';
export class DatabaseQueryTool implements McpTool {
name = 'database-query-tool';
description = 'Execute predefined database queries';
version = '1.0.0';
private pool: Pool;
constructor() {
this.pool = new Pool({
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT || '5432'),
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
max: 20 // Connection pool size
});
}
schema: ToolSchema = {
input: {
type: 'object',
properties: {
queryType: {
type: 'string',
enum: ['getUser', 'getProducts', 'getOrders'],
description: 'Type of predefined query to execute'
},
parameters: {
type: 'object',
description: 'Query parameters'
}
},
required: ['queryType']
},
output: {
type: 'object',
properties: {
results: {
type: 'array',
items: {
type: 'object'
},
description: 'Query results'
},
count: {
type: 'number',
description: 'Number of results'
}
}
}
};
async execute(params: any): Promise<any> {
const { queryType, parameters = {} } = params;
// Define allowed queries
const queries = {
getUser: {
text: 'SELECT id, name, email FROM users WHERE id = $1',
values: [parameters.userId]
},
getProducts: {
text: 'SELECT id, name, price FROM products WHERE category = $1 LIMIT $2',
values: [parameters.category, parameters.limit || 10]
},
getOrders: {
text: 'SELECT id, customer_id, total FROM orders WHERE customer_id = $1',
values: [parameters.customerId]
}
};
if (!queries[queryType]) {
throw new Error(`Unknown query type: [queryType]`);
}
try {
const result = await this.pool.query(queries[queryType]);
return {
results: result.rows,
count: result.rowCount
};
} catch (error) {
throw new Error(`Database query error: [error.message]`);
}
}
}
File Operation Toolโ
import { McpTool, ToolSchema } from '@llm-mcp/tool-sdk';
import * as fs from 'fs';
import * as path from 'path';
export class FileOperationTool implements McpTool {
name = 'file-operation-tool';
description = 'Perform file operations in a designated directory';
version = '1.0.0';
// Base directory for file operations (configurable via environment)
private baseDir: string;
constructor() {
this.baseDir = process.env.FILE_OPERATIONS_DIR || '/tmp/file-operations';
// Ensure base directory exists
if (!fs.existsSync(this.baseDir)) {
fs.mkdirSync(this.baseDir, { recursive: true });
}
}
schema: ToolSchema = {
input: {
type: 'object',
properties: {
operation: {
type: 'string',
enum: ['read', 'write', 'list', 'delete'],
description: 'File operation to perform'
},
filename: {
type: 'string',
description: 'Name of the file (relative to base directory)'
},
content: {
type: 'string',
description: 'Content to write (for write operation)'
}
},
required: ['operation']
},
output: {
type: 'object',
properties: {
success: {
type: 'boolean',
description: 'Operation success status'
},
data: {
type: 'string',
description: 'File content (for read operation) or operation result'
},
files: {
type: 'array',
items: {
type: 'string'
},
description: 'List of files (for list operation)'
}
}
}
};
validate(params: any): boolean {
const { operation, filename } = params;
// All operations except 'list' require a filename
if (operation !== 'list' && !filename) {
return false;
}
// Write operation requires content
if (operation === 'write' && !params.content) {
return false;
}
// Prevent path traversal attacks
if (filename && (
filename.includes('..') ||
filename.startsWith('/') ||
filename.includes('\\')
)) {
return false;
}
return true;
}
async execute(params: any): Promise<any> {
const { operation, filename, content } = params;
try {
switch (operation) {
case 'read': {
const filePath = path.join(this.baseDir, filename);
if (!fs.existsSync(filePath)) {
return { success: false, data: 'File not found' };
}
const data = fs.readFileSync(filePath, 'utf8');
return { success: true, data };
}
case 'write': {
const filePath = path.join(this.baseDir, filename);
fs.writeFileSync(filePath, content, 'utf8');
return { success: true, data: 'File written successfully' };
}
case 'list': {
const files = fs.readdirSync(this.baseDir);
return { success: true, files };
}
case 'delete': {
const filePath = path.join(this.baseDir, filename);
if (!fs.existsSync(filePath)) {
return { success: false, data: 'File not found' };
}
fs.unlinkSync(filePath);
return { success: true, data: 'File deleted successfully' };
}
default:
return { success: false, data: 'Invalid operation' };
}
} catch (error) {
return {
success: false,
data: `Error: [error.message]`
};
}
}
}
This comprehensive guide provides all the information needed to develop, test, and deploy custom tools for LLM-MCP. For additional help, consult the LLM-MCP API reference or contact the platform team.