Files
gronod d40646211f
Build and publish / Test and build (darwin) (push) Failing after 1m42s
Build and publish / Test and build (linux) (push) Failing after 1m53s
Build and publish / Test and build (windows) (push) Failing after 2m50s
Build and publish / Build and publish Docker image (push) Skipped
Initial Go implementation of Emby.MCP
Go rewrite of the Python Emby.MCP server with tool parity (20 tools),
plus a streamable-HTTP transport with per-request Emby authentication
(Basic / Bearer token passthrough), a multi-arch Docker build, and a
Gitea CI workflow.
2026-09-20 22:52:46 +01:00

82 lines
1.7 KiB
Go

// Package state holds the per-session mutable context shared by the MCP
// tools: the authenticated Emby client, library selection, and in-progress
// search-result chunking. It mirrors the Python lifespan context dict.
package state
import (
"sync"
"github.com/gordon/emby-mcp/internal/emby"
)
// SearchChunk tracks an in-progress chunked search result set.
type SearchChunk struct {
SearchID string
TotalItems int
ChunkSize int
ChunkNum int // last returned chunk (1-based); 0 = none returned yet
Items []emby.MediaItem
}
// State is the shared server state. All access goes through the mutex.
type State struct {
mu sync.Mutex
Client *emby.Client
UserID string
MaxChunkSize int
libraries []emby.Library
current *emby.Library
search *SearchChunk
}
func New(client *emby.Client, userID string, maxChunkSize int) *State {
return &State{Client: client, UserID: userID, MaxChunkSize: maxChunkSize}
}
// Libraries returns a copy of the cached library list.
func (s *State) Libraries() []emby.Library {
s.mu.Lock()
defer s.mu.Unlock()
out := make([]emby.Library, len(s.libraries))
copy(out, s.libraries)
return out
}
func (s *State) SetLibraries(libs []emby.Library) {
s.mu.Lock()
defer s.mu.Unlock()
s.libraries = libs
}
func (s *State) CurrentLibrary() *emby.Library {
s.mu.Lock()
defer s.mu.Unlock()
return s.current
}
func (s *State) SetCurrentLibrary(l *emby.Library) {
s.mu.Lock()
defer s.mu.Unlock()
s.current = l
}
func (s *State) Search() *SearchChunk {
s.mu.Lock()
defer s.mu.Unlock()
return s.search
}
func (s *State) SetSearch(c *SearchChunk) {
s.mu.Lock()
defer s.mu.Unlock()
s.search = c
}
func (s *State) ClearSearch() {
s.mu.Lock()
defer s.mu.Unlock()
s.search = nil
}