package main import ( "context" "fmt" stdio "git.novox.be/novox/mesh-sdk/go" ) var busArg = map[string]any{"type": "string", "enum": Buses, "description": "system (the default) or session (this account's login session bus, where one exists)"} func busOf(args map[string]any) string { b, _ := args["bus"].(string) return b } // Tools are the module's tools over MCP (novox/hq ADR 0215): the names on either bus, what an object // offers, a bounded watch of message headers, the module's check, and the bus's health. func Tools(m *Machine, w *Watcher) []stdio.Tool { return []stdio.Tool{ { Name: "dbus_names", Description: "Every well-known name on the system or session bus: its owner's pid, process, user and " + "systemd unit, the activatable names that are not running, and how many connections the bus has. " + "Read as the operator's account.", Input: map[string]any{"type": "object", "properties": map[string]any{"bus": busArg}}, Run: func(args map[string]any) (any, error) { return m.Names(context.Background(), busOf(args)) }, }, { Name: "dbus_introspect", Description: "What one object on a bus offers: its interfaces with their methods (arguments in and out), " + "properties (type and access, never their values) and signals, and its child objects. A service " + "that is not running is not started for it.", Input: map[string]any{ "type": "object", "properties": map[string]any{ "bus": busArg, "service": map[string]any{"type": "string", "description": "the bus name, e.g. org.freedesktop.login1"}, "path": map[string]any{"type": "string", "description": "the object path (default /)"}, }, "required": []string{"service"}, }, Run: func(args map[string]any) (any, error) { service, _ := args["service"].(string) path, _ := args["path"].(string) return m.Introspect(context.Background(), busOf(args), service, path) }, }, { Name: "dbus_monitor", Description: fmt.Sprintf("Watch a bus for a few seconds (at most %d) and answer the headers of the "+ "messages that passed: type, sender, destination, path, interface, member. Never a message's body, "+ "which carries secrets, notification text and the clipboard. Optional match rule and names to "+ "narrow it. The system bus is watched as root through sudo -n.", MaxMonitorSeconds), Input: map[string]any{ "type": "object", "properties": map[string]any{ "bus": busArg, "seconds": map[string]any{"type": "integer", "description": fmt.Sprintf("how long (default 5, at most %d)", MaxMonitorSeconds)}, "match": map[string]any{"type": "string", "description": "a D-Bus match rule, e.g. type='signal',interface='org.freedesktop.login1.Manager'"}, "names": map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": "only messages to or from these bus names"}, }, }, Run: func(args map[string]any) (any, error) { s := 5 if v, ok := args["seconds"].(float64); ok { s = int(v) } match, _ := args["match"].(string) var names []string if list, ok := args["names"].([]any); ok { for _, n := range list { if str, ok := n.(string); ok { names = append(names, str) } } } return m.Monitor(context.Background(), busOf(args), s, match, names) }, }, { Name: "dbus_check", Description: "Whether this machine's message bus is as the mesh expects: the bus's packages installed, " + "dbus-broker running behind dbus.service, whether the running bus is older than its installed " + "package (then a reboot is due: the bus is never restarted live), activatable services whose " + "unit does not exist, policy denials in the last hour, and the watcher's state.", Run: func(map[string]any) (any, error) { return m.Check(context.Background(), w), nil }, }, { Name: "dbus_health", Description: "The system bus's health now: a ping's round trip, how many connections it has, its unit, " + "pid and uptime, and what the watcher last saw.", Run: func(map[string]any) (any, error) { return m.Health(context.Background(), w), nil }, }, } }