- Tables now render properly in Outline Wiki - Parses Markdown table syntax (| Col1 | Col2 |) - Converts to ProseMirror table structure with tr, th, td nodes - First row becomes header cells (th) - Bidirectional: tables also convert back to Markdown - v1.3.16 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
82 lines
2.3 KiB
JavaScript
82 lines
2.3 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* MCP Outline PostgreSQL - Stdio Server
|
|
* Standard stdio transport for CLI/local access
|
|
* @author Descomplicar® | @link descomplicar.pt | @copyright 2026
|
|
*/
|
|
|
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
import * as dotenv from 'dotenv';
|
|
|
|
import { PgClient } from './pg-client.js';
|
|
import { getDatabaseConfig } from './config/database.js';
|
|
import { createMcpServer, allTools, getToolCounts } from './server/index.js';
|
|
import { logger } from './utils/logger.js';
|
|
import { startRateLimitCleanup, stopRateLimitCleanup } from './utils/security.js';
|
|
|
|
dotenv.config();
|
|
|
|
// Validate all tools have required properties
|
|
const invalidTools = allTools.filter((tool) => !tool.name || !tool.handler);
|
|
if (invalidTools.length > 0) {
|
|
logger.error(`${invalidTools.length} invalid tools found`);
|
|
process.exit(1);
|
|
}
|
|
|
|
async function main() {
|
|
// Get database configuration
|
|
const config = getDatabaseConfig();
|
|
|
|
// Initialize PostgreSQL client
|
|
const pgClient = new PgClient(config);
|
|
|
|
// Test database connection
|
|
const isConnected = await pgClient.testConnection();
|
|
if (!isConnected) {
|
|
throw new Error('Failed to connect to PostgreSQL database');
|
|
}
|
|
|
|
// Create MCP server with shared configuration
|
|
const server = createMcpServer(pgClient.getPool(), {
|
|
name: 'mcp-outline-postgresql',
|
|
version: '1.3.16'
|
|
});
|
|
|
|
// Connect stdio transport
|
|
const transport = new StdioServerTransport();
|
|
await server.connect(transport);
|
|
|
|
// Start background tasks
|
|
startRateLimitCleanup();
|
|
|
|
// Graceful shutdown handler
|
|
const shutdown = async () => {
|
|
stopRateLimitCleanup();
|
|
await pgClient.close();
|
|
process.exit(0);
|
|
};
|
|
|
|
process.on('SIGINT', shutdown);
|
|
process.on('SIGTERM', shutdown);
|
|
|
|
// Log startup (minimal logging for MCP protocol compatibility)
|
|
if (process.env.LOG_LEVEL !== 'error' && process.env.LOG_LEVEL !== 'none') {
|
|
logger.info('MCP Server started');
|
|
}
|
|
|
|
// Debug logging
|
|
logger.debug('MCP Outline PostgreSQL Server running', {
|
|
transport: 'stdio',
|
|
totalTools: allTools.length,
|
|
toolsByModule: getToolCounts()
|
|
});
|
|
}
|
|
|
|
main().catch((error) => {
|
|
logger.error('Fatal error', {
|
|
error: error instanceof Error ? error.message : String(error),
|
|
stack: error instanceof Error ? error.stack : undefined
|
|
});
|
|
process.exit(1);
|
|
});
|