117 lines
4.0 KiB
Go
117 lines
4.0 KiB
Go
package mcpserver
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/modelcontextprotocol/go-sdk/mcp"
|
|
|
|
"isphere-ai-bridge/internal/helperclient"
|
|
"isphere-ai-bridge/internal/isphere"
|
|
"isphere-ai-bridge/internal/msglib"
|
|
"isphere-ai-bridge/internal/tools"
|
|
)
|
|
|
|
const (
|
|
ServerName = "isphere-ai-bridge"
|
|
ServerTitle = "iSphere AI Bridge"
|
|
ServerVersion = "0.1.0"
|
|
EnvPacketLogFileKey = "ISPHERE_PACKET_LOG_FILE"
|
|
EnvPacketLogDirKey = "ISPHERE_PACKET_LOG_DIR"
|
|
EnvMsgLibSidecarExeKey = "ISPHERE_MSGLIB_SIDECAR_EXE"
|
|
EnvMsgLibSQLiteDLLKey = "ISPHERE_MSGLIB_SQLITE_DLL"
|
|
EnvMsgLibDBKey = "ISPHERE_MSGLIB_DB"
|
|
)
|
|
|
|
type msgLibClient interface {
|
|
tools.DisplayEntitySource
|
|
isphere.MsgLibMessageLister
|
|
}
|
|
|
|
var newMsgLibClient = func(cfg msglib.Config) msgLibClient {
|
|
return msglib.NewClient(cfg)
|
|
}
|
|
|
|
func NewServer() *mcp.Server {
|
|
return NewServerWithReceiveSource(isphere.EncryptedPacketLogSource{})
|
|
}
|
|
|
|
func NewServerFromEnv() (*mcp.Server, error) {
|
|
var source tools.ReceiveMessagesSource = isphere.EncryptedPacketLogSource{}
|
|
packetLogFile := strings.TrimSpace(os.Getenv(EnvPacketLogFileKey))
|
|
packetLogDir := strings.TrimSpace(os.Getenv(EnvPacketLogDirKey))
|
|
if packetLogFile != "" && packetLogDir != "" {
|
|
return nil, fmt.Errorf("configure packet log source: set only one of %s or %s", EnvPacketLogFileKey, EnvPacketLogDirKey)
|
|
}
|
|
if packetLogFile != "" {
|
|
loaded, err := isphere.LoadEncryptedPacketLogSourceFromFile(packetLogFile)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("configure %s: %w", EnvPacketLogFileKey, err)
|
|
}
|
|
source = loaded
|
|
} else if packetLogDir != "" {
|
|
loaded, err := isphere.LoadEncryptedPacketLogSourceFromDirectory(packetLogDir)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("configure %s: %w", EnvPacketLogDirKey, err)
|
|
}
|
|
source = loaded
|
|
}
|
|
displaySource, msglibReceiveSource, err := msgLibSourcesFromEnv()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewServerWithSourcesAndMsgLibReceive(source, displaySource, msglibReceiveSource), nil
|
|
}
|
|
|
|
func msgLibSourcesFromEnv() (tools.DisplayEntitySource, tools.ReceiveMessagesSource, error) {
|
|
sidecarExe := strings.TrimSpace(os.Getenv(EnvMsgLibSidecarExeKey))
|
|
sqliteDLL := strings.TrimSpace(os.Getenv(EnvMsgLibSQLiteDLLKey))
|
|
dbPath := strings.TrimSpace(os.Getenv(EnvMsgLibDBKey))
|
|
configured := 0
|
|
for _, value := range []string{sidecarExe, sqliteDLL, dbPath} {
|
|
if value != "" {
|
|
configured++
|
|
}
|
|
}
|
|
if configured == 0 {
|
|
return nil, nil, nil
|
|
}
|
|
if configured != 3 {
|
|
return nil, nil, fmt.Errorf("configure MsgLib source: set all of %s, %s, and %s, or set none", EnvMsgLibSidecarExeKey, EnvMsgLibSQLiteDLLKey, EnvMsgLibDBKey)
|
|
}
|
|
cfg, err := msglib.ConfigFromEnv()
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("configure MsgLib source: %w", err)
|
|
}
|
|
client := newMsgLibClient(cfg)
|
|
return client, isphere.MsgLibMessageSource{
|
|
Lister: client,
|
|
IncludeBody: true,
|
|
IncludeAttachmentMetadata: true,
|
|
}, nil
|
|
}
|
|
|
|
func NewServerWithReceiveSource(source tools.ReceiveMessagesSource) *mcp.Server {
|
|
return NewServerWithSources(source, nil)
|
|
}
|
|
|
|
func NewServerWithSources(source tools.ReceiveMessagesSource, displaySource tools.DisplayEntitySource) *mcp.Server {
|
|
return NewServerWithSourcesAndMsgLibReceive(source, displaySource, nil)
|
|
}
|
|
|
|
func NewServerWithSourcesAndMsgLibReceive(source tools.ReceiveMessagesSource, displaySource tools.DisplayEntitySource, msglibReceiveSource tools.ReceiveMessagesSource) *mcp.Server {
|
|
server := mcp.NewServer(&mcp.Implementation{
|
|
Name: ServerName,
|
|
Title: ServerTitle,
|
|
Version: ServerVersion,
|
|
}, nil)
|
|
tools.RegisterWinHelperTools(server, helperclient.Client{})
|
|
tools.RegisterISphereReadToolsWithReceiveSources(server, source, msglibReceiveSource, displaySource)
|
|
tools.RegisterISphereContactToolsWithDisplayEntities(server, source, displaySource)
|
|
tools.RegisterISphereGroupToolsWithDisplayEntities(server, source, displaySource)
|
|
tools.RegisterISphereFileTools(server, source)
|
|
tools.RegisterISphereSendMessageTool(server, nil)
|
|
return server
|
|
}
|