Files
filepuff-mcp/cmd/mcp-filepuff/main.go
T
lukaszraczylo 0a3c14c8bd feat: anonymous usage telemetry via oss-telemetry
Send a single fire-and-forget ping at startup to help track adoption
and version spread. No persistent identifiers are collected.

Also adds main.version var (defaulting to "dev") so the existing
goreleaser ldflags injection (-X main.version={{.Version}}) now binds
to a real symbol.

Opt out via any of:
  DO_NOT_TRACK=1
  OSS_TELEMETRY_DISABLED=1
  MCP_FILEPUFF_DISABLE_TELEMETRY=1
2026-05-21 03:51:45 +01:00

104 lines
2.4 KiB
Go

// Package main is the entry point for the MCP file operations server.
package main
import (
"context"
"flag"
"log/slog"
"os"
"github.com/lukaszraczylo/mcp-filepuff/internal/config"
"github.com/lukaszraczylo/mcp-filepuff/internal/server"
telemetry "github.com/lukaszraczylo/oss-telemetry"
)
// version is the build version. Set via goreleaser ldflags
// (-X main.version={{.Version}}).
var version = "dev"
func main() {
telemetry.Send("mcp-filepuff", version)
// Parse command line flags
var (
workspaceRoot = flag.String("workspace", "", "Workspace root directory (default: current directory)")
logLevel = flag.String("log-level", "info", "Log level (debug, info, warn, error)")
logFile = flag.String("log-file", "", "Log file path (default: stderr)")
)
flag.Parse()
// Set up logging
logger := setupLogger(*logLevel, *logFile)
// Load configuration
cfg, err := config.Load(*workspaceRoot)
if err != nil {
logger.Error("failed to load configuration", "error", err)
os.Exit(1)
}
logger.Info("configuration loaded",
"workspace_root", cfg.WorkspaceRoot,
"lsp_enabled", cfg.EnableLSP,
)
// Create and run server
srv, err := server.New(cfg, logger)
if err != nil {
logger.Error("failed to create server", "error", err)
os.Exit(1)
}
ctx := context.Background()
if err := srv.Run(ctx); err != nil {
logger.Error("server error", "error", err)
os.Exit(1)
}
}
func setupLogger(level string, logFile string) *slog.Logger {
var logLevel slog.Level
switch level {
case "debug":
logLevel = slog.LevelDebug
case "warn":
logLevel = slog.LevelWarn
case "error":
logLevel = slog.LevelError
default:
logLevel = slog.LevelInfo
}
opts := &slog.HandlerOptions{
Level: logLevel,
}
var handler slog.Handler
var logFileErr error
if logFile != "" {
f, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
logFileErr = err
// Fallback to stderr
handler = slog.NewJSONHandler(os.Stderr, opts)
} else {
handler = slog.NewJSONHandler(f, opts)
}
} else {
// Use stderr for MCP servers (stdout is for protocol messages)
handler = slog.NewJSONHandler(os.Stderr, opts)
}
logger := slog.New(handler)
// Warn if log file couldn't be opened
if logFileErr != nil {
logger.Warn("failed to open log file, using stderr",
"file", logFile,
"error", logFileErr,
)
}
return logger
}