diff --git a/BOOTSTRAP_PROMPT.md b/BOOTSTRAP_PROMPT.md index 4dc36c0..f3cd7c7 100644 --- a/BOOTSTRAP_PROMPT.md +++ b/BOOTSTRAP_PROMPT.md @@ -8,7 +8,7 @@ I'm bootstrapping **SynapBus** — an open-source, local-first, MCP-native agent The project idea is fully described in `IDEA.md` — read it first. -The repo is at https://github.com/smart-mcp-proxy/synapbus (public, empty). +The repo is at https://github.com/synapbus/synapbus (public, empty). Domains: synapbus.com + synapbus.dev (to be registered). ## What I need you to do (in order): @@ -175,7 +175,7 @@ After creating all specs, run `/speckit.tasks` for each spec to generate impleme ### 5. Create initial project files -- `go.mod` with module `github.com/smart-mcp-proxy/synapbus` +- `go.mod` with module `github.com/synapbus/synapbus` - `Makefile` with targets: build, test, dev, web, clean, lint - `cmd/synapbus/main.go` — cobra CLI with `serve` command (placeholder) - `schema/001_initial.sql` — SQLite migration for agents, messages, conversations, channels, channel_members, inbox_state, traces, attachments diff --git a/CLAUDE.md b/CLAUDE.md index a5d6967..5fb1f3f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,7 +2,7 @@ Local-first, MCP-native agent-to-agent messaging service. Single Go binary with embedded storage, semantic search, and a Slack-like Web UI. -**Repo**: github.com/smart-mcp-proxy/synapbus +**Repo**: github.com/synapbus/synapbus **License**: Apache 2.0 ## Tech Stack diff --git a/IDEA.md b/IDEA.md index 3e7407c..81a467c 100644 --- a/IDEA.md +++ b/IDEA.md @@ -184,7 +184,7 @@ Agents interact with SynapBus entirely through MCP tools: - **Name**: SynapBus (synapse + bus — neural messaging bus) - **Domains**: synapbus.com ($11.28/yr), synapbus.dev ($12.98/yr) - **Website**: synapbus.dev (landing page + docs) -- **Repo**: github.com/smart-mcp-proxy/synapbus +- **Repo**: github.com/synapbus/synapbus - **License**: Apache 2.0 ## MVP Scope (v0.1) diff --git a/Makefile b/Makefile index 2adaa97..8fe6b44 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build test dev web clean lint hooks BINARY := synapbus -MODULE := github.com/smart-mcp-proxy/synapbus +MODULE := github.com/synapbus/synapbus BUILD_DIR := bin LDFLAGS := -s -w diff --git a/cmd/synapbus/main.go b/cmd/synapbus/main.go index 8759a6a..36c985c 100644 --- a/cmd/synapbus/main.go +++ b/cmd/synapbus/main.go @@ -19,22 +19,23 @@ import ( "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/spf13/cobra" - "github.com/smart-mcp-proxy/synapbus/internal/admin" - "github.com/smart-mcp-proxy/synapbus/internal/agents" - "github.com/smart-mcp-proxy/synapbus/internal/api" - "github.com/smart-mcp-proxy/synapbus/internal/apikeys" - "github.com/smart-mcp-proxy/synapbus/internal/attachments" - "github.com/smart-mcp-proxy/synapbus/internal/auth" - "github.com/smart-mcp-proxy/synapbus/internal/channels" - "github.com/smart-mcp-proxy/synapbus/internal/health" - mcpserver "github.com/smart-mcp-proxy/synapbus/internal/mcp" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - prommetrics "github.com/smart-mcp-proxy/synapbus/internal/metrics" - "github.com/smart-mcp-proxy/synapbus/internal/search" - "github.com/smart-mcp-proxy/synapbus/internal/search/embedding" - "github.com/smart-mcp-proxy/synapbus/internal/storage" - "github.com/smart-mcp-proxy/synapbus/internal/trace" - "github.com/smart-mcp-proxy/synapbus/internal/web" + "github.com/synapbus/synapbus/internal/admin" + "github.com/synapbus/synapbus/internal/agents" + "github.com/synapbus/synapbus/internal/api" + "github.com/synapbus/synapbus/internal/apikeys" + "github.com/synapbus/synapbus/internal/attachments" + "github.com/synapbus/synapbus/internal/auth" + "github.com/synapbus/synapbus/internal/channels" + "github.com/synapbus/synapbus/internal/console" + "github.com/synapbus/synapbus/internal/health" + mcpserver "github.com/synapbus/synapbus/internal/mcp" + "github.com/synapbus/synapbus/internal/messaging" + prommetrics "github.com/synapbus/synapbus/internal/metrics" + "github.com/synapbus/synapbus/internal/search" + "github.com/synapbus/synapbus/internal/search/embedding" + "github.com/synapbus/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/web" ) var ( @@ -140,12 +141,15 @@ func runServe(cmd *cobra.Command, args []string) error { adminSocketPath = filepath.Join(dataDir, "synapbus.sock") } - // Configure slog with JSON handler + // Configure slog with JSON handler writing to stderr (stdout is for console output) level := parseLogLevel(logLevel) - handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: level}) + handler := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: level}) logger := slog.New(handler) slog.SetDefault(logger) + // Create console printer for pretty output + con := console.New() + ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -333,7 +337,7 @@ func runServe(cmd *cobra.Command, args []string) error { apiKeyService := apikeys.NewService(apiKeyStore) // Create MCP server (with swarm + attachment + search tools) - mcpSrv := mcpserver.NewMCPServer(msgService, agentService, channelService, swarmService, attachmentService, searchService) + mcpSrv := mcpserver.NewMCPServer(msgService, agentService, channelService, swarmService, attachmentService, searchService, con) startTime := time.Now() // Start task expiry worker @@ -438,6 +442,14 @@ func runServe(cmd *cobra.Command, args []string) error { go func() { slog.Info("HTTP server listening", "addr", addr) + // Pretty startup banner + con.Blank() + con.Success(fmt.Sprintf("SynapBus listening on %s", addr)) + con.Success("MCP server ready") + con.Success(fmt.Sprintf("Web UI at http://localhost:%d", port)) + con.Blank() + con.Info("Waiting for agents...") + con.Blank() if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { slog.Error("server error", "error", err) cancel() diff --git a/go.mod b/go.mod index e90e861..cc90bce 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/smart-mcp-proxy/synapbus +module github.com/synapbus/synapbus go 1.25.0 diff --git a/internal/admin/server.go b/internal/admin/server.go index e977d4c..0b8ce20 100644 --- a/internal/admin/server.go +++ b/internal/admin/server.go @@ -6,11 +6,11 @@ import ( "log/slog" "net" - "github.com/smart-mcp-proxy/synapbus/internal/agents" - "github.com/smart-mcp-proxy/synapbus/internal/auth" - "github.com/smart-mcp-proxy/synapbus/internal/channels" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/agents" + "github.com/synapbus/synapbus/internal/auth" + "github.com/synapbus/synapbus/internal/channels" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/trace" ) // Services holds references to all services the admin socket can control. diff --git a/internal/admin/socket.go b/internal/admin/socket.go index edd31db..42fb752 100644 --- a/internal/admin/socket.go +++ b/internal/admin/socket.go @@ -13,8 +13,8 @@ import ( "strings" "time" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/trace" ) // Request is the JSON-RPC style request sent over the admin socket. diff --git a/internal/agents/middleware.go b/internal/agents/middleware.go index a5d019e..0260af2 100644 --- a/internal/agents/middleware.go +++ b/internal/agents/middleware.go @@ -7,8 +7,8 @@ import ( "net/http" "strings" - "github.com/smart-mcp-proxy/synapbus/internal/apikeys" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/apikeys" + "github.com/synapbus/synapbus/internal/trace" ) type contextKey string diff --git a/internal/agents/middleware_test.go b/internal/agents/middleware_test.go index 8995368..fb2a0ea 100644 --- a/internal/agents/middleware_test.go +++ b/internal/agents/middleware_test.go @@ -8,7 +8,7 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/trace" ) func TestAuthMiddleware(t *testing.T) { diff --git a/internal/agents/service.go b/internal/agents/service.go index 00be199..9ecdeb4 100644 --- a/internal/agents/service.go +++ b/internal/agents/service.go @@ -11,7 +11,7 @@ import ( "golang.org/x/crypto/bcrypt" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/trace" ) // AgentService provides business logic for agent registry operations. diff --git a/internal/agents/service_test.go b/internal/agents/service_test.go index 380d6d1..d92d223 100644 --- a/internal/agents/service_test.go +++ b/internal/agents/service_test.go @@ -7,7 +7,7 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/trace" ) func newTestService(t *testing.T) *AgentService { diff --git a/internal/agents/store_test.go b/internal/agents/store_test.go index 1bcb4c2..0791958 100644 --- a/internal/agents/store_test.go +++ b/internal/agents/store_test.go @@ -9,7 +9,7 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/storage" ) func newTestDB(t *testing.T) *sql.DB { diff --git a/internal/api/agents_handler.go b/internal/api/agents_handler.go index cc7fe4b..9053c7e 100644 --- a/internal/api/agents_handler.go +++ b/internal/api/agents_handler.go @@ -7,8 +7,8 @@ import ( "github.com/go-chi/chi/v5" - "github.com/smart-mcp-proxy/synapbus/internal/agents" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/agents" + "github.com/synapbus/synapbus/internal/trace" ) // AgentsHandler handles REST API requests for agents. diff --git a/internal/api/apikeys_handler.go b/internal/api/apikeys_handler.go index 01c81bb..dd6907d 100644 --- a/internal/api/apikeys_handler.go +++ b/internal/api/apikeys_handler.go @@ -10,7 +10,7 @@ import ( "github.com/go-chi/chi/v5" - "github.com/smart-mcp-proxy/synapbus/internal/apikeys" + "github.com/synapbus/synapbus/internal/apikeys" ) // APIKeysHandler handles REST API requests for API key management. diff --git a/internal/api/attachments_handler.go b/internal/api/attachments_handler.go index 34a2f06..a383740 100644 --- a/internal/api/attachments_handler.go +++ b/internal/api/attachments_handler.go @@ -9,7 +9,7 @@ import ( "github.com/go-chi/chi/v5" - "github.com/smart-mcp-proxy/synapbus/internal/attachments" + "github.com/synapbus/synapbus/internal/attachments" ) // AttachmentsHandler provides REST API endpoints for attachment operations. diff --git a/internal/api/channels_handler.go b/internal/api/channels_handler.go index 259f07f..47fea6c 100644 --- a/internal/api/channels_handler.go +++ b/internal/api/channels_handler.go @@ -7,9 +7,9 @@ import ( "github.com/go-chi/chi/v5" - "github.com/smart-mcp-proxy/synapbus/internal/agents" - "github.com/smart-mcp-proxy/synapbus/internal/channels" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/agents" + "github.com/synapbus/synapbus/internal/channels" + "github.com/synapbus/synapbus/internal/messaging" ) // ChannelsHandler handles REST API requests for channels. diff --git a/internal/api/messages_handler.go b/internal/api/messages_handler.go index d471538..8f6dfa7 100644 --- a/internal/api/messages_handler.go +++ b/internal/api/messages_handler.go @@ -9,8 +9,8 @@ import ( "github.com/go-chi/chi/v5" - "github.com/smart-mcp-proxy/synapbus/internal/agents" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/agents" + "github.com/synapbus/synapbus/internal/messaging" ) // MessagesHandler handles REST API requests for messages. diff --git a/internal/api/router.go b/internal/api/router.go index 07a1134..f3868b4 100644 --- a/internal/api/router.go +++ b/internal/api/router.go @@ -5,12 +5,12 @@ import ( "github.com/go-chi/chi/v5" - "github.com/smart-mcp-proxy/synapbus/internal/agents" - "github.com/smart-mcp-proxy/synapbus/internal/apikeys" - "github.com/smart-mcp-proxy/synapbus/internal/attachments" - "github.com/smart-mcp-proxy/synapbus/internal/channels" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/agents" + "github.com/synapbus/synapbus/internal/apikeys" + "github.com/synapbus/synapbus/internal/attachments" + "github.com/synapbus/synapbus/internal/channels" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/trace" ) // RouterConfig holds optional services for the API router. diff --git a/internal/api/session_middleware.go b/internal/api/session_middleware.go index de17a40..d51875a 100644 --- a/internal/api/session_middleware.go +++ b/internal/api/session_middleware.go @@ -3,7 +3,7 @@ package api import ( "net/http" - "github.com/smart-mcp-proxy/synapbus/internal/auth" + "github.com/synapbus/synapbus/internal/auth" ) // SessionToOwnerMiddleware wraps RequireSession and extracts the owner ID diff --git a/internal/api/traces_export_handler.go b/internal/api/traces_export_handler.go index 9a72bda..0dbf4c7 100644 --- a/internal/api/traces_export_handler.go +++ b/internal/api/traces_export_handler.go @@ -8,7 +8,7 @@ import ( "strconv" "time" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/trace" ) // ExportTraces handles GET /api/traces/export. diff --git a/internal/api/traces_handler.go b/internal/api/traces_handler.go index ed003df..a625ac7 100644 --- a/internal/api/traces_handler.go +++ b/internal/api/traces_handler.go @@ -7,7 +7,7 @@ import ( "strconv" "time" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/trace" ) // TracesHandler handles REST API requests for trace data. diff --git a/internal/api/traces_handler_test.go b/internal/api/traces_handler_test.go index 702dfa2..0225c80 100644 --- a/internal/api/traces_handler_test.go +++ b/internal/api/traces_handler_test.go @@ -12,7 +12,7 @@ import ( "testing" "time" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/trace" _ "modernc.org/sqlite" ) diff --git a/internal/attachments/sqlite_store_test.go b/internal/attachments/sqlite_store_test.go index 3620040..7ef5826 100644 --- a/internal/attachments/sqlite_store_test.go +++ b/internal/attachments/sqlite_store_test.go @@ -9,7 +9,7 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/storage" ) func newTestDB(t *testing.T) *sql.DB { diff --git a/internal/auth/user_store_test.go b/internal/auth/user_store_test.go index 166310c..206edaa 100644 --- a/internal/auth/user_store_test.go +++ b/internal/auth/user_store_test.go @@ -8,7 +8,7 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/storage" "golang.org/x/crypto/bcrypt" ) diff --git a/internal/channels/expiry_test.go b/internal/channels/expiry_test.go index ff3d9a9..52be2b4 100644 --- a/internal/channels/expiry_test.go +++ b/internal/channels/expiry_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/trace" ) func TestExpiryWorker_ExpiresOverdueTasks(t *testing.T) { diff --git a/internal/channels/service.go b/internal/channels/service.go index a4b8057..c964103 100644 --- a/internal/channels/service.go +++ b/internal/channels/service.go @@ -5,8 +5,8 @@ import ( "fmt" "log/slog" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/trace" ) // Service provides business logic for channel operations. diff --git a/internal/channels/service_test.go b/internal/channels/service_test.go index 26e95b5..f26cce8 100644 --- a/internal/channels/service_test.go +++ b/internal/channels/service_test.go @@ -9,9 +9,9 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/storage" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/trace" ) func newTestService(t *testing.T) (*Service, *sql.DB) { diff --git a/internal/channels/store_test.go b/internal/channels/store_test.go index fbcff9e..c85b7e1 100644 --- a/internal/channels/store_test.go +++ b/internal/channels/store_test.go @@ -8,7 +8,7 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/storage" ) func newTestDB(t *testing.T) *sql.DB { diff --git a/internal/channels/swarm_service.go b/internal/channels/swarm_service.go index f37d121..b94edcc 100644 --- a/internal/channels/swarm_service.go +++ b/internal/channels/swarm_service.go @@ -7,7 +7,7 @@ import ( "log/slog" "time" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/trace" ) // SwarmService handles task auction and stigmergy patterns. diff --git a/internal/channels/swarm_service_test.go b/internal/channels/swarm_service_test.go index b799cd1..7abea16 100644 --- a/internal/channels/swarm_service_test.go +++ b/internal/channels/swarm_service_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/trace" ) func newTestSwarmService(t *testing.T) (*SwarmService, *SQLiteChannelStore) { diff --git a/internal/mcp/auth.go b/internal/mcp/auth.go index 5210d08..8dc5b21 100644 --- a/internal/mcp/auth.go +++ b/internal/mcp/auth.go @@ -3,7 +3,7 @@ package mcp import ( "context" - "github.com/smart-mcp-proxy/synapbus/internal/agents" + "github.com/synapbus/synapbus/internal/agents" ) type mcpContextKey string diff --git a/internal/mcp/channel_tools.go b/internal/mcp/channel_tools.go index b637bd9..9ce99ed 100644 --- a/internal/mcp/channel_tools.go +++ b/internal/mcp/channel_tools.go @@ -7,7 +7,7 @@ import ( "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" - "github.com/smart-mcp-proxy/synapbus/internal/channels" + "github.com/synapbus/synapbus/internal/channels" ) // ChannelToolRegistrar registers channel MCP tools on the server. diff --git a/internal/mcp/channel_tools_test.go b/internal/mcp/channel_tools_test.go index 7ac85fb..f795625 100644 --- a/internal/mcp/channel_tools_test.go +++ b/internal/mcp/channel_tools_test.go @@ -8,10 +8,10 @@ import ( mcplib "github.com/mark3labs/mcp-go/mcp" _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/channels" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/storage" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/channels" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/trace" ) func newTestChannelRegistrar(t *testing.T) (*ChannelToolRegistrar, *channels.Service) { diff --git a/internal/mcp/connection.go b/internal/mcp/connection.go index 6f3c338..893d478 100644 --- a/internal/mcp/connection.go +++ b/internal/mcp/connection.go @@ -8,11 +8,15 @@ import ( // Connection represents an active agent connection. type Connection struct { - ID string `json:"id"` - AgentName string `json:"agent_name"` - Transport string `json:"transport"` - ConnectedAt time.Time `json:"connected_at"` - LastActivity time.Time `json:"last_activity"` + ID string `json:"id"` + AgentName string `json:"agent_name"` + Transport string `json:"transport"` + ConnectedAt time.Time `json:"connected_at"` + LastActivity time.Time `json:"last_activity"` + ClientName string `json:"client_name,omitempty"` + ClientVersion string `json:"client_version,omitempty"` + ProtocolVersion string `json:"protocol_version,omitempty"` + ClientCapabilities []string `json:"client_capabilities,omitempty"` } // ConnectionManager tracks active MCP connections (thread-safe). diff --git a/internal/mcp/server.go b/internal/mcp/server.go index 7d07051..4d072b3 100644 --- a/internal/mcp/server.go +++ b/internal/mcp/server.go @@ -2,17 +2,21 @@ package mcp import ( "context" + "fmt" "log/slog" "net/http" + "time" + mcplib "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" - "github.com/smart-mcp-proxy/synapbus/internal/agents" - "github.com/smart-mcp-proxy/synapbus/internal/attachments" - "github.com/smart-mcp-proxy/synapbus/internal/channels" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/search" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/agents" + "github.com/synapbus/synapbus/internal/attachments" + "github.com/synapbus/synapbus/internal/channels" + "github.com/synapbus/synapbus/internal/console" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/search" + "github.com/synapbus/synapbus/internal/trace" ) // MCPServer wraps the mcp-go server with SynapBus services. @@ -22,6 +26,7 @@ type MCPServer struct { connMgr *ConnectionManager agentService *agents.AgentService logger *slog.Logger + console *console.Printer } // NewMCPServer creates and configures a new MCP server with all tools registered. @@ -32,14 +37,104 @@ func NewMCPServer( swarmService *channels.SwarmService, attachmentService *attachments.Service, searchService *search.Service, + consolePrinter *console.Printer, ) *MCPServer { logger := slog.Default().With("component", "mcp-server") + connMgr := NewConnectionManager() + + // Set up hooks for client info capture and connection tracking + hooks := &server.Hooks{} + hooks.AddAfterInitialize(func(ctx context.Context, id any, msg *mcplib.InitializeRequest, result *mcplib.InitializeResult) { + clientName := msg.Params.ClientInfo.Name + clientVersion := msg.Params.ClientInfo.Version + protocolVersion := msg.Params.ProtocolVersion + + // Build capabilities list + var caps []string + if msg.Params.Capabilities.Roots != nil { + caps = append(caps, "roots") + } + if msg.Params.Capabilities.Sampling != nil { + caps = append(caps, "sampling") + } + if msg.Params.Capabilities.Elicitation != nil { + caps = append(caps, "elicitation") + } + if len(msg.Params.Capabilities.Experimental) > 0 { + for k := range msg.Params.Capabilities.Experimental { + caps = append(caps, "experimental/"+k) + } + } + + // Extract agent name from context (set by HTTP auth middleware) + agentName, _ := extractAgentName(ctx) + + // Get session ID for connection tracking + session := server.ClientSessionFromContext(ctx) + sessionID := "" + if session != nil { + sessionID = session.SessionID() + } + + // Register connection + if sessionID != "" { + conn := &Connection{ + ID: sessionID, + AgentName: agentName, + Transport: "streamable-http", + ConnectedAt: time.Now(), + LastActivity: time.Now(), + ClientName: clientName, + ClientVersion: clientVersion, + ProtocolVersion: protocolVersion, + ClientCapabilities: caps, + } + connMgr.Add(conn) + } + + // Structured log (always) + logger.Info("client initialized", + "agent", agentName, + "client_name", clientName, + "client_version", clientVersion, + "protocol_version", protocolVersion, + "capabilities", caps, + "session_id", sessionID, + ) + + // Pretty console output + if consolePrinter != nil { + if agentName != "" { + consolePrinter.AgentConnected(agentName, clientName, clientVersion) + } else { + consolePrinter.ClientConnected(clientName, clientVersion) + } + } + }) + + hooks.AddOnUnregisterSession(func(ctx context.Context, session server.ClientSession) { + sessionID := session.SessionID() + conn, ok := connMgr.Get(sessionID) + if ok { + if consolePrinter != nil && conn.AgentName != "" { + consolePrinter.AgentDisconnected(conn.AgentName) + } + logger.Info("client disconnected", + "agent", conn.AgentName, + "client_name", conn.ClientName, + "session_id", sessionID, + "duration", fmt.Sprintf("%s", time.Since(conn.ConnectedAt).Truncate(time.Second)), + ) + connMgr.Remove(sessionID) + } + }) // Create the mcp-go server mcpSrv := server.NewMCPServer( "SynapBus", "0.1.0", server.WithToolCapabilities(true), + server.WithHooks(hooks), ) // Register all tools @@ -85,9 +180,10 @@ func NewMCPServer( s := &MCPServer{ mcpServer: mcpSrv, httpServer: httpServer, - connMgr: NewConnectionManager(), + connMgr: connMgr, agentService: agentService, logger: logger, + console: consolePrinter, } logger.Info("MCP server initialized (streamable HTTP transport)") diff --git a/internal/mcp/swarm_tools.go b/internal/mcp/swarm_tools.go index 3c4c8e5..3fff910 100644 --- a/internal/mcp/swarm_tools.go +++ b/internal/mcp/swarm_tools.go @@ -10,7 +10,7 @@ import ( "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" - "github.com/smart-mcp-proxy/synapbus/internal/channels" + "github.com/synapbus/synapbus/internal/channels" ) // SwarmToolRegistrar registers swarm-pattern MCP tools on the server. diff --git a/internal/mcp/tools.go b/internal/mcp/tools.go index 7caaf83..f415459 100644 --- a/internal/mcp/tools.go +++ b/internal/mcp/tools.go @@ -9,9 +9,9 @@ import ( "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" - "github.com/smart-mcp-proxy/synapbus/internal/agents" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/search" + "github.com/synapbus/synapbus/internal/agents" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/search" ) // ToolRegistrar registers all SynapBus MCP tools on the given server. diff --git a/internal/mcp/tools_attachments.go b/internal/mcp/tools_attachments.go index c5dd923..13e0fc2 100644 --- a/internal/mcp/tools_attachments.go +++ b/internal/mcp/tools_attachments.go @@ -10,7 +10,7 @@ import ( "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" - "github.com/smart-mcp-proxy/synapbus/internal/attachments" + "github.com/synapbus/synapbus/internal/attachments" ) // AttachmentToolRegistrar registers attachment MCP tools on the server. diff --git a/internal/mcp/tools_test.go b/internal/mcp/tools_test.go index 3554f6d..2ec6077 100644 --- a/internal/mcp/tools_test.go +++ b/internal/mcp/tools_test.go @@ -10,10 +10,10 @@ import ( mcplib "github.com/mark3labs/mcp-go/mcp" _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/agents" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/storage" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/agents" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/trace" ) func newTestDB(t *testing.T) *sql.DB { diff --git a/internal/messaging/service.go b/internal/messaging/service.go index 3af8fd4..5c0981b 100644 --- a/internal/messaging/service.go +++ b/internal/messaging/service.go @@ -8,7 +8,7 @@ import ( "log/slog" "strings" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/trace" ) // MessagingService provides business logic for messaging operations. diff --git a/internal/messaging/service_test.go b/internal/messaging/service_test.go index 3b59eac..d2d7551 100644 --- a/internal/messaging/service_test.go +++ b/internal/messaging/service_test.go @@ -8,8 +8,8 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/storage" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/trace" ) func newTestService(t *testing.T) (*MessagingService, *sql.DB) { diff --git a/internal/messaging/store_test.go b/internal/messaging/store_test.go index 4318826..c4f7414 100644 --- a/internal/messaging/store_test.go +++ b/internal/messaging/store_test.go @@ -8,7 +8,7 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/storage" ) func newTestDB(t *testing.T) *sql.DB { diff --git a/internal/search/pipeline.go b/internal/search/pipeline.go index 969afa8..09fe8be 100644 --- a/internal/search/pipeline.go +++ b/internal/search/pipeline.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/smart-mcp-proxy/synapbus/internal/search/embedding" + "github.com/synapbus/synapbus/internal/search/embedding" ) // Pipeline processes unembedded messages in the background. diff --git a/internal/search/pipeline_test.go b/internal/search/pipeline_test.go index b9e64d6..e37ddf2 100644 --- a/internal/search/pipeline_test.go +++ b/internal/search/pipeline_test.go @@ -9,10 +9,10 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/search/embedding" - "github.com/smart-mcp-proxy/synapbus/internal/storage" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/search/embedding" + "github.com/synapbus/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/trace" ) func newPipelineTestDB(t *testing.T) *sql.DB { diff --git a/internal/search/service.go b/internal/search/service.go index 1787652..c0ed70b 100644 --- a/internal/search/service.go +++ b/internal/search/service.go @@ -9,8 +9,8 @@ import ( "strings" "time" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/search/embedding" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/search/embedding" ) // SearchMode constants. diff --git a/internal/search/service_test.go b/internal/search/service_test.go index b32f0e1..5eff699 100644 --- a/internal/search/service_test.go +++ b/internal/search/service_test.go @@ -8,10 +8,10 @@ import ( _ "modernc.org/sqlite" - "github.com/smart-mcp-proxy/synapbus/internal/messaging" - "github.com/smart-mcp-proxy/synapbus/internal/search/embedding" - "github.com/smart-mcp-proxy/synapbus/internal/storage" - "github.com/smart-mcp-proxy/synapbus/internal/trace" + "github.com/synapbus/synapbus/internal/messaging" + "github.com/synapbus/synapbus/internal/search/embedding" + "github.com/synapbus/synapbus/internal/storage" + "github.com/synapbus/synapbus/internal/trace" ) func newTestDB(t *testing.T) *sql.DB { diff --git a/logo-options.md b/logo-options.md new file mode 100644 index 0000000..a2ebf34 --- /dev/null +++ b/logo-options.md @@ -0,0 +1,86 @@ +# SynapBus Logo Options + +Generated using FLUX 1.1 Pro (black-forest-labs/flux-1.1-pro) via Replicate API. + +--- + +## 1. Neural S + +**Prompt:** Minimalist tech startup logo for SynapBus, letter S formed by interconnected neural network nodes and glowing synapses, purple (#7c3aed) and cyan (#06b6d4) on solid black background, clean vector style, simple, iconic, suitable for favicon + +**Image URL:** https://replicate.delivery/xezq/cqgVEevQM7VySyaJ4weZHb702f3bB1AC1kmMeF5bEkaERiCZB/tmpzc5b09t5.png + +![Neural S](https://replicate.delivery/xezq/cqgVEevQM7VySyaJ4weZHb702f3bB1AC1kmMeF5bEkaERiCZB/tmpzc5b09t5.png) + +--- + +## 2. Triple Node + +**Prompt:** Minimalist tech logo for SynapBus, three interconnected circular nodes forming a triangle connected by glowing electric lines, purple and teal gradient, solid black background, clean flat vector design, iconic + +**Image URL:** https://replicate.delivery/xezq/nU3DW7gd7PZPPRffVbJ4lBSL92ogV8eBwPMfrayzrg47RiCZB/tmpqy2cfyj0.png + +![Triple Node](https://replicate.delivery/xezq/nU3DW7gd7PZPPRffVbJ4lBSL92ogV8eBwPMfrayzrg47RiCZB/tmpqy2cfyj0.png) + +--- + +## 3. Circuit Synapse + +**Prompt:** Abstract minimalist logo for SynapBus, a neural synapse junction made of clean geometric circuit traces, single glowing connection point at center, purple and cyan colors, solid black background, vector icon style + +**Image URL:** https://replicate.delivery/xezq/GECNZKcnfR1qDaZSdFpnlsnjqHZgryvaqNfaCNsK9eiZJRhsA/tmp1mms12bu.png + +![Circuit Synapse](https://replicate.delivery/xezq/GECNZKcnfR1qDaZSdFpnlsnjqHZgryvaqNfaCNsK9eiZJRhsA/tmp1mms12bu.png) + +--- + +## 4. Pulse Signal + +**Prompt:** Minimalist tech logo for SynapBus, abstract signal pulse wave traveling between connected nodes, purple to cyan gradient energy flow, solid black background, clean modern design, suitable as app icon + +**Image URL:** https://replicate.delivery/xezq/eHiERjVwKrx2LKlU5IHBix4vi5jF1yRf2u8weHJOjxBnJRhsA/tmpcd64guyd.png + +![Pulse Signal](https://replicate.delivery/xezq/eHiERjVwKrx2LKlU5IHBix4vi5jF1yRf2u8weHJOjxBnJRhsA/tmpcd64guyd.png) + +--- + +## 5. Hexagonal Mesh + +**Prompt:** Minimalist logo for SynapBus, hexagonal mesh network with glowing nodes at key intersections, forming abstract neural pattern, purple and teal accents, solid black background, clean vector + +**Image URL:** https://replicate.delivery/xezq/9fznZBHzCyXyYqKVJJ0fm3edpLSYLhkA1exb2wMmZwmAUiCZB/tmpusby4b7s.png + +![Hexagonal Mesh](https://replicate.delivery/xezq/9fznZBHzCyXyYqKVJJ0fm3edpLSYLhkA1exb2wMmZwmAUiCZB/tmpusby4b7s.png) + +--- + +## 6. Bridge Connection + +**Prompt:** Abstract minimalist logo for SynapBus, two clusters of dots connected by flowing curved luminous lines forming a bridge, purple and cyan glow, solid black background, flat vector tech design + +**Image URL:** https://replicate.delivery/xezq/GSWjdPbVmvZ3PhIQ9e6kjOl36xrPRn9VF6pvnfxf1pFZKRhsA/tmpjnjkz6ib.png + +![Bridge Connection](https://replicate.delivery/xezq/GSWjdPbVmvZ3PhIQ9e6kjOl36xrPRn9VF6pvnfxf1pFZKRhsA/tmpjnjkz6ib.png) + +--- + +## 7. Constellation + +**Prompt:** Minimalist logo for SynapBus, constellation-style pattern of dots connected by thin lines forming interconnected network, purple and teal glow effects, solid black background, clean tech startup branding + +**Image URL:** https://replicate.delivery/xezq/8NzIPD0WDQqsOJ90RnTzj1ePEfnhNZ7L7GgQ4joF4NnVloQWA/tmpmbws_2nw.png + +![Constellation](https://replicate.delivery/xezq/8NzIPD0WDQqsOJ90RnTzj1ePEfnhNZ7L7GgQ4joF4NnVloQWA/tmpmbws_2nw.png) + +--- + +## 8. Radial Hub + +**Prompt:** Minimalist tech logo for SynapBus, central glowing circular hub with 5 radiating connections to satellite nodes, purple center with cyan endpoints, solid black background, clean vector icon design + +**Image URL:** https://replicate.delivery/xezq/ncb7M1AjSypOLxQdDaUQw4YBORKAibcd7ep75cfUCD9kloQWA/tmp8305o8ky.png + +![Radial Hub](https://replicate.delivery/xezq/ncb7M1AjSypOLxQdDaUQw4YBORKAibcd7ep75cfUCD9kloQWA/tmp8305o8ky.png) + +--- + diff --git a/logo-options/constellation-icon.png b/logo-options/constellation-icon.png new file mode 100644 index 0000000..4bf6a9d Binary files /dev/null and b/logo-options/constellation-icon.png differ diff --git a/logo-options/constellation-with-text.png b/logo-options/constellation-with-text.png new file mode 100644 index 0000000..19c5c40 Binary files /dev/null and b/logo-options/constellation-with-text.png differ