feat: Initial release MCP Outline PostgreSQL v1.0.0

86 tools across 12 modules for direct PostgreSQL access to Outline Wiki:
- Documents (19), Collections (14), Users (9), Groups (8)
- Comments (6), Shares (5), Revisions (3), Events (3)
- Attachments (5), File Operations (4), OAuth (8), Auth (2)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 13:25:09 +00:00
commit b05b54033f
30 changed files with 14439 additions and 0 deletions

90
src/utils/logger.ts Normal file
View File

@@ -0,0 +1,90 @@
/**
* MCP Outline PostgreSQL - Logger
* Optimized for MCP - reduce logs to not exhaust Claude context
* @author Descomplicar® | @link descomplicar.pt | @copyright 2026
*/
type LogLevel = 'error' | 'warn' | 'info' | 'debug';
interface LogEntry {
timestamp: string;
level: LogLevel;
message: string;
data?: Record<string, unknown>;
}
const LOG_LEVELS: Record<LogLevel, number> = {
error: 0,
warn: 1,
info: 2,
debug: 3
};
class Logger {
private level: LogLevel;
constructor() {
this.level = (process.env.LOG_LEVEL as LogLevel) || 'error';
}
private shouldLog(level: LogLevel): boolean {
return LOG_LEVELS[level] <= LOG_LEVELS[this.level];
}
private formatLog(level: LogLevel, message: string, data?: Record<string, unknown>): string {
const entry: LogEntry = {
timestamp: new Date().toISOString(),
level,
message,
...(data && { data })
};
return JSON.stringify(entry);
}
private write(level: LogLevel, message: string, data?: Record<string, unknown>): void {
if (!this.shouldLog(level)) return;
const formatted = this.formatLog(level, message, data);
// For MCP, send logs to stderr
if (process.env.MCP_MODE !== 'false') {
process.stderr.write(formatted + '\n');
} else {
console.log(formatted);
}
}
error(message: string, data?: Record<string, unknown>): void {
this.write('error', message, data);
}
warn(message: string, data?: Record<string, unknown>): void {
this.write('warn', message, data);
}
info(message: string, data?: Record<string, unknown>): void {
this.write('info', message, data);
}
debug(message: string, data?: Record<string, unknown>): void {
this.write('debug', message, data);
}
}
export const logger = new Logger();
// Log queries for auditing (if enabled) - OPTIMIZED
export function logQuery(
sql: string,
_params?: any[],
duration?: number,
_clientId?: string
): void {
// DISABLED by default to save Claude context
if (process.env.ENABLE_AUDIT_LOG === 'true' && process.env.NODE_ENV !== 'production') {
logger.debug('SQL', {
sql: sql.substring(0, 50),
duration
});
}
}