Files
isphere-ai-bridge/internal/mcpserver/server.go
2026-07-10 03:09:37 +08:00

98 lines
3.2 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"
)
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, err := msgLibDisplayEntitySourceFromEnv()
if err != nil {
return nil, err
}
return NewServerWithSources(source, displaySource), nil
}
func msgLibDisplayEntitySourceFromEnv() (tools.DisplayEntitySource, 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
}
if configured != 3 {
return 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, fmt.Errorf("configure MsgLib source: %w", err)
}
return msglib.NewClient(cfg), nil
}
func NewServerWithReceiveSource(source tools.ReceiveMessagesSource) *mcp.Server {
return NewServerWithSources(source, nil)
}
func NewServerWithSources(source tools.ReceiveMessagesSource, displaySource tools.DisplayEntitySource) *mcp.Server {
server := mcp.NewServer(&mcp.Implementation{
Name: ServerName,
Title: ServerTitle,
Version: ServerVersion,
}, nil)
tools.RegisterWinHelperTools(server, helperclient.Client{})
tools.RegisterISphereReadTools(server, source)
tools.RegisterISphereContactToolsWithDisplayEntities(server, source, displaySource)
tools.RegisterISphereGroupToolsWithDisplayEntities(server, source, displaySource)
tools.RegisterISphereFileTools(server, source)
return server
}