From b5b490eb43e609137b3f3e9dc2ac8706f084ac00 Mon Sep 17 00:00:00 2001 From: thibaud-leclere Date: Tue, 12 May 2026 09:33:39 +0200 Subject: [PATCH] chore: scaffold project, generate mcpgen, add dependencies --- go.mod | 19 +++++++++ go.sum | 45 +++++++++++++++++++++ mcp.toml | 8 ++++ mcpgen/manifest.go | 11 ++++++ mcpgen/metadata.go | 27 +++++++++++++ mcpgen/secretstore.go | 91 +++++++++++++++++++++++++++++++++++++++++++ mcpgen/update.go | 59 ++++++++++++++++++++++++++++ 7 files changed, 260 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 mcp.toml create mode 100644 mcpgen/manifest.go create mode 100644 mcpgen/metadata.go create mode 100644 mcpgen/secretstore.go create mode 100644 mcpgen/update.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c7a6ae3 --- /dev/null +++ b/go.mod @@ -0,0 +1,19 @@ +module forge.lclr.dev/AI/xdebug-mcp + +go 1.25.5 + +require forge.lclr.dev/AI/mcp-framework v1.10.0 + +require ( + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.2 // indirect + github.com/BurntSushi/toml v1.6.0 // indirect + github.com/danieljoos/wincred v1.1.2 // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect + github.com/mtibben/percent v0.2.1 // indirect + github.com/stretchr/testify v1.11.1 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/term v0.40.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ac3f01c --- /dev/null +++ b/go.sum @@ -0,0 +1,45 @@ +forge.lclr.dev/AI/mcp-framework v1.10.0 h1:RrTy7K/hSruaVS9Z/oaRpkLs2U5WGs4H3tox7PiErak= +forge.lclr.dev/AI/mcp-framework v1.10.0/go.mod h1:2xzmFEHGLQzT5PORq35j10pRhsOm0CDwivUZTHvxgh4= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= +github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= +github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= +github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= +github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/mcp.toml b/mcp.toml new file mode 100644 index 0000000..d2a5484 --- /dev/null +++ b/mcp.toml @@ -0,0 +1,8 @@ +binary_name = "xdebug-mcp" + +[bootstrap] +description = "MCP server for Xdebug profiling files" + +[profiles] +default = "prod" +known = ["dev", "prod"] diff --git a/mcpgen/manifest.go b/mcpgen/manifest.go new file mode 100644 index 0000000..04f3dd6 --- /dev/null +++ b/mcpgen/manifest.go @@ -0,0 +1,11 @@ +// Code generated by mcp-framework generate. DO NOT EDIT. + +package mcpgen + +import fwmanifest "forge.lclr.dev/AI/mcp-framework/manifest" + +const embeddedManifest = "binary_name = \"xdebug-mcp\"\n\n[bootstrap]\ndescription = \"MCP server for Xdebug profiling files\"\n\n[profiles]\ndefault = \"prod\"\nknown = [\"dev\", \"prod\"]\n" + +func LoadManifest(startDir string) (fwmanifest.File, string, error) { + return fwmanifest.LoadDefaultOrEmbedded(startDir, embeddedManifest) +} diff --git a/mcpgen/metadata.go b/mcpgen/metadata.go new file mode 100644 index 0000000..ecac7ed --- /dev/null +++ b/mcpgen/metadata.go @@ -0,0 +1,27 @@ +// Code generated by mcp-framework generate. DO NOT EDIT. + +package mcpgen + +import fwmanifest "forge.lclr.dev/AI/mcp-framework/manifest" + +const BinaryName = "xdebug-mcp" +const DefaultDescription = "MCP server for Xdebug profiling files" +const DocsURL = "" + +func BootstrapInfo(startDir string) (fwmanifest.BootstrapMetadata, string, error) { + manifestFile, source, err := LoadManifest(startDir) + if err != nil { + return fwmanifest.BootstrapMetadata{}, "", err + } + + return manifestFile.BootstrapInfo(), source, nil +} + +func ScaffoldInfo(startDir string) (fwmanifest.ScaffoldMetadata, string, error) { + manifestFile, source, err := LoadManifest(startDir) + if err != nil { + return fwmanifest.ScaffoldMetadata{}, "", err + } + + return manifestFile.ScaffoldInfo(), source, nil +} diff --git a/mcpgen/secretstore.go b/mcpgen/secretstore.go new file mode 100644 index 0000000..e6d822c --- /dev/null +++ b/mcpgen/secretstore.go @@ -0,0 +1,91 @@ +// Code generated by mcp-framework generate. DO NOT EDIT. + +package mcpgen + +import ( + "os" + "path/filepath" + "strings" + + fwsecretstore "forge.lclr.dev/AI/mcp-framework/secretstore" +) + +type SecretStoreOptions struct { + ServiceName string + LookupEnv func(string) (string, bool) + KWalletAppID string + KWalletFolder string + BitwardenCommand string + BitwardenDebug bool + DisableBitwardenCache bool + Shell string + ExecutableResolver fwsecretstore.ExecutableResolver +} + +func OpenSecretStore(options SecretStoreOptions) (fwsecretstore.Store, error) { + return fwsecretstore.OpenFromManifest(secretStoreOpenOptions(options)) +} + +func DescribeSecretRuntime(options SecretStoreOptions) (fwsecretstore.RuntimeDescription, error) { + return fwsecretstore.DescribeRuntime(secretStoreDescribeOptions(options)) +} + +func PreflightSecretStore(options SecretStoreOptions) (fwsecretstore.PreflightReport, error) { + return fwsecretstore.PreflightFromManifest(secretStoreDescribeOptions(options)) +} + +func secretStoreOpenOptions(options SecretStoreOptions) fwsecretstore.OpenFromManifestOptions { + return fwsecretstore.OpenFromManifestOptions{ + ServiceName: secretStoreServiceName(options), + LookupEnv: options.LookupEnv, + KWalletAppID: options.KWalletAppID, + KWalletFolder: options.KWalletFolder, + BitwardenCommand: options.BitwardenCommand, + BitwardenDebug: options.BitwardenDebug, + DisableBitwardenCache: options.DisableBitwardenCache, + Shell: options.Shell, + ManifestLoader: LoadManifest, + ExecutableResolver: options.ExecutableResolver, + } +} + +func secretStoreDescribeOptions(options SecretStoreOptions) fwsecretstore.DescribeRuntimeOptions { + return fwsecretstore.DescribeRuntimeOptions{ + ServiceName: secretStoreServiceName(options), + LookupEnv: options.LookupEnv, + KWalletAppID: options.KWalletAppID, + KWalletFolder: options.KWalletFolder, + BitwardenCommand: options.BitwardenCommand, + BitwardenDebug: options.BitwardenDebug, + DisableBitwardenCache: options.DisableBitwardenCache, + Shell: options.Shell, + ManifestLoader: LoadManifest, + ExecutableResolver: options.ExecutableResolver, + } +} + +func secretStoreServiceName(options SecretStoreOptions) string { + serviceName := strings.TrimSpace(options.ServiceName) + if serviceName != "" { + return serviceName + } + + startDir := "." + executableResolver := options.ExecutableResolver + if executableResolver == nil { + executableResolver = os.Executable + } + if executablePath, err := executableResolver(); err == nil { + if dir := strings.TrimSpace(filepath.Dir(strings.TrimSpace(executablePath))); dir != "" { + startDir = dir + } + } + + if manifestFile, _, err := LoadManifest(startDir); err == nil { + if binaryName := strings.TrimSpace(manifestFile.BinaryName); binaryName != "" { + return binaryName + } + } + + return BinaryName +} diff --git a/mcpgen/update.go b/mcpgen/update.go new file mode 100644 index 0000000..09cafff --- /dev/null +++ b/mcpgen/update.go @@ -0,0 +1,59 @@ +// Code generated by mcp-framework generate. DO NOT EDIT. + +package mcpgen + +import ( + "context" + "flag" + "fmt" + "io" + "strings" + + fwupdate "forge.lclr.dev/AI/mcp-framework/update" +) + +func UpdateOptions(version string, stdout io.Writer) (fwupdate.Options, error) { + return UpdateOptionsFrom(".", version, stdout) +} + +func UpdateOptionsFrom(startDir string, version string, stdout io.Writer) (fwupdate.Options, error) { + manifestFile, _, err := LoadManifest(startDir) + if err != nil { + return fwupdate.Options{}, err + } + + binaryName := strings.TrimSpace(manifestFile.BinaryName) + if binaryName == "" { + binaryName = BinaryName + } + + return fwupdate.Options{ + CurrentVersion: version, + Stdout: stdout, + BinaryName: binaryName, + ReleaseSource: manifestFile.Update.ReleaseSource(), + }, nil +} + +func RunUpdate(ctx context.Context, args []string, version string, stdout io.Writer) error { + return RunUpdateFrom(ctx, args, ".", version, stdout) +} + +func RunUpdateFrom(ctx context.Context, args []string, startDir string, version string, stdout io.Writer) error { + fs := flag.NewFlagSet("update", flag.ContinueOnError) + fs.SetOutput(io.Discard) + + if err := fs.Parse(args); err != nil { + return err + } + if fs.NArg() != 0 { + return fmt.Errorf("update does not accept positional arguments: %s", strings.Join(fs.Args(), ", ")) + } + + options, err := UpdateOptionsFrom(startDir, version, stdout) + if err != nil { + return err + } + + return fwupdate.Run(ctx, options) +}