Building Your Own MCP Server
This guide walks you through creating a custom MCP server for developers that exposes filesystem operations.Prerequisites
- Node.js 16+
- Basic understanding of MCP protocol
agent-corex-sdkinstalled
Step 1: Initialize Project
mkdir filesystem-mcp
cd filesystem-mcp
npm init -y
npm install agent-corex-sdk
Step 2: Create Server File
Createindex.js:
import { MCPServer } from 'agent-corex-sdk';
import fs from 'fs/promises';
import path from 'path';
const server = new MCPServer({
name: 'filesystem-mcp',
version: '1.0.0',
description: 'Filesystem operations for Agent-CoreX'
});
// Tool 1: Read file
server.addTool({
name: 'read-file',
description: 'Read contents of a file',
inputSchema: {
type: 'object',
properties: {
path: {
type: 'string',
description: 'File path to read'
},
encoding: {
type: 'string',
description: 'File encoding (default: utf-8)',
enum: ['utf-8', 'base64']
}
},
required: ['path']
},
async execute(params) {
try {
const content = await fs.readFile(params.path, params.encoding || 'utf-8');
return {
success: true,
content: content,
encoding: params.encoding || 'utf-8'
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
});
// Tool 2: Write file
server.addTool({
name: 'write-file',
description: 'Write content to a file',
inputSchema: {
type: 'object',
properties: {
path: {
type: 'string',
description: 'File path to write to'
},
content: {
type: 'string',
description: 'Content to write'
},
mode: {
type: 'string',
enum: ['write', 'append'],
description: 'Write mode'
}
},
required: ['path', 'content']
},
async execute(params) {
try {
if (params.mode === 'append') {
await fs.appendFile(params.path, params.content);
} else {
await fs.writeFile(params.path, params.content);
}
return {
success: true,
path: params.path,
mode: params.mode || 'write'
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
});
// Tool 3: List directory
server.addTool({
name: 'list-directory',
description: 'List files in a directory',
inputSchema: {
type: 'object',
properties: {
path: {
type: 'string',
description: 'Directory path'
},
recursive: {
type: 'boolean',
description: 'List recursively'
}
},
required: ['path']
},
async execute(params) {
try {
const files = await fs.readdir(params.path);
return {
success: true,
files: files,
count: files.length
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
});
// Tool 4: Delete file
server.addTool({
name: 'delete-file',
description: 'Delete a file',
inputSchema: {
type: 'object',
properties: {
path: {
type: 'string',
description: 'File path to delete'
},
force: {
type: 'boolean',
description: 'Force deletion'
}
},
required: ['path']
},
async execute(params) {
try {
await fs.unlink(params.path);
return {
success: true,
path: params.path
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
});
// Start server
const port = process.env.PORT || 3000;
server.start(port);
console.log(`Filesystem MCP server running on port ${port}`);
Step 3: Run the Server
node index.js
# Output: Filesystem MCP server running on port 3000
Step 4: Register with Agent-CoreX
agent-corex mcp register \
--name "filesystem-mcp" \
--url "http://localhost:3000"
Step 5: Use in Your Agent
const agent = new AgentCorex({
apiKey: process.env.AGENT_COREX_API_KEY
});
// Retrieve tools
const tools = await agent.retrieveTools({
query: "Read a file and list directory contents"
});
// Execute
const fileContent = await agent.executeTool({
toolName: 'read-file',
params: {
path: './README.md'
}
});
console.log(fileContent.content);
Best Practices for Custom MCP Servers
1. Validate Inputs
server.addTool({
name: 'secure-read-file',
// ...
async execute(params) {
// Security: prevent path traversal
const normalizedPath = path.normalize(params.path);
if (!normalizedPath.startsWith(process.cwd())) {
return { success: false, error: 'Path outside allowed directory' };
}
// Now safe to read
const content = await fs.readFile(normalizedPath);
return { success: true, content };
}
});
2. Handle Errors Gracefully
async execute(params) {
try {
// ...
} catch (error) {
if (error.code === 'ENOENT') {
return { success: false, error: 'File not found' };
} else if (error.code === 'EACCES') {
return { success: false, error: 'Permission denied' };
} else {
return { success: false, error: error.message };
}
}
}
3. Performance Optimization
// For large operations, implement pagination
server.addTool({
name: 'list-directory-paginated',
async execute(params) {
const files = await fs.readdir(params.path);
const page = params.page || 0;
const pageSize = params.pageSize || 20;
const start = page * pageSize;
const paginatedFiles = files.slice(start, start + pageSize);
return {
success: true,
files: paginatedFiles,
total: files.length,
page,
hasMore: start + pageSize < files.length
};
}
});
Deploy to Production
Using Docker
CreateDockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
docker build -t filesystem-mcp .
docker run -p 3000:3000 filesystem-mcp
Advanced Features
Add Authentication
server.setAuthHandler((token) => {
// Validate token
return token === process.env.API_TOKEN;
});
Add Logging
server.onToolCall((toolName, params) => {
console.log(`Tool: ${toolName}`);
console.log(`Params:`, params);
});
Add Caching
const cache = new Map();
server.addTool({
name: 'read-file-cached',
async execute(params) {
const cacheKey = `file:${params.path}`;
if (cache.has(cacheKey)) {
return { ...cache.get(cacheKey), cached: true };
}
const content = await fs.readFile(params.path, 'utf-8');
const result = { success: true, content };
cache.set(cacheKey, result);
return result;
}
});
Testing Your MCP Server
// test.js
import { MCPClient } from 'agent-corex-sdk';
const client = new MCPClient('http://localhost:3000');
async function testServer() {
// Test read-file
const readResult = await client.call('read-file', {
path: './package.json'
});
console.log('Read result:', readResult);
// Test write-file
const writeResult = await client.call('write-file', {
path: './test.txt',
content: 'Hello, MCP!'
});
console.log('Write result:', writeResult);
}
testServer();
Next Steps
MCP Concepts
Understand the protocol.
Setup MCP Servers
Connect your server.
API Reference
Full API docs.
Marketplace
Share your server.
Ready to build? Create your custom MCP server for developers and unlock unlimited possibilities! 🚀