Skip to content

Commit d5c44f0

Browse files
committed
progress
1 parent c6f3214 commit d5c44f0

File tree

18 files changed

+2294
-235
lines changed

18 files changed

+2294
-235
lines changed

cmd/root.go

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ package cmd
22

33
import (
44
"fmt"
5-
"log"
65
"os"
76
"slices"
87
"strings"
98

9+
"github.com/mark3labs/codebench-mcp/internal/logger"
1010
"github.com/mark3labs/codebench-mcp/jsserver"
1111
"github.com/mark3labs/mcp-go/server"
1212
"github.com/spf13/cobra"
@@ -15,6 +15,7 @@ import (
1515
var (
1616
enabledModules []string
1717
disabledModules []string
18+
debugMode bool
1819
)
1920

2021
// Available modules
@@ -23,15 +24,17 @@ var availableModules = []string{
2324
"fetch",
2425
"timers",
2526
"buffer",
26-
"cache",
27+
"kv",
2728
"crypto",
28-
"dom",
2929
"encoding",
30-
"ext",
31-
"html",
32-
"signal",
33-
"stream",
3430
"url",
31+
// TODO: Add these as they're implemented
32+
// "cache",
33+
// "dom",
34+
// "ext",
35+
// "html",
36+
// "signal",
37+
// "stream",
3538
}
3639

3740
// rootCmd represents the base command when called without any subcommands
@@ -41,9 +44,14 @@ var rootCmd = &cobra.Command{
4144
Long: `A Model Context Protocol (MCP) server that provides JavaScript execution capabilities
4245
with ski runtime including http, fetch, timers, buffer, crypto, and other modules.`,
4346
Run: func(cmd *cobra.Command, args []string) {
47+
// Initialize logger first
48+
logger.Init(debugMode)
49+
50+
logger.Debug("Starting codebench-mcp server", "debug", debugMode)
51+
4452
// Validate module configuration
4553
if len(enabledModules) > 0 && len(disabledModules) > 0 {
46-
log.Fatal("Error: --enabled-modules and --disabled-modules are mutually exclusive")
54+
logger.Fatal("--enabled-modules and --disabled-modules are mutually exclusive")
4755
}
4856

4957
// Determine which modules to enable
@@ -52,17 +60,15 @@ with ski runtime including http, fetch, timers, buffer, crypto, and other module
5260
// Only enable specified modules
5361
for _, module := range enabledModules {
5462
if !slices.Contains(availableModules, module) {
55-
log.Fatalf("Error: unknown module '%s'. Available modules: %s",
56-
module, strings.Join(availableModules, ", "))
63+
logger.Fatal("unknown module", "module", module, "available", strings.Join(availableModules, ", "))
5764
}
5865
}
5966
modulesToEnable = enabledModules
6067
} else if len(disabledModules) > 0 {
6168
// Enable all modules except disabled ones
6269
for _, module := range disabledModules {
6370
if !slices.Contains(availableModules, module) {
64-
log.Fatalf("Error: unknown module '%s'. Available modules: %s",
65-
module, strings.Join(availableModules, ", "))
71+
logger.Fatal("unknown module", "module", module, "available", strings.Join(availableModules, ", "))
6672
}
6773
}
6874
for _, module := range availableModules {
@@ -72,22 +78,26 @@ with ski runtime including http, fetch, timers, buffer, crypto, and other module
7278
}
7379
} else {
7480
// Enable default modules (same as NewJSHandler default)
75-
modulesToEnable = []string{"http", "fetch", "timers", "buffer", "crypto"}
81+
modulesToEnable = []string{"http", "fetch", "timers", "buffer", "kv", "crypto"}
7682
}
7783

84+
logger.Debug("Module configuration", "enabled", modulesToEnable)
85+
7886
// Create server with module configuration
7987
config := jsserver.ModuleConfig{
8088
EnabledModules: modulesToEnable,
8189
}
8290

8391
jss, err := jsserver.NewJSServerWithConfig(config)
8492
if err != nil {
85-
log.Fatalf("Failed to create server: %v", err)
93+
logger.Fatal("Failed to create server", "error", err)
8694
}
8795

96+
logger.Info("Starting MCP server", "modules", modulesToEnable)
97+
8898
// Serve requests
8999
if err := server.ServeStdio(jss); err != nil {
90-
log.Fatalf("Server error: %v", err)
100+
logger.Fatal("Server error", "error", err)
91101
}
92102
},
93103
}
@@ -107,6 +117,8 @@ func init() {
107117
rootCmd.Flags().StringSliceVar(&disabledModules, "disabled-modules", nil,
108118
fmt.Sprintf("Comma-separated list of modules to disable. Available: %s",
109119
strings.Join(availableModules, ", ")))
120+
rootCmd.Flags().BoolVar(&debugMode, "debug", false,
121+
"Enable debug logging (outputs to stderr)")
110122

111123
rootCmd.MarkFlagsMutuallyExclusive("enabled-modules", "disabled-modules")
112124
}

go.mod

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,39 @@ module github.com/mark3labs/codebench-mcp
33
go 1.23.10
44

55
require (
6+
github.com/charmbracelet/log v0.4.2
67
github.com/grafana/sobek v0.0.0-20250312125646-01f8811babf6
78
github.com/mark3labs/mcp-go v0.32.0
8-
github.com/shiroyk/ski v0.0.0-20250408031354-4adc80b35df6
99
github.com/spf13/cobra v1.9.1
1010
github.com/stretchr/testify v1.10.0
1111
)
1212

1313
require (
14+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
15+
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
16+
github.com/charmbracelet/lipgloss v1.1.0 // indirect
17+
github.com/charmbracelet/x/ansi v0.8.0 // indirect
18+
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
19+
github.com/charmbracelet/x/term v0.2.1 // indirect
1420
github.com/davecgh/go-spew v1.1.1 // indirect
1521
github.com/dlclark/regexp2 v1.11.5 // indirect
22+
github.com/go-logfmt/logfmt v0.6.0 // indirect
1623
github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect
1724
github.com/google/pprof v0.0.0-20250302191652-9094ed2288e7 // indirect
1825
github.com/google/uuid v1.6.0 // indirect
1926
github.com/inconshreveable/mousetrap v1.1.0 // indirect
27+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
28+
github.com/mattn/go-isatty v0.0.20 // indirect
29+
github.com/mattn/go-runewidth v0.0.16 // indirect
30+
github.com/muesli/termenv v0.16.0 // indirect
2031
github.com/pmezard/go-difflib v1.0.0 // indirect
32+
github.com/rivo/uniseg v0.4.7 // indirect
2133
github.com/spf13/cast v1.7.1 // indirect
2234
github.com/spf13/pflag v1.0.6 // indirect
35+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
2336
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
24-
golang.org/x/crypto v0.36.0 // indirect
25-
golang.org/x/net v0.37.0 // indirect
37+
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
38+
golang.org/x/sys v0.31.0 // indirect
2639
golang.org/x/text v0.23.0 // indirect
2740
gopkg.in/yaml.v3 v3.0.1 // indirect
2841
)

go.sum

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
11
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
22
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
3+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
4+
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
5+
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
6+
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
7+
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
8+
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
9+
github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig=
10+
github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw=
11+
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
12+
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
13+
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
14+
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
15+
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
16+
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
317
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
418
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
519
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
620
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
721
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
822
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
923
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
24+
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
25+
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
1026
github.com/go-sourcemap/sourcemap v2.1.4+incompatible h1:a+iTbH5auLKxaNwQFg0B+TCYl6lbukKPc7b5x0n1s6Q=
1127
github.com/go-sourcemap/sourcemap v2.1.4+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
1228
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
@@ -23,15 +39,24 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
2339
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
2440
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
2541
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
42+
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
43+
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
2644
github.com/mark3labs/mcp-go v0.32.0 h1:fgwmbfL2gbd67obg57OfV2Dnrhs1HtSdlY/i5fn7MU8=
2745
github.com/mark3labs/mcp-go v0.32.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
46+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
47+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
48+
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
49+
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
50+
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
51+
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
2852
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
2953
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
54+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
55+
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
56+
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
3057
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
3158
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
3259
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
33-
github.com/shiroyk/ski v0.0.0-20250408031354-4adc80b35df6 h1:MP/JX14gcF+xYACElKB+Dzr56oMW8xLO/r+2CKnsusc=
34-
github.com/shiroyk/ski v0.0.0-20250408031354-4adc80b35df6/go.mod h1:jCP1xHey89rnssFI9hlBSNOZ34LUROFMysGNkE5otlY=
3560
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
3661
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
3762
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
@@ -40,12 +65,15 @@ github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
4065
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
4166
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
4267
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
68+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
69+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
4370
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
4471
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
45-
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
46-
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
47-
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
48-
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
72+
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
73+
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
74+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
75+
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
76+
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
4977
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
5078
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
5179
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

internal/logger/logger.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package logger
2+
3+
import (
4+
"os"
5+
6+
"github.com/charmbracelet/log"
7+
)
8+
9+
var (
10+
// Logger is the global logger instance
11+
Logger *log.Logger
12+
// DebugEnabled tracks if debug logging is enabled
13+
DebugEnabled bool
14+
)
15+
16+
// Init initializes the global logger with the specified debug level
17+
func Init(debug bool) {
18+
DebugEnabled = debug
19+
20+
// Create logger that outputs to stderr (stdin/stdout reserved for MCP)
21+
Logger = log.NewWithOptions(os.Stderr, log.Options{
22+
ReportCaller: debug, // Show caller info in debug mode
23+
ReportTimestamp: true,
24+
TimeFormat: "15:04:05",
25+
Prefix: "codebench-mcp",
26+
})
27+
28+
// Set log level based on debug flag
29+
if debug {
30+
Logger.SetLevel(log.DebugLevel)
31+
} else {
32+
Logger.SetLevel(log.InfoLevel)
33+
}
34+
}
35+
36+
// Debug logs a debug message (only if debug is enabled)
37+
func Debug(msg interface{}, keyvals ...interface{}) {
38+
if Logger != nil {
39+
Logger.Debug(msg, keyvals...)
40+
}
41+
}
42+
43+
// Info logs an info message
44+
func Info(msg interface{}, keyvals ...interface{}) {
45+
if Logger != nil {
46+
Logger.Info(msg, keyvals...)
47+
}
48+
}
49+
50+
// Warn logs a warning message
51+
func Warn(msg interface{}, keyvals ...interface{}) {
52+
if Logger != nil {
53+
Logger.Warn(msg, keyvals...)
54+
}
55+
}
56+
57+
// Error logs an error message
58+
func Error(msg interface{}, keyvals ...interface{}) {
59+
if Logger != nil {
60+
Logger.Error(msg, keyvals...)
61+
}
62+
}
63+
64+
// Fatal logs a fatal message and exits
65+
func Fatal(msg interface{}, keyvals ...interface{}) {
66+
if Logger != nil {
67+
Logger.Fatal(msg, keyvals...)
68+
} else {
69+
// Fallback if logger not initialized
70+
log.Fatal(msg, keyvals...)
71+
}
72+
}
73+
74+
// GetLogger returns the global logger instance (for use in modules)
75+
func GetLogger() *log.Logger {
76+
return Logger
77+
}

0 commit comments

Comments
 (0)