import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { ConfigManager } from './config/manager.js';
import { createFetchRssTool, handleFetchRss } from './tools/fetch-rss.js';
import { createListFeedsTool, handleListFeeds } from './tools/list-feeds.js';
import { createAddFeedTool, handleAddFeed } from './tools/add-feed.js';
import { createRemoveFeedTool, handleRemoveFeed } from './tools/remove-feed.js';
export class RssFeedMcpServer {
private server: Server;
private configManager: ConfigManager;
constructor(configPath?: string) {
this.configManager = new ConfigManager(configPath);
this.server = new Server(
{
name: 'rss-feed-mcp-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
this.setupToolHandlers();
}
private setupToolHandlers(): void {
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
createFetchRssTool(this.configManager),
createListFeedsTool(),
createAddFeedTool(),
createRemoveFeedTool(),
],
};
});
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
const { name, arguments: args } = request.params;
switch (name) {
case 'fetch_rss_feed':
const fetchResult = await handleFetchRss(args, this.configManager);
return {
content: [
{
type: 'text',
text: JSON.stringify(fetchResult, null, 2),
},
],
};
case 'list_feeds':
const listResult = await handleListFeeds(args, this.configManager);
return {
content: [
{
type: 'text',
text: JSON.stringify(listResult, null, 2),
},
],
};
case 'add_feed':
const addResult = await handleAddFeed(args, this.configManager);
return {
content: [
{
type: 'text',
text: JSON.stringify(addResult, null, 2),
},
],
};
case 'remove_feed':
const removeResult = await handleRemoveFeed(args, this.configManager);
return {
content: [
{
type: 'text',
text: JSON.stringify(removeResult, null, 2),
},
],
};
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error) {
return {
content: [
{
type: 'text',
text: JSON.stringify({
error: true,
code: 'INTERNAL_ERROR',
message: `ツール実行エラー: ${error instanceof Error ? error.message : 'Unknown error'}`,
}, null, 2),
},
],
isError: true,
};
}
});
}
async start(): Promise<void> {
await this.configManager.load();
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error('RSS Feed MCP Server started');
}
}