import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import express from 'express'
import searchTool from './tools/search.js'
import { contentAnalysisTool } from './tools/content-analysis.js'
import { exportResultsTool } from './tools/export.js'
import { scrapeTool } from './tools/scrape.js'
import { searchAndScrapeTool } from './tools/search-scrape.js'
import { enhancedExportTool } from './tools/enhanced-export.js'
import { cacheStatsTool, cacheClearTool } from './tools/cache.js'
import { healthTool } from './tools/health.js'
import logger from './core/logger.js'
import { loadConfig } from './core/config.js'
function parseArgs() {
const args = process.argv.slice(2)
const flags = {
stdio: args.includes('--stdio'),
port: undefined
}
for (let i = 0; i < args.length; i++) {
if (args[i] === '--port' && args[i+1]) {
flags.port = parseInt(args[i+1])
i++
}
}
if (process.env.MCP_TRANSPORT === 'stdio') flags.stdio = true
if (process.env.PORT && !flags.port) flags.port = parseInt(process.env.PORT)
return flags
}
const main = async () => {
try {
const config = await loadConfig()
const flags = parseArgs()
const server = new McpServer({
name: 'presearch-mcp-server',
description: 'Privacy-focused MCP server for web search and content export with caching and result processing.',
version: '2.1.0'
})
server.registerTool(searchTool.name, searchTool.inputSchema, async (args) => searchTool.execute(args))
server.registerTool(contentAnalysisTool.name, contentAnalysisTool.inputSchema, async (args) => contentAnalysisTool.execute(args))
server.registerTool(exportResultsTool.name, exportResultsTool.inputSchema, async (args) => exportResultsTool.execute(args))
server.registerTool(scrapeTool.name, scrapeTool.inputSchema, async (args) => scrapeTool.execute(args))
server.registerTool(searchAndScrapeTool.name, searchAndScrapeTool.inputSchema, async (args) => searchAndScrapeTool.execute(args))
server.registerTool(enhancedExportTool.name, enhancedExportTool.inputSchema, async (args) => enhancedExportTool.execute(args))
server.registerTool(cacheStatsTool.name, cacheStatsTool.inputSchema, async (args) => cacheStatsTool.execute(args))
server.registerTool(cacheClearTool.name, cacheClearTool.inputSchema, async (args) => cacheClearTool.execute(args))
server.registerTool(healthTool.name, healthTool.inputSchema, async (args) => healthTool.execute(args))
if (flags.stdio) {
const transport = new StdioServerTransport()
await server.connect(transport)
logger.info('MCP Server (STDIO) starting')
return
}
const app = express()
app.use(express.json())
app.post('/mcp', async (req, res) => {
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
enableJsonResponse: true
})
res.on('close', () => transport.close())
await server.connect(transport)
await transport.handleRequest(req, res, req.body)
})
const port = flags.port || config.port
app.listen(port, () => {
logger.info(`MCP Server (HTTP) on http://localhost:${port}/mcp`)
}).on('error', (error) => {
logger.error('Server error:', error)
process.exit(1)
})
} catch (error) {
logger.error('Failed to start the server:', error)
process.exit(1)
}
}
main()