175 lines
5.5 KiB
Go
175 lines
5.5 KiB
Go
// pkg/mcp/tools_events.go
|
|
package mcp
|
|
|
|
import (
|
|
"context"
|
|
|
|
core "dappco.re/go/core"
|
|
coreerr "dappco.re/go/core/log"
|
|
"forge.lthn.ai/core/gui/pkg/events"
|
|
"github.com/modelcontextprotocol/go-sdk/mcp"
|
|
)
|
|
|
|
// --- event_emit ---
|
|
|
|
type EventEmitInput struct {
|
|
Name string `json:"name"`
|
|
Data any `json:"data,omitempty"`
|
|
}
|
|
type EventEmitOutput struct {
|
|
Cancelled bool `json:"cancelled"`
|
|
}
|
|
|
|
func (s *Subsystem) eventEmit(_ context.Context, _ *mcp.CallToolRequest, input EventEmitInput) (*mcp.CallToolResult, EventEmitOutput, error) {
|
|
r := s.core.Action("events.emit").Run(context.Background(), core.NewOptions(
|
|
core.Option{Key: "task", Value: events.TaskEmit{Name: input.Name, Data: input.Data}},
|
|
))
|
|
if !r.OK {
|
|
if e, ok := r.Value.(error); ok {
|
|
return nil, EventEmitOutput{}, e
|
|
}
|
|
return nil, EventEmitOutput{}, nil
|
|
}
|
|
cancelled, ok := r.Value.(bool)
|
|
if !ok {
|
|
return nil, EventEmitOutput{}, coreerr.E("mcp.eventEmit", "unexpected result type", nil)
|
|
}
|
|
return nil, EventEmitOutput{Cancelled: cancelled}, nil
|
|
}
|
|
|
|
// --- event_on ---
|
|
|
|
type EventOnInput struct {
|
|
Name string `json:"name"`
|
|
}
|
|
type EventOnOutput struct {
|
|
Success bool `json:"success"`
|
|
}
|
|
|
|
func (s *Subsystem) eventOn(_ context.Context, _ *mcp.CallToolRequest, input EventOnInput) (*mcp.CallToolResult, EventOnOutput, error) {
|
|
r := s.core.Action("events.on").Run(context.Background(), core.NewOptions(
|
|
core.Option{Key: "task", Value: events.TaskOn{Name: input.Name}},
|
|
))
|
|
if !r.OK {
|
|
if e, ok := r.Value.(error); ok {
|
|
return nil, EventOnOutput{}, e
|
|
}
|
|
return nil, EventOnOutput{}, nil
|
|
}
|
|
return nil, EventOnOutput{Success: true}, nil
|
|
}
|
|
|
|
// --- event_subscribe ---
|
|
|
|
type EventSubscribeInput struct {
|
|
Name string `json:"name"`
|
|
}
|
|
type EventSubscribeOutput struct {
|
|
Success bool `json:"success"`
|
|
}
|
|
|
|
func (s *Subsystem) eventSubscribe(ctx context.Context, req *mcp.CallToolRequest, input EventSubscribeInput) (*mcp.CallToolResult, EventSubscribeOutput, error) {
|
|
result, output, err := s.eventOn(ctx, req, EventOnInput{Name: input.Name})
|
|
if err != nil {
|
|
return nil, EventSubscribeOutput{}, err
|
|
}
|
|
if result != nil {
|
|
return result, EventSubscribeOutput{}, nil
|
|
}
|
|
return nil, EventSubscribeOutput{Success: output.Success}, nil
|
|
}
|
|
|
|
// --- event_off ---
|
|
|
|
type EventOffInput struct {
|
|
Name string `json:"name"`
|
|
}
|
|
type EventOffOutput struct {
|
|
Success bool `json:"success"`
|
|
}
|
|
|
|
func (s *Subsystem) eventOff(_ context.Context, _ *mcp.CallToolRequest, input EventOffInput) (*mcp.CallToolResult, EventOffOutput, error) {
|
|
r := s.core.Action("events.off").Run(context.Background(), core.NewOptions(
|
|
core.Option{Key: "task", Value: events.TaskOff{Name: input.Name}},
|
|
))
|
|
if !r.OK {
|
|
if e, ok := r.Value.(error); ok {
|
|
return nil, EventOffOutput{}, e
|
|
}
|
|
return nil, EventOffOutput{}, nil
|
|
}
|
|
return nil, EventOffOutput{Success: true}, nil
|
|
}
|
|
|
|
// --- event_unsubscribe ---
|
|
|
|
type EventUnsubscribeInput struct {
|
|
Name string `json:"name"`
|
|
}
|
|
type EventUnsubscribeOutput struct {
|
|
Success bool `json:"success"`
|
|
}
|
|
|
|
func (s *Subsystem) eventUnsubscribe(ctx context.Context, req *mcp.CallToolRequest, input EventUnsubscribeInput) (*mcp.CallToolResult, EventUnsubscribeOutput, error) {
|
|
result, output, err := s.eventOff(ctx, req, EventOffInput{Name: input.Name})
|
|
if err != nil {
|
|
return nil, EventUnsubscribeOutput{}, err
|
|
}
|
|
if result != nil {
|
|
return result, EventUnsubscribeOutput{}, nil
|
|
}
|
|
return nil, EventUnsubscribeOutput{Success: output.Success}, nil
|
|
}
|
|
|
|
// --- event_list ---
|
|
|
|
type EventListInput struct{}
|
|
type EventListOutput struct {
|
|
Listeners []events.ListenerInfo `json:"listeners"`
|
|
}
|
|
|
|
func (s *Subsystem) eventList(_ context.Context, _ *mcp.CallToolRequest, _ EventListInput) (*mcp.CallToolResult, EventListOutput, error) {
|
|
r := s.core.QUERY(events.QueryListeners{})
|
|
if !r.OK {
|
|
if e, ok := r.Value.(error); ok {
|
|
return nil, EventListOutput{}, e
|
|
}
|
|
return nil, EventListOutput{}, nil
|
|
}
|
|
listenerInfos, ok := r.Value.([]events.ListenerInfo)
|
|
if !ok {
|
|
return nil, EventListOutput{}, coreerr.E("mcp.eventList", "unexpected result type", nil)
|
|
}
|
|
return nil, EventListOutput{Listeners: listenerInfos}, nil
|
|
}
|
|
|
|
// --- event_info ---
|
|
|
|
type EventInfoInput struct{}
|
|
type EventInfoOutput struct {
|
|
Info events.ServerInfo `json:"info"`
|
|
}
|
|
|
|
func (s *Subsystem) eventInfo(_ context.Context, _ *mcp.CallToolRequest, _ EventInfoInput) (*mcp.CallToolResult, EventInfoOutput, error) {
|
|
r := s.core.QUERY(events.QueryServerInfo{})
|
|
if !r.OK {
|
|
return nil, EventInfoOutput{}, nil
|
|
}
|
|
info, ok := r.Value.(events.ServerInfo)
|
|
if !ok {
|
|
return nil, EventInfoOutput{}, coreerr.E("mcp.eventInfo", "unexpected result type", nil)
|
|
}
|
|
return nil, EventInfoOutput{Info: info}, nil
|
|
}
|
|
|
|
// --- Registration ---
|
|
|
|
func (s *Subsystem) registerEventsTools(server *mcp.Server) {
|
|
addTool(s, server, &mcp.Tool{Name: "event_emit", Description: "Fire a named custom event with optional data"}, s.eventEmit)
|
|
addTool(s, server, &mcp.Tool{Name: "event_on", Description: "Register a listener for a named custom event"}, s.eventOn)
|
|
addTool(s, server, &mcp.Tool{Name: "event_subscribe", Description: "Register a listener for a named custom event"}, s.eventSubscribe)
|
|
addTool(s, server, &mcp.Tool{Name: "event_off", Description: "Remove all listeners for a named custom event"}, s.eventOff)
|
|
addTool(s, server, &mcp.Tool{Name: "event_unsubscribe", Description: "Remove all listeners for a named custom event"}, s.eventUnsubscribe)
|
|
addTool(s, server, &mcp.Tool{Name: "event_list", Description: "Query all registered event listeners"}, s.eventList)
|
|
addTool(s, server, &mcp.Tool{Name: "event_info", Description: "Get WebSocket event server information"}, s.eventInfo)
|
|
}
|