Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
61b91ca
feat(api): add SERVICE_TYPE_CATALOG and ServiceAnnounce message
kaisoz Jun 28, 2026
0a9e615
feat(sam-node): self-signed ServiceAnnounce build/sign/verify helpers
kaisoz Jun 28, 2026
6b3c1da
feat(sam-node): publish signed service announces on the reprovide tick
kaisoz Jun 28, 2026
f41fbb9
test(integration): service announce propagates between nodes
kaisoz Jun 28, 2026
be6cf80
refactor(announce): extract build/sign/verify into shared internal/an…
kaisoz Jun 29, 2026
207372a
fix(sam-node): subscribeToTopic subscribes even when topic already jo…
kaisoz Jun 29, 2026
6ccb34a
feat(sam-node): host CATALOG service type via MCP proxying
kaisoz Jun 29, 2026
c3e60be
feat(sam-node): SSE endpoint streaming verified service announces
kaisoz Jun 29, 2026
5bbb2d4
feat(catalog): in-memory service store with TTL sweep
kaisoz Jun 29, 2026
6dfa684
feat(catalog): node-client bootstrap + SSE announce tail + sweeper
kaisoz Jun 29, 2026
d5cc191
fix(catalog): backoff on every reconnect; bootstrap continues past pe…
kaisoz Jun 29, 2026
f5b5de3
feat(catalog): MCP query_catalog server and self-registration
kaisoz Jun 29, 2026
5a2aa7c
feat(catalog): sam-catalog binary + end-to-end integration test
kaisoz Jun 29, 2026
b2b26bb
fix(catalog): surface non-200 node responses instead of silently retr…
kaisoz Jun 29, 2026
32fcaa7
feat(sam-node): queryCatalog client with lazy catalog-peer memory
kaisoz Jun 29, 2026
6a15d0c
feat(sam-node): resolve discovery via catalog first, DHT fallback
kaisoz Jun 29, 2026
422f8ec
test(integration): discovery resolves via catalog with DHT fallback
kaisoz Jun 29, 2026
86df4cc
test(integration): skip catalog-path e2e (mock hub lacks real biscuit…
kaisoz Jun 29, 2026
a2c24ee
fix(sam-node): decode catalog peer id (was raw cast) so LocalProxyUrl…
kaisoz Jun 29, 2026
4ba64dd
docs(catalog): note bootstrap entries lack Addrs until a live announce
kaisoz Jun 29, 2026
d930512
fix(sam-node): use a locally-hosted catalog (query directly, no self-…
kaisoz Jun 29, 2026
9c38b5a
refactor(sam-node): transport-agnostic catalog endpoint resolution
kaisoz Jun 29, 2026
7404320
refactor(sam-node): dial hosted catalog once; drop unused queryCatalo…
kaisoz Jun 29, 2026
8a86774
fix(catalog): use upstream's single /mcp endpoint (was /mcp/events)
kaisoz Jun 29, 2026
215d411
fix(catalog): switch MCP transport to StreamableHTTP (upstream SDK ch…
kaisoz Jun 29, 2026
459c21b
test(e2e): bats catalog test (retrieval via catalog, on-the-fly, DHT …
kaisoz Jun 29, 2026
671f33f
test(e2e): split catalog bats into three cases with shared provision …
kaisoz Jun 29, 2026
a02619c
fix(catalog): satisfy errcheck/unused lint (explicit _= on ignored cl…
kaisoz Jun 30, 2026
5c73214
fix(catalog): check deferred resp.Body.Close (errcheck) in tail + reg…
kaisoz Jun 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ build:
go build -v -o "$(OUT_DIR)/sam-node" ./cmd/sam-node
go build -v -o "$(OUT_DIR)/sam-hub" ./cmd/sam-hub
go build -v -o "$(OUT_DIR)/mcp-client" ./cmd/mcp-client
go build -v -o "$(OUT_DIR)/sam-catalog" ./cmd/sam-catalog

.PHONY: proto
proto:
Expand Down
168 changes: 137 additions & 31 deletions api/sam.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions api/sam.proto
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ enum ServiceType {
SERVICE_TYPE_UNSPECIFIED = 0;
SERVICE_TYPE_MCP = 1;
SERVICE_TYPE_INFERENCE = 2;
SERVICE_TYPE_CATALOG = 3;
}

message ServiceInfo {
Expand All @@ -67,6 +68,16 @@ message ServiceInfo {
string description = 3;
}

message ServiceAnnounce {
ServiceType type = 1;
string name = 2;
string peer_id = 3;
repeated string addrs = 4;
int64 timestamp = 5;
int64 ttl_ms = 6;
bytes signature = 7;
}

message CommandBackend {
repeated string command = 1;
map<string, string> env = 2;
Expand Down
6 changes: 6 additions & 0 deletions api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const EnrollProtocolID protocol.ID = "/sam/enroll/1.0.0"
const MCPProtocolID protocol.ID = "/sam/mcp/1.0.0"
const GossipEvents = "/sam/mesh/events/v1"
const GossipHubSync = "/sam/hub/sync/v1"
const GossipServiceAnnounce = "/sam/service/announce/v1"
const AuthProtocolID protocol.ID = "/sam/auth/1.0.0"

// CatalogTarget is the special target service name used to retrieve tool catalogs from remote nodes.
Expand Down Expand Up @@ -101,6 +102,7 @@ func ParseServiceTarget(target string) (svcType, svcName string) {
const (
ServiceTypeStringMCP = "mcp"
ServiceTypeStringInference = "inference"
ServiceTypeStringCatalog = "catalog"
)

// InferenceServicePrefix is the conventional prefix used for LLM gateway inference services.
Expand All @@ -113,6 +115,8 @@ func ParseServiceType(s string) (ServiceType, error) {
return ServiceType_SERVICE_TYPE_MCP, nil
case ServiceTypeStringInference:
return ServiceType_SERVICE_TYPE_INFERENCE, nil
case ServiceTypeStringCatalog:
return ServiceType_SERVICE_TYPE_CATALOG, nil
default:
return ServiceType_SERVICE_TYPE_UNSPECIFIED, fmt.Errorf("invalid service type: %s", s)
}
Expand All @@ -125,6 +129,8 @@ func ServiceTypeToString(t ServiceType) (string, error) {
return ServiceTypeStringMCP, nil
case ServiceType_SERVICE_TYPE_INFERENCE:
return ServiceTypeStringInference, nil
case ServiceType_SERVICE_TYPE_CATALOG:
return ServiceTypeStringCatalog, nil
default:
return "", fmt.Errorf("invalid or unspecified service type")
}
Expand Down
Loading
Loading