52 lines
1.5 KiB
Go
52 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"os/exec"
|
|
|
|
"github.com/mark3labs/mcp-go/mcp"
|
|
)
|
|
|
|
type doctorArgs struct {
|
|
Subcommand string `json:"subcommand,omitempty"`
|
|
}
|
|
|
|
func doctorTool() mcp.Tool {
|
|
return mcp.NewTool("fn_doctor",
|
|
mcp.WithDescription("Run `fn doctor [subcommand] --json` and return the parsed report. Subcommands: artefacts, services, sync, uses-functions, unused. Empty = all checks. Read-only."),
|
|
mcp.WithString("subcommand",
|
|
mcp.Description("Subcommand. Empty runs all."),
|
|
mcp.Enum("", "artefacts", "services", "sync", "uses-functions", "unused"),
|
|
),
|
|
)
|
|
}
|
|
|
|
func (d *deps) handleDoctor(ctx context.Context, _ mcp.CallToolRequest, args doctorArgs) (*mcp.CallToolResult, error) {
|
|
bin := d.fnBin()
|
|
cmdArgs := []string{"doctor"}
|
|
if args.Subcommand != "" {
|
|
cmdArgs = append(cmdArgs, args.Subcommand)
|
|
}
|
|
cmdArgs = append(cmdArgs, "--json")
|
|
|
|
cmd := exec.CommandContext(ctx, bin, cmdArgs...)
|
|
cmd.Dir = d.root
|
|
out, err := cmd.Output()
|
|
if err != nil {
|
|
stderr := ""
|
|
if ee, ok := err.(*exec.ExitError); ok {
|
|
stderr = string(ee.Stderr)
|
|
}
|
|
return mcp.NewToolResultError("fn doctor: " + err.Error() + "\n" + stderr), nil
|
|
}
|
|
|
|
// Try to parse JSON; if it fails, return the raw output.
|
|
var report any
|
|
if jsonErr := json.Unmarshal(out, &report); jsonErr != nil {
|
|
return mcp.NewToolResultText(string(out)), nil
|
|
}
|
|
b, _ := json.MarshalIndent(map[string]any{"subcommand": args.Subcommand, "report": report}, "", " ")
|
|
return mcp.NewToolResultText(string(b)), nil
|
|
}
|