RootCause exposes a small SDK so toolsets (toolchains/plugins) can be built in-repo or in a separate module and still share the same tool registry and evidence/rendering helpers.
- Create a new module:
mkdir rootcause-aws
cd rootcause-aws
go mod init github.com/acme/rootcause-aws
go mod edit -require=rootcause@v0.0.0
go mod edit -replace=rootcause=/absolute/path/to/rootcause- Add your toolset under
toolsets/aws. - Register it in
init()so RootCause can discover it. - Build a custom binary that blank-imports your toolset.
- Create a Go package that implements the toolset interface.
- Register the toolset in
init()so it is discovered at runtime. - Use shared services or the tool invoker if you need cross-tool interactions.
package aws
import (
"fmt"
"rootcause/pkg/sdk"
)
type Toolset struct {
ctx sdk.ToolsetContext
}
func New() *Toolset { return &Toolset{} }
func (t *Toolset) ID() string { return "aws" }
func (t *Toolset) Version() string { return "0.1.0" }
func (t *Toolset) Init(ctx sdk.ToolsetContext) error {
if ctx.Clients == nil {
return fmt.Errorf("missing kube clients")
}
// Example: register a shared client for other toolsets.
if err := ctx.Services.Register("aws.session", mySession); err != nil {
return err
}
return nil
}
func (t *Toolset) Register(reg sdk.Registry) error {
return reg.Add(sdk.ToolSpec{
Name: "aws.status",
Description: "Example tool",
ToolsetID: t.ID(),
InputSchema: map[string]any{"type": "object"},
Safety: sdk.SafetyReadOnly,
Handler: t.handleStatus,
})
}
func init() {
sdk.MustRegisterToolset("aws", func() sdk.Toolset {
return New()
})
}- Shared services:
ctx.Services.Register("key", svc)andctx.Services.Get("key"). - Internal tool calls (from a handler):
t.ctx.CallTool(callCtx, req.User, "k8s.describe", args)(uses policy + audit).
This keeps policy checks and audit logging consistent across toolsets.
Create a small main in your own module, import RootCause’s server runner and your toolsets, and run it:
package main
import (
"context"
"os"
"rootcause/pkg/server"
_ "rootcause/toolsets/k8s"
_ "rootcause/toolsets/linkerd"
_ "github.com/acme/rootcause-aws/toolsets/aws"
)
func main() {
if err := server.Run(context.Background(), server.Options{Version: "0.1.0", Stderr: os.Stderr}); err != nil {
panic(err)
}
}Toolsets are enabled via --toolsets or config like usual.
Note: this repository currently uses module path rootcause (see go.mod), so external modules should use a replace directive unless/until the module path is changed to a public VCS import path.
Example config.yaml:
toolsets = ["k8s", "linkerd", "aws"]Or CLI:
--toolsets k8s,linkerd,aws
- Toolchains are compiled in; dynamic Go plugins are not used (keeps a single static binary).
- Use
ctx.Servicesfor shared clients or caches so other toolsets can reuse your logic.