Repository navigation
Releases: SolaceProducts/solace-broker-mcp
Release list
v1.0.0
Release: v1.0.0, first GA
Date: 2026-10-14
License: Apache 2.0
MCP specification: 2025-11-25 (latest stable)
Platforms: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64
Brokers: Solace event brokers, software and appliance, on LTS and rolling releases currently under Solace support
Tools
- 47 tools: 29 read-only and 18 write. Write tools are disabled by default and require explicit opt-in via
enable_write_tools. - Read tools cover broker discovery, broker status and redundancy, replication, message rates, Message VPNs, queues, clients, client usernames and client profiles, slow subscribers, REST Delivery Points, bridges, Kafka receivers and senders, discard diagnostics, and SEMP schema introspection.
- Write tools disconnect clients, delete queued messages, and clear client and queue statistics. They also create, update, and delete Message VPNs, queues, topic endpoints, and REST Delivery Points, and create and delete queue subscriptions.
- Multi-broker support, with each broker addressed by configured alias from a single server instance.
Clients
- Compatible with any MCP client that supports the Streamable HTTP transport. Setup documented for Claude Code and Claude Desktop.
- Solace Agent Mesh integration, wiring the server into an Agent Mesh project as an MCP-tooled agent.
Authentication and authorization
- OAuth 2.1 / OIDC for production, validated with Keycloak and Microsoft Entra ID. Unauthenticated and static-token modes available for development.
- End-user identity propagation to the broker, through OAuth token exchange or Entra On-Behalf-Of, so broker audit logs record the calling user rather than a shared service account.
- Claim-based tool authorization, gating individual tools by the group or role claim in the caller's token.
Observability
- Prometheus metrics and OpenTelemetry tracing.
- Correlation ID on every request, returned to the caller and recorded in server logs and audit records.
- Metrics for tool invocations, SEMP requests, broker reachability, authentication and authorization failures, audit pipeline health, and panic recovery.
- Audit log covering every destructive operation.
- Importable Grafana dashboard and an operator runbook.
- Kubernetes liveness and readiness probes.
Deployment
- Standalone binary, Docker image, or
go install. Kubernetes manifests included. - TLS terminated at the server or upstream at a proxy or ingress.
- Per-broker rate limiting, retry and backoff, and concurrency caps.
- Published checksums, plus a build provenance attestation on the release archives and the container image, verifiable against the release workflow.
Upgrading
The server is a replacement upgrade. It holds no persistent state, so a new instance starts serving as soon as it is healthy. Open MCP sessions do not survive the swap, and clients reconnect.
Version numbering also changes at 1.0. Through the 0.x line a breaking change raised the middle number. From 1.0 it raises the first.
Upgrading from a pre-GA release may need configuration changes, and some behaviour has changed with it. The changelog lists every breaking change in the 0.x line. One is worth calling out, because it can break broker connectivity with an unchanged configuration file: broker traffic now follows the standard proxy environment variables where it previously went direct, so exempt your brokers, and your OTLP collector if telemetry is enabled, before upgrading.
Links
- Repository
- v1.0.0 release
- Tools Reference
- User Guide
- Configuration
- Authentication
- Observability
- Examples
- Solace Agent Mesh integration
- Kubernetes deployment
What's Changed
- SOL-155413: list tools report a missing VPN or client as not-found by @solace-awaheed in #483
- docs(DOC-8761): First pass of editorials - more to come by @gilyusolace in #482
- SOL-155412: show the agent and operator why a request body was rejected by @amitmorade in #487
- SOL-155411: report a timed-out create/update as outcome-unknown, not "try again later" by @bczoma in #488
- SOL-155451: document offline_access in scopes_supported for Entra setups by @amitmorade in #490
- SOL-155480: remaining VPN-scoped list tools report a missing VPN as not-found by @solace-awaheed in #486
- SOL-155426: fix list-queue-discards token-budget overflow at its documented default by @solace-lootii in #484
- SOL-155432: strip broker self-referential links/meta URIs from tool results by @solace-lootii in #489
- SOL-155668: Fix follow-up doc errors and drop rename history by @amitmorade in #492
- Bump the go-minor-patch group across 1 directory with 2 updates by @dependabot[bot] in #480
- SOL-155670: Remove the retired OBS_METRICS_ENABLED flag handling by @amitmorade in #493
- SOL-155414: warn when /metrics is reachable beyond the loopback-only MCP listener by @solace-lootii in #485
- Bump the third-party-actions group across 1 directory with 2 updates by @dependabot[bot] in #491
- SOL-155864: bump golang.org/x/net v0.58.0 -> v0.60.0 (CVE-2026-78663 et al.) by @DevSol-UQ in #494
- SOL-155918: log structured owner-validation fields when the owner check blocks a write by @solace-lootii in #497
- SOL-154679: add mcp_owner_validation_total for writes blocked by the owner check by @solace-lootii in #498
- SOL-155938: fix increase() alert guidance for mcp_authz_denied_total, trim SOL-155918 CHANGELOG entry by @solace-lootii in #499
- SOL-155075: restore the nightly LLM eval beside the release gate by @amitmorade in #502
- Update SEMP schemas to latest rolling release (10.26.8) by @bczoma in #501
- SOL-156024: Prepare release v1.0.0 by @solace-awaheed in #505
New Contributors
- @gilyusolace made their first contribution in #482
- @DevSol-UQ made their first contribution in #494
Full Changelog: v0.11.0...v1.0.0
v0.11.0
What's new in 0.11.0
Microsoft Entra ID support is complete, plus a Windows build and a few fixes.
Full details are in
CHANGELOG.md.
Added
- Microsoft Entra ID support is complete. Entra On-Behalf-Of no longer needs a feature
flag, and the Authentication Guide
covers setting up Entra end to end. - A Windows (amd64) binary build is now included in the release assets
(solace-broker-mcp-<version>-windows-amd64.zip).
Removed
- The
HOP2_JWT_BEARER_ENABLEDenvironment variable. It was the feature flag for Microsoft
Entra ID support, which is no longer behind a feature flag, so you can delete it.
Fixed
list-brokersanddescribe-semp-schemanow validate their input like every other tool,
and report bad input as a readable tool error.- The token-exchange audience-mismatch message is now logged at
INFOinstead ofWARN, once
per broker, requested audience and returned audience, so Entra deployments no longer see it
on every exchange. create-queue-subscriptionrejects topics containing HTML-encoded characters (such as
>) instead of subscribing to the wrong topic.
What's Changed
- SOL-155015: bound loadgen memory and add the Box C observability stack by @solace-awaheed in #470
- SOL-155161: warnIfAudienceMismatch logs a false-positive WARN on every successful Entra exchange by @solace-lootii in #468
- SOL-153693: Validate input for list-brokers and describe-semp-schema by @solace-lootii in #475
- Bump the internal-reusable-workflows group across 1 directory with 6 updates by @dependabot[bot] in #469
- Bump the third-party-actions group across 1 directory with 2 updates by @dependabot[bot] in #474
- SOL-152578: State a policy for what may live in .githooks/ by @McCly-Solace in #472
- SOL-154049: reject HTML-entity-encoded topics on create-queue-subscription by @solace-lootii in #446
- SOL-154663: Document the macOS Gatekeeper block and its workarounds by @McCly-Solace in #471
- SOL-155349: remove the HOP2_JWT_BEARER_ENABLED soak door by @amitmorade in #478
- SOL-154399: document Entra ID for operators by @amitmorade in #479
- SOL-153187: Add windows/amd64 to the release matrix by @McCly-Solace in #477
- SOL-155401: Prepare release v0.11.0 by @solace-awaheed in #481
Full Changelog: v0.10.0...v0.11.0
v0.10.0
What's new in 0.10.0
New client-access tools, Entra On-Behalf-Of support, outbound proxy support, an
owner-validation security fix, and a round of observability additions. This release has breaking changes — see
Before you upgrade.
Full details are in
CHANGELOG.md.
Before you upgrade
- YAML config:
auth.audienceis nowauth.target, and
broker_oauth.audience_parameter_nameis removed. A config file using either fails to
load. Token-exchange error logs also saytargetinstead ofaudience. - Environment variable:
OBS_METRICS_ENABLEDis nowOBS_METRICS_SCRAPE_ENABLED. The
old name is ignored. - The
OTEL_SERVICE_NAME/OTEL_RESOURCE_ATTRIBUTESenvironment variables are now
honoured, soservice.namecan change. Setobservability.service_namein the YAML
config to keep the old value. list-vpnsreal-clients.byKey[vpn]now returns onlyhasRealClientor
indeterminate.- Go 1.26.0 is the new minimum for building from source.
- Queue/topic-endpoint
ownermust be an existing client username. Create the client
username first. - Broker traffic now follows the
HTTPS_PROXYenvironment variable. If one is already
set, add your brokers toNO_PROXY. - YAML config: an unquoted
${VAR}inside[...]or{...}must now be quoted.
Added
- Read-only tools:
list-client-usernames,get-client-username,
list-client-profiles,get-client-profile. - Broker traffic honours the
HTTP_PROXY/HTTPS_PROXY/NO_PROXYenvironment variables. - YAML config field
mcp_client_auth.scopes_supportedsets the OAuth scopes the server
advertises. - YAML config field
broker_oauth.token_expiry_fallbacksupports IdPs that omitexpires_in. - Entra On-Behalf-Of: the jwt-bearer grant type for
broker_oauth.grant_typenow obtains
broker tokens, behind theHOP2_JWT_BEARER_ENABLEDenvironment variable. - Observability: a Grafana dashboard, an operator runbook, Kubernetes metrics port and
NetworkPolicy, and new metrics for broker authorization denials, dropped audit
records, and token-exchange circuit-breaker state. - Extra startup and debug log lines for troubleshooting OAuth and identity settings.
Changed
- Embedded SEMPv2 specs updated to 10.26.7.
- The Kubernetes deployment now sets
GOMEMLIMITto 75% of the memory limit. docs/observability.mdrewritten to describe the shipped behaviour, including every
OBS_*flag's default.
Fixed
- Security: queue/topic-endpoint write tools no longer accept a nonexistent
owner,
which could leave the object open to every client on the VPN. list-vpnsno longer reports most active VPNs as idle.- Config comments containing an apostrophe or quote no longer trigger
${VAR}
substitution. - Tool errors now return valid JSON-RPC codes, and
describe-semp-schemadeclares an
output schema. - Blank identity values are now treated as unset.
Security
- Environment-variable substitution in the config can no longer inject extra YAML keys.
What's Changed
- SOL-154042: record each observability flag's default and flip-condition by @solace-aross in #408
- SOL-153332: emit a broker_authz_denied audit event and counter for hop-2 authorization denials by @solace-lootii in #389
- SOL-151608: optional token expiry fallback when IdP omits expires_in by @amitmorade in #410
- Log advertised OAuth PRM at startup (SOL-154210) by @amitmorade in #415
- SOL-152284: alertable token-exchange circuit breaker state metric by @amitmorade in #414
- SOL-154328: set GOMEMLIMIT in the shipped Kubernetes manifest and condition the 512Mi claim by @bczoma in #413
- Bump softprops/action-gh-release from 3.0.2 to 3.0.3 in the github-actions group by @dependabot[bot] in #417
- Record hop-2 expiry fallback first use at INFO (SOL-154334) by @amitmorade in #419
- SOL-154238: add CI check validating docs/observability.md against the live Prometheus registry by @solace-lootii in #407
- SOL-153694: declare an output schema for describe-semp-schema by @solace-awaheed in #418
- Bump docker/setup-qemu-action from 4.2.0 to 4.3.0 in the github-actions group by @dependabot[bot] in #422
- SOL-152423: Ship a reference OTel collector deployment and tested-backend matrix so tracing is usable on day one (Story 40) by @solace-wmaryam in #412
- Update SEMP schemas to latest rolling release (10.26.6) by @solace-wmaryam in #426
- SOL-152424: ship a ServiceMonitor and NetworkPolicy for the metrics e… by @solace-awaheed in #423
- SOL-154446: accept "already absent" wording in the d2 nightly llm-eval scenario by @McCly-Solace in #425
- SOL-153295: route broker SEMP traffic through HTTP_PROXY/HTTPS_PROXY/… by @solace-awaheed in #428
- SOL-154339: memory provenance, gctrace and log-volume guards in the perf harness by @bczoma in #421
- SOL-153079: fix YAML comment substitution, reorder Quickstart, and un-hardcode the example VPN by @McCly-Solace in #420
- SOL-152092: Ship an importable reference Grafana dashboard (Story 37) by @solace-lootii in #424
- SOL-153692: give tool-handler errors a valid JSON-RPC code at the withRecovery seam by @solace-awaheed in #430
- SOL-152098: add the operator runbook so Tier-1 can work a failure without paging an engineer (Story 36) by @solace-wmaryam in #429
- SOL-153076: Add read-only client-username and client-profile management tools by @solace-wmaryam in #431
- SOL-154545: verify the published Grafana dashboard and collector metrics pipeline nightly, on both ingestion paths by @solace-lootii in #432
- SOL-154569: wire mcp_audit_events_dropped_total so audit drops are vi… by @solace-awaheed in #436
- SOL-154607: rename OBS_METRICS_ENABLED to OBS_METRICS_SCRAPE_ENABLED … by @solace-awaheed in #438
- SOL-153545: Distinguish waiters of a concurrent broker-token exchange by @amitmorade in #440
- SOL-154608: honour OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES whe… by @solace-awaheed in #441
- SOL-154727: treat empty and whitespace-only identity values as unset,… by @solace-awaheed in #443
- SOL-153080: reject queue/topic-endpoint owner bindings to nonexistent client usernames by @solace-lootii in #439
- SOL-154397: configurable mcp_client_auth.scopes_supported for RFC 9728 PRM by @amitmorade in #447
- SOL-154318: correct drifted citations and audit status in internal architecture docs by @amitmorade in #445
- SOL-154315: enforce changelog entry length limits in /changelog skill by @McCly-Solace in #433
- SOL-154871: Remove the Entra laptop lab from the public repo by @amitmorade in #448
- SOL-154365: expose a test-only reset for the panics package counter by @solace-awaheed in #449
- SOL-153116: Re-organize README Quickstart into a single happy path by @McCly-Solace in #444
- Bump the go-minor-patch group across 1 directory with 6 updates by @dependabot[bot] in #435
- SOL-153071: fix list-vpns zeroConnectionCount false positives by @McCly-Solace in #437
- Bump github.com/modelcontextprotocol/go-sdk from 1.7.0 to 1.8.0 in /test/e2e-basic-mcp/agent in the go-minor-patch group by @dependabot[bot] in #434
- chore(DATAGO-154672): split internal GitHub Actions updates and drop their cooldown by @artyom-morozov in #456
- SOL-154894: rewrite operator observability docs as a shipped snapshot by @amitmorade in #451
- SOL-154398: Entra 2: Optional tool RBAC honors one named inbound claim by @solace-lootii in #453
- SOL-152815: hold image publish on the LLM eval suite by @amitmorade in #450
- SOL-154654: rename Hop 2 auth.audience to auth.target and drop audien… by @solace-awahe...
v0.9.0
[0.9.0] - 2026-09-11
Added
-
Three new Prometheus gauges expose passive per-broker reachability on
/metrics(SOL-152088,metrics_schema1.2→1.3):mcp_broker_reachable{broker}(1 when last SEMP call succeeded, 0 otherwise),mcp_broker_unreachable_reason{broker,reason}(one-hot across all failure reasons ever seen —credential_invalidfor 401/403,unreachablefor transport failures,broker_error_NNNfor 5xx/429), andmcp_broker_last_result_timestamp_seconds{broker}(Unix timestamp of the most recent result, for detecting silently idle brokers). All three are updated passively from real SEMP calls with no added broker load and no heartbeat goroutine. They are decoupled from/readyz(ADR-004): a broker outage sets the gauge to 0 but never marks the MCP pod unready. -
Three new write/read tools close the gap where a queue created through
create-queuehad no way to be given a topic subscription without leaving the MCP tool set:create-queue-subscription,delete-queue-subscription, andlist-queue-subscriptions. Without a subscription a queue attracts no messages regardless of its other settings, socreate-queue's description now namescreate-queue-subscriptionas the required follow-up rather than leaving the caller to discover the gap by failure.create-queue-subscription/delete-queue-subscriptionfollow the flat-sub-resource-tool convention (one MCP tool per SEMP operation on the sub-resource, not a nested parameter oncreate-queue): a queue's subscriptions are added and removed over its lifetime, and the SEMPv2 create/delete operations forMsgVpnQueueSubscriptiontake one topic at a time — there is noupdate-queue-subscription, since a subscription is immutable (SEMP has no update operation for it; changing one is delete-and-recreate). Both accept Solace wildcards (>,*) insubscriptionTopic, which can contain/— the first MCP tool parameter in this codebase to put an arbitrary, slash-bearing string into a SEMP path segment (delete-queue-subscription's URL).list-queue-subscriptionsverifies the queue exists before listing (amonitor/getMsgVpnQueuepreflight step): SEMP's own collection GET returns200with an empty list for a nonexistent queue, which would otherwise be indistinguishable from "queue exists, has no subscriptions" — the preflight surfaces the broker's own not-found error instead.delete-queue's description and confirmation preamble now state that deleting a queue also removes any subscriptions attached to it, since deleting a queue cascades to its subscriptions with no separate detach step and no error if it does.delete-queue-subscription's own confirmation preamble likewise now states the silent-traffic-loss consequence in the restate clause itself (previously only in the description body, so the model wasn't instructed to say it back to the user before proceeding). Tracked under SOL-153868. -
Every release now publishes a CycloneDX SBOM (
solace-broker-mcp-<tag>.cdx.json), generated bycyclonedx-gomod(pinnedv1.10.0, matching this repo's Go version) against the same dependency closureTHIRD_PARTY_LICENSES.mdinventories, checksummed alongside the binary archives. A new.github/scripts/sbom-check.sh(with its own self-test,sbom-check.test.sh) verifies the SBOM's dependency set matchesTHIRD_PARTY_LICENSES.mdbefore it's attached — resolving both sides to their Go module first, since the SBOM lists components at module granularity while the document lists some rows a package deeper (e.g.golang.org/x/sys/cpuinside modulegolang.org/x/sys), which a naive string comparison would misread as drift on every run. Per SOL-148440, the SBOM does not gate on its own absence —cyclonedx-gomodfailing degrades the release to "no SBOM attached," never "no release" — but once an SBOM exists, a real divergence fromTHIRD_PARTY_LICENSES.mddoes fail the release, the same as any other compliance drift here. -
New
deploy/kubernetes/ingress.yaml.example, anddocs/authentication.md§ "Session Routing at the Ingress" documenting it as a required step rather than a caveat. Now that the manifests default toreplicas: 2(SOL-152089), an operator following the TLS-terminated-upstream pattern gets a deployment that fails on essentially the first call: an Ingress load-balances to pod IPs and so bypasses the Service'ssessionAffinity: ClientIP, and MCP sessions live in a single pod's memory, so each call after initialize has roughly a1/replicaschance of reaching the pod that owns the session — a 10-call session survives with probability(1/2)^10≈ 0.1%, and worse in practice, since nginx's default round-robin is deterministic rather than random. The working annotation isnginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr", which restores at the ingress whatsessionAffinity: ClientIPgave on the ClusterIP path, inheriting its NAT caveat. The docs now also name the two configurations that look correct and silently are not: cookie affinity, which needs a cookie jar no MCP client has, and hashing on$http_mcp_session_id, which fails because the initialize POST carries no such header — the server mints the ID onto the response, so that request hashes on an empty key and lands anywhere while the ID it returns hashes independently, stranding half of all sessions at two replicas. Gateway API'ssessionPersistencefails for the same reason cookies do; controller-specific source-address hashing is the portable answer. The example routes the whole/.well-knownprefix rather than just/.well-known/oauth-protected-resource, because clients probe several paths under it before they hold a token and the server answers the unregistered ones with a JSON 404 that nginx's plain-text default backend would otherwise replace;/livezand/readyzare deliberately left unexposed. Named.exampleso the directory-widekubectl applyskips it. Documentation and example manifests only — no code change. Tracked under SOL-153834. -
New
THIRD_PARTY_CLASSIFICATION.md: a committed green/yellow/red classification of every dependency in the shipped closure, sourced directly from FOSSA's policy result forSolaceProducts_solace-broker-mcp(Issues tab: zero active violations) rather than inferred from licence type alone. Zero dependencies are classified red, stated explicitly. The two MPL-2.0 dependencies (github.com/hashicorp/go-cleanhttp,github.com/hashicorp/go-retryablehttp) are classified yellow, per policy — see that file for approval status. Unlike the SBOM, this file is a committed snapshot, not a generated artifact — a yellow approval is a human decision that must survive a re-run. Tracked under SOL-153188. -
A Prometheus-format
/metricsendpoint is now served on a dedicated listener (default:9091), separate from the main MCP port, so operators can apply an independent network policy to metrics scraping without changing MCP traffic rules. The capability is gated by the newOBS_METRICS_ENABLEDenvironment flag and is off by default (v1 door-closing policy): when off, no second listener is started and no instruments are registered; when on, the listener is registered as a requiredmetrics_endpointreadiness probe, so a bind failure (for example, the port already in use) surfaces on/readyzasmetrics_endpoint: <err>instead of failing silently. The bind address is configurable through the newobservability.metrics_bind_addressYAML field (default:9091,${VAR}substitution supported). When metrics are enabled, config load now rejects ametrics_bind_addressthat shares the MCP server's own port — the two listeners would otherwise race for it at startup, and the loser, being a required readiness probe, would hold/readyzunready and crash-loop the pod; the guard is wildcard-aware ("",0.0.0.0,::overlap any host on the same port), and the:9090/:9091defaults never collide. The endpoint serves Go runtime and process collectors plus three self-observation instruments —mcp_build_info{version},mcp_schema_version{metrics_schema,audit_schema}, and themcp_metrics_scrape_totalcounter — on an OpenTelemetry meter provider that later metrics work registers additional instruments against; OpenMetrics exposition is enabled on the handler. Tracked under SOL-152091. -
On graceful shutdown, the metrics meter provider (SOL-152091) is now flushed and stopped through the shared shutdown-hook registry (SOL-152449). The Prometheus exporter is pull-based, so nothing is buffered to lose today — this is for a clean shutdown and to carry any future push-based exporter. Tracked under SOL-153884.
-
An OpenTelemetry tracer provider with OTLP gRPC export is now wired at startup, gated by
OBS_TRACING_ENABLED(off by default, door-closing policy): off,Newdoes nothing, leaving the OTel API's own non-recording global default in place; on, it installs a real provider, so the span-instrumentation stories that follow (MCP entry, executor, SEMP-per-attempt, retry, token-exchange spans) callotel.Tracer(name)today with no wiring of their own. OTLP endpoint and TLS come from the standardOTEL_EXPORTER_OTLP_ENDPOINT/OTEL_EXPORTER_OTLP_INSECUREenv vars with no code in this binary. Sampling honorsOTEL_TRACES_SAMPLER/OTEL_TRACES_SAMPLER_ARGwhen both are set; with neither set, the SDK's own default applies (parentbased_always_on— sample everything, the v1 pilot intent), andOTEL_TRACES_SAMPLER_ARGalone, with noOTEL_TRACES_SAMPLER, is not read at all — set both together, perdocs/observability.md. Two new self-observation instruments,mcp_otel_spans_exported_totalandmcp_otel_spans_dropped_total{reason}(export_timeout,export_error,shutdown, and a reservedqueue_full— see the known limitation below), register against the metrics meter provider (SOL-152091) whenever one exists; otherwise (metrics off, or its endpoint failed to start) a periodic `event=otel_s...
v0.8.0
What's new in 0.8.0
Stricter output contracts on the write tools, a faster CallTool path, four security
hardening fixes, and the embedded SEMPv2 specs moved to the 10.26.4 rolling release.
The full, verbose entry for each item is in
CHANGELOG.md.
Added
make refresh-third-party-inventoryregeneratesTHIRD_PARTY_LICENSES.mdand
THIRD_PARTY_BUILD_TEST.mdfrom what the repository actually uses, instead of
hand-deriving the dependency closure. It rewrites only the rows that actually
changed and refuses outright — leaving the files untouched — on anything it
doesn't recognize. Still a manual step on Dependabot PRs.
Changed
- Embedded SEMPv2 OpenAPI specs updated to the 10.26.4 rolling release
(10.26.4.10725), so tool schemas track current broker attributes. - The eight create/update composite tools (
create-message-vpn,update-message-vpn,
create-queue,update-queue,create-topic-endpoint,update-topic-endpoint,
create-rdp,update-rdp) now declare strict, spec-derived output schemas that
reject undeclared fields and require the resource's own identifier. A future SEMP
release that reshapes a response field now fails validation instead of silently
passing through. Read-only tools are unchanged. - Each tool's input/output JSON Schema is now compiled once at registration rather
than re-compiled on everyCallTool. Internal change only — the on-the-wire MCP
schemas, tool behavior, and response bytes are unchanged. - A
/mcprequest body over the 4 MiB cap that doesn't declare an oversized
Content-Lengthnow returns413instead of400. The negotiated protocol
revisions are unchanged by the underlyinggo-sdkv1.7.0 bump. THIRD_PARTY_LICENSES.md's source of truth is now documented as the Go module
graph, replacing the standing instruction to hand-reconcile it against the FOSSA
scan. FOSSA remains the authoritative policy gate.- The release pipeline now executes every matrix leg's archived binary before it can
publish, asserting a clean exit and a version matching the tag — closing a gap
where cross-compileddarwin/arm64andlinux/arm64archives were never run.
Fixed
- The token-exchange circuit breaker's
consecutive_failure_thresholdrule now trips
on a slow, low-traffic IdP outage, not only a fast-failing one. Its state-change
WARNalso now carries aconsecutive_failuresattribute, so an operator can tell
which rule opened the breaker from the log line alone. - OAuth Protected Resource Metadata is now also served at the RFC 9728 canonical path
/.well-known/oauth-protected-resource/mcp. Clients that follow the
WWW-Authenticatechallenge verbatim are unaffected; clients that build the
canonical path directly now get a 200 instead of a 404. CallToolnow returns a structured tool result (isError: true, withretryable)
instead of a bare JSON-RPC protocol error on every local failure path — unknown
broker, schema validation, nil/invalid result, marshal failure. This matters most
for destructive tools, where the broker-side action may already have succeeded by
the time the failure is caught.
Security
-
Cross-origin protection on
/mcpnow runs outside the auth middleware. A
browser-initiated cross-origin POST or DELETE gets the403it earned — before any
JWT or JWKS work — instead of a401that masked a CSRF-shaped probe as an ordinary
auth failure. What passes on the wire is otherwise unchanged; protection stays on by
default with no new configuration. -
Broker URLs logged at four runtime sites now go through the same sanitizer
BrokerConfig.LogValuealready applied, rather than being logged raw.
Defense-in-depth: config-load validation already rejects embedded userinfo. -
Token exchange now logs a diagnostic
WARNwhen the IdP-issued token'saudclaim
doesn't include the audience this process requested, surfacing an inert per-broker
audience config. It never fails the exchange. The exchange dedup/cache key now
includes the requested audience. -
The container health check (
--health) now verifies the server's TLS certificate
instead of accepting any certificate, closing CWE-295.Upgrading a TLS-enabled container: the probe now reports unhealthy — while the
server keeps serving TLS correctly — if the certificate attls_cert_fileis
unreadable from the probe's process, carries no DNS or IP SAN, has expired, or is not
the one the server presents. Failure reasons go to stderr, which Docker records in
State.Health.Log.
What's Changed
- SOL-152372 test: add stub AccessLevelGroups to opt-in ToolAuthorization subtests by @amitmorade in #292
- Bump github.com/modelcontextprotocol/go-sdk from 1.6.1 to 1.7.0 in the go-minor-patch group by @dependabot[bot] in #289
- SOL-153050: retire the DCO workflow, keep the identity check it carried by @bczoma in #294
- SOL-153050: state the registered ruleset, not the work to register it by @bczoma in #298
- Bump the github-actions group across 1 directory with 5 updates by @dependabot[bot] in #295
- SOL-151996: Backfill get-redundancy-status parser tests with active/standby (HA) fixtures by @helen-zhu-solace in #300
- SOL-152979: sanitize broker URLs in log output as defense-in-depth by @solace-aross in #279
- SOL-153089: Publish PRM at the RFC 9728 canonical path (keep WWW-Authenticate URI unchanged) by @solace-wmaryam in #297
- SOL-152856: Add a required CI gate that runs actionlint and zizmor over every GitHub Actions by @solace-awaheed in #299
- SOL-152286: Track consecutive exchange failures outside gobreaker so slow outages trip the breaker by @amitmorade in #296
- SOL-153167: verify the server certificate in the --health probe by @bczoma in #301
- SOL-152980: return structured results, not bare errors, from CallTool's local failure paths by @solace-aross in #280
- SOL-152971: Restore cross-origin protection on the /mcp endpoint by @helen-zhu-solace in #303
- SOL-152947: SEMPv2 config/action output-schema drift guard (write tools) by @solace-lootii in #302
- SOL-152981: warn on token-exchange audience mismatch; include audience in dedup key by @solace-aross in #281
- SOL-153184: Create daily job that runs in GHA for e2e-llm by @helen-zhu-solace in #305
- SOL-153255: Refresh understand-anything knowledge graph by @solace-aross in #307
- Bump the github-actions group with 5 updates by @dependabot[bot] in #304
- SOL-153086: Give fork pull requests a vulnerability verdict before merge by @solace-awaheed in #306
- SOL-153285: Update allowrance words in d1 scenario for e2e-llm by @helen-zhu-solace in #309
- SOL-152741: KTLO: Upgrade MCP Go SDK to v1.7.0 and pin E2E to protocol revision 2025-11-25 by @helen-zhu-solace in #310
- Bump github.com/getkin/kin-openapi from 0.145.0 to 0.146.0 in the go-minor-patch group by @dependabot[bot] in #312
- SOL-153190: Settle third-party licence inventory source of truth by @solace-lootii in #313
- SOL-153189: Smoke-test every release archive and surface the released version in the README by @solace-lootii in #311
- SOL-153334: cache compiled JSON-schema validators per tool by @solace-aross in #314
- SOL-153359: Gitignore make build's binary output at the repo root by @bczoma in #318
- SOL-153337: Update e2e-llm scenarios and reduce flakey runs by @helen-zhu-solace in #321
- SOL-152956: Add make refresh-third-party-inventory to close the drift-gate toil by @solace-lootii in #316
- Update SEMP schemas to latest rolling release (10.26.4) by @solace-wmaryam in #319
- SOL-152858: Document the static-analysis posture and the required CodeQL check by @bczoma in #323
- SOL-153346: Add a Claude Code skill for third-party inventory refresh by @solace-lootii in #317
- SOL-153335: verify composite output schema is not rebuilt per call by @solace-aross in #315
- SOL-152974: Adopt GitHub merge queue by @solace-awaheed in #322
- SOL-153411: Migrate CodeQL to advanced setup with a blocking gate job by @bczoma in #325
- Bump the g...
v0.7.1
[0.7.1] - 2026-08-11
v0.7.0 was tagged but its release pipeline failed before publishing anything, so it has no binary archives, no container image, and no GitHub Release — only a git tag and a Go module version. 0.7.1 is the first published release of the 0.7 line, and because git history is cumulative it contains everything listed under 0.7.0 below in addition to the change here. Anyone looking for 0.7.0 downloads wants 0.7.1.
Taken together with 0.7.0, this is the first release published from the public repository, and the first whose artifacts can be verified: every binary archive and the container image now carries a build provenance attestation tracing it to the workflow run and commit that produced it, with the commands in README.md. Also new since 0.6.0 — the describe-semp-schema tool, which lets an agent enumerate a SEMPv2 operation's configurable attributes before attempting a write; an optional filter_tools_list flag narrowing tools/list to what the caller is actually authorized to invoke; and a second third-party inventory, THIRD_PARTY_BUILD_TEST.md, covering the components used to build and test the project rather than ship in it.
Two breaking changes, both from the move to the SolaceProducts GitHub organization. The Go module path is now github.com/SolaceProducts/solace-broker-mcp. The container image is published to ghcr.io/solaceproducts/solace-broker-mcp — and the old path does not fail loudly, it keeps serving the last image pushed there, so a stale reference silently stops receiving updates. Migration notes are in the Changed section under 0.7.0.
Changed
- Updated the embedded SEMPv2 OpenAPI specs to the 10.26.3 rolling release (
10.26.3.10320), so tool schemas track current broker attributes. The three spec files are renamed tosemp-v2-swagger-{action,config,monitor}.10.26.3.jsonand continue to be sourced from the private-extended variant. Loading is unaffected — specs are picked up by the embed glob and typed from theirbasePath, not their filename. Tracked under SOL-152939.
What's Changed
- SOL-152939: Update SEMP schemas to latest rolling release (10.26.3) by @solace-wmaryam in #290
- ci(DATAGO-148031): forward secrets to Guardian scan via workflow_call by @artyom-morozov in #291
- Prepare release v0.7.1 by @bczoma in #293
Full Changelog: v0.7.0...v0.7.1
v0.6.0
[0.6.0] - 2026-07-28
Added
- Broker
auth.mode: oauth(RFC 8693 token exchange, "Hop 2") is now a fully supported broker authentication mode alongsidebasicandbearer. A broker configured withauth.mode: oauthobtains its broker-bound token by exchanging the calling agent's Hop 1 token via thebroker_oauth:block's IdP coordinates — seedocs/authentication.mdfor the full Hop 1 / Hop 2 model, config shape, and operational behavior (retries, circuit breaker,Retry-Afterhandling, token caching).mcp_client_auth.mode: oauthis required whenever any broker usesauth.mode: oauth, since Hop 2 consumes the agent's Hop 1 token as the RFC 8693subject_token. - New MCP tools
list-kafka-receivers,get-kafka-receiver-status,list-kafka-senders, andget-kafka-sender-statusfor Kafka Receiver/Sender monitoring — the same list-then-drill-down pattern aslist-rdps/get-rdp-statusandlist-bridges/get-bridge-status. A Kafka Receiver pulls messages from an external Kafka cluster into a Message VPN; a Kafka Sender pushes messages from a VPN's queues out to an external Kafka cluster. Unlike bridges' two-directional connection-state model, both objects use a singleup/enabled/failureReasonstatus shape (the same shape as RDPs) and a single-name identifier (kafkaReceiverName/kafkaSenderName, not a compound key).list-kafka-receivers/list-kafka-sendersreturn up to 100 by default (max 500 viamaxResults), with a summary block (downCount,disabledCount,byFailureReason);get-kafka-receiver-status/get-kafka-sender-statusreturn additional per-object detail including topic-binding status (topicBindingUpCount/topicBindingCount) or queue-binding status (queueBindingUpCount/queueBindingCount). Read-only monitoring only; write tools and live-broker E2E fixture coverage are deferred to follow-up tickets. Unlike bridges, this implementation is spec-derived rather than lab-verified: neither lab appliance available at implementation time (sempVersion 100.0main.0.7305and10.26.0.8586) exposes thekafkaReceivers/kafkaSendersSEMP paths at all, so whetherfailureReasonreliably populates on a real down receiver/sender — versus staying empty the way bridges'inboundFailureReasondid — remains unconfirmed; a follow-up should verify against a broker with the feature licensed/enabled. Tracked under SOL-152328. - New MCP tools
list-bridgesandget-bridge-statusfor Bridge monitoring — the same list-then-drill-down pattern aslist-rdps/get-rdp-status.list-bridgesreturns enabled state, inbound/outbound connection state, and last inbound failure reason for every bridge in a VPN (default 100, max 500 viamaxResults), with a summary block (downCount,disabledCount,byInboundFailureReason).get-bridge-statusreturns additional per-bridge diagnostic detail — connection establisher, failure category, and client name — for one bridge, identified bymsgVpnName+bridgeName+bridgeVirtualRouter(bridges are the only object in this server keyed by two names rather than one, since a bridge's config can differ between a broker's primary and backup virtual router in an HA pair). Tracked under SOL-152124. - Process-level circuit breaker in front of RFC 8693 token exchange to the IdP, so a sustained IdP outage fails fast instead of driving every broker's requests into the full retry/timeout budget. One breaker per process guards the single shared IdP; because the deployment has one IdP, one client credential, and one shared availability dependency, all brokers and tenants share it. A "request" for the breaker is one complete logical exchange after the retry loop has finished — a chain that retries a 5xx three times before giving up records one failure, not three. Failure classification is owned by the server, not the operator: transient network errors, upstream 5xx, and response-body-read failures count toward the breaker; HTTP 429 is excluded (the IdP is reachable and throttling, so counting it would let one tenant's rate-limit trip the shared breaker); token rejections, caller cancellations, and local request-build errors are excluded (they say nothing about IdP availability). Endpoint misconfiguration — an untrusted/expired TLS certificate, a hostname mismatch, or a DNS name-not-found for the configured IdP — is also excluded: it is a permanent operator fault, not an outage, and counting it would let one bad config value trip the shared breaker for every tenant with no chance to heal (a DNS timeout, by contrast, is transient and does count). Once open, exchanges are rejected immediately with a new
ErrExchangeCircuitOpensentinel — classified transient like a transport failure but distinct in the audit line ("we did not try" vs. retries-exhausted's "we tried and gave up"); state transitions log at WARN. Configured under a new optionalbroker_oauth.circuit_breaker:block (nested there because the breaker only protects OAuth token exchange, which exists only whenbroker_oauthdoes):enabled(default true;falseis an operational escape hatch that disables the breaker while leaving retries intact and logs a WARN),failure_rate_window,minimum_requests,failure_rate_threshold_percent,consecutive_failure_threshold(fast-trips a fast-failing outage without waiting for the rate rule's sample; the count is window-bound, so failures spaced out by long retry chains may not accumulate;0disables it),open_state_duration, andhalf_open_probe_requests. Every field is optional and falls back to a production-safe default, so omitting the block (or the whole thing) yields the shipped defaults with the breaker on; out-of-bounds values are rejected at config load alongside every otherbroker_oautherror. The internal bucket granularity and breaker name are derived, not operator-configurable. Tracked under SOL-151600. - Shared, process-wide backoff that honors an IdP's
Retry-Afterheader on an exhausted RFC 8693 token-exchange 429 chain, closing a gap in the circuit breaker's 429-exclusion policy (SOL-151600): because a 429 is deliberately excluded from breaker failure counting, and gobreaker refunds a half-open probe slot for excluded outcomes, a still-throttling IdP could previously admit unbounded sequential probes with no pacing between them.Retry-Afteris parsed per RFC 9110 §10.2.3 (both delta-seconds and HTTP-date forms; an HTTP-date at or before the current instant, or a negative delta-seconds value, floors to no gate rather than a negative one, so IdP clock skew cannot produce a nonsensical result) only when a 429 retry chain fully exhausts — not on an intermediate 429 a later retry in the same chain resolves — and only holds off subsequent exchange calls; it does not change the 429-excluded classification itself, nor retry pacing within a single exchange's own chain (which already honorsRetry-Afteruncapped per SOL-151520 and is unaffected). The gate is shared across every broker and tenant, deliberately: it sits in front of the same one-shared-IdP circuit breaker (SOL-151600), so a 429 from one broker's exchange paces back every other caller against that IdP, not just the one that triggered it. A gated call fails fast with a newErrExchangeRateLimitedsentinel — distinct fromErrExchangeCircuitOpenso an operator (or alerting keyed on either) can tell "the IdP is unhealthy" apart from "the IdP is healthy but asked us to wait" — before any breaker bookkeeping or IdP round-trip occurs. The honored duration is capped (default 60s, double the breaker's default 30s open-state window) via a new optionalbroker_oauth.retry_after:block with a singlemax_honored_durationfield; omitting the block or the field keeps the shipped default, and an operator-set value replaces it entirely in both directions (a smaller cap can clamp tighter than the default, a larger one can honor longer). Three distinct WARN log lines cover the operator-visible outcomes on every exhausted 429 chain: the gate was set (with the honored duration and expiry), the gate was set but the IdP's requested duration was clamped to the configured cap, or the gate could not be set at all because the IdP sent noRetry-After(or sent one that didn't parse) — the last of these is called out explicitly because it means this protection cannot engage for that IdP, distinct from a routine "everything working as intended" log line. Tracked under SOL-152285. - Server-side retry loop for RFC 8693 token exchange to the IdP. Previously a single 5xx, HTTP 429, or connection error to the IdP failed the tool call outright; the loop now transparently retries up to three attempts total against transient signals (5xx, 429, and connection-level errors — DNS, TLS handshake, body-read partials), honoring the IdP's
Retry-Afterheader uncapped between attempts via jittered linear backoff. 4xx client errors (400, 401, 403) are deliberately not retried — they will not fix themselves on repeat. The whole retry loop is fenced by a chain-deadline (context.WithTimeoutderived from the retry knobs — currently 19s worst case with the shipped defaults of 5s per attempt, 2 retries, and 1–2s backoff), which also bounds a hostileRetry-Aftervalue. When all attempts fail, a newErrExchangeRetriesExhaustedsentinel distinguishes "we tried and gave up" from a single-shot transport failure; the last attempt's HTTP status and IdP endpoint survive on the same*ExchangeErrorenvelope for the audit line. JWKS refresh and OIDC discovery paths deliberately keep the non-retrying HTTP client — they are read-only lookups where a single failure is the correct signal. Tracked under SOL-151520. - New top-level
tool_authorization:configuration block for per-tool authorization based on the caller's group or role memberships as carried by a configurable OIDC claim. Required undermcp_client_auth.mode: oauthand refused under any other mode — theenabledfield must be set explicit...
v0.5.0
What's Changed
- SOL-150717: Add unit test for auth mode: disabled (no-auth-required p… by @solace-wmaryam in #107
- SOL-150878: Fix flakey slow-subscriber, clean up e2e-monitoring and gitignore by @helen-zhu-solace in #108
- SOL-150796: add OAuth broker config schema (mcp_client_auth rename, banner consolidation) by @amitmorade in #110
- SOL-150797: capture raw subject token on ctx after SDK validation by @amitmorade in #111
- SOL-151114: F7-ttl fixture flaky in e2e-monitoring: maxTtlExpiredDiscardedMsgCount stays 0 by @helen-zhu-solace in #113
- SOL-150799 (T5 prep): extract internal/idpclient by @amitmorade in #114
- SOL-148462: Implement Action Tools (Queue Actions, Client Actions) by @solace-lootii in #88
- SOL-151052: Implement composite-tool postprocessor + first handler for list-queues by @helen-zhu-solace in #112
- SOL-150789: Productionize the LLM e2e eval harness (Mode 2) by @helen-zhu-solace in #106
- SOL-151278: Observability package skeleton and flag plumbing by @solace-aross in #115
- SOL-151283: /livez endpoint with /health as alias by @solace-aross in #116
- SOL-151279: Correlation-ID HTTP middleware by @solace-aross in #118
- SOL-151286: HTTP panic-recovery middleware (whole-mux, unconditional) by @solace-aross in #122
- SOL-151284: /readyz endpoint reflecting MCP-server readiness (decoupled from broker) by @solace-aross in #123
- SOL-151281: forward correlation ID to SEMPv1/v2 broker requests by @solace-aross in #125
- SOL-150799: RFC 8693 token-exchange Exchanger (T5) by @amitmorade in #131
- SOL-151282: return correlation ID in MCP response header and CallToolResult.Meta by @solace-aross in #126
- SOL-151288: SIGTERM in-process drain (/readyz 503 → sleep → graceful shutdown) + terminationGracePeriodSeconds by @solace-aross in #130
- SOL-150690: Add listen_address server config with loopback default fo… by @solace-awaheed in #133
- SOL-151280: emit correlation_id as a slog attribute on every request-scoped log line by @solace-aross in #129
- SOL-150860: complete remaining user documentation by @solace-aross in #117
- SOL-151468: lift SafeCookieJar to broker level, delegate 401 recovery to Authenticator by @amitmorade in #136
- SOL-150260: report accurate live queue depth by @solace-lootii in #137
- SOL-151315: list-slow-subscribers aggregations by @helen-zhu-solace in #135
- SOL-151285: k8s split probes + startupProbe; alias /ready to /readyz by @solace-aross in #127
- SOL-148460: Implement Core Management tools (VPN, Queue) by @solace-wmaryam in #124
- SOL-151316: list-queue-discards aggregations by @helen-zhu-solace in #134
- SOL-151314: list-vpns aggregations by @helen-zhu-solace in #132
- SOL-151313: list-rdps aggregations by @helen-zhu-solace in #128
- SOL-150800, SOL-150801: OAuthAuthenticator, exchanger wiring, and exchange error visibility by @amitmorade in #138
- fix(sempv1): bound broker error text at capture [SOL-151516] by @solace-aross in #140
- fix(safego): recover panics in errgroup worker goroutines [SOL-151514] by @solace-aross in #139
- SOL-148461: Adding RDP Write Tools by @solace-awaheed in #144
- fix(config): refuse insecure broker TLS in production unless opted in [SOL-151517] by @solace-aross in #141
- SOL-151343: get-rdp-status aggregations by @helen-zhu-solace in #145
- fix(resilience): bound the overall SEMP retry chain with a deadline [SOL-151518] by @solace-aross in #142
- SOL-151574: gate Hop-2 OAuth runtime resources on ENABLE_UNRELEASED_BROKER_OAUTH by @amitmorade in #147
- SOL-151552: Unify downCount semantics across list-* aggregating tools by @helen-zhu-solace in #148
- feat(cmd/server): second signal forces immediate shutdown [SOL-151437] by @solace-aross in #143
- SOL-151506: harden BasicAuthenticator with nil-jar panic by @amitmorade in #149
- SOL-151627: fix latent SA5011 nil-deref warnings in test files by @amitmorade in #152
- ci(lint): disable stale analysis cache and uncap issue reporting by @amitmorade in #157
- SOL-151500: Extract shared field-coercion helpers into one file for postprocess aggregation handlers by @helen-zhu-solace in #153
- SOL-151442: add in-memory OAuth token cache with exchanger wiring by @amitmorade in #150
- SOL-150725: E2E functional tests for MCP server management tools (manage-vpn, manage-queue) by @solace-wmaryam in #154
Full Changelog: v0.4.0...v0.5.0
v0.4.0
What's Changed
- SOL-150025: E2E functional tests for all supported MCP server monitoring tools by @helen-zhu-solace in #82
- SOL-150440: Add 4 new tools to README and user-guide tools reference by @solace-lootii in #83
- SOL-150248: Refactoring e2e-basic-mcp, docs, and health by @helen-zhu-solace in #84
- SOL-148434: Implement Error Translation and Output Sanitization by @solace-wmaryam in #85
- SOL-148434: Implement Error Translation and Output Sanitization by @solace-wmaryam in #87
- SOL-150663: Truncate broker-controlled error text at capture by @solace-aross in #92
- SOL-150660: Cap inbound /mcp request body at 4 MiB by @solace-aross in #89
- SOL-150664: Enable retries for read-only SEMPv1 show commands by @solace-aross in #93
- SOL-150661: Close response body when SEMP retries are exhausted by @solace-aross in #90
- SOL-150665: Enforce per-broker connection bound via MaxConnsPerHost by @solace-aross in #94
- SOL-150666: Keep secrets out of YAML config parse errors in startup logs by @solace-aross in #95
- fix(tools): recover tool-handler panics instead of crashing the server [SOL-150685] by @solace-aross in #96
- SOL-150689: Fix flaky e2e-monitoring F4 txMsgRate assertion (get-message-rates) by @helen-zhu-solace in #100
- SOL-150707: Updating get-broker-health to be get-broker-status by @solace-awaheed in #99
- fix(semp): enforce MaxConcurrentPerBroker with shared in-flight semaphore [SOL-150116] by @solace-aross in #97
- Freshen agent context: CLAUDE.md commands and tool guidance, fix architecture.md drift by @solace-aross in #98
- SOL-150749: Re-arm F6 slowSubscriber flag before Tool 10 assertions (fix flaky e2e-monitoring) by @solace-aross in #101
- SOL-150724: Add get-broker-status in e2e-monitoring by @helen-zhu-solace in #102
- docs: add RELEASING.md describing the release model by @solace-aross in #86
- SOL-150815: Add logging to e2e-monitoring for list-slow-subscribers by @helen-zhu-solace in #103
- SOL-150708: Creating get-hardware-details step for appliances by @solace-awaheed in #104
- Authenticator interface and SEMP protocol-client migration (SOL-150794, SOL-150795) by @amitmorade in #105
Full Changelog: v0.3.0...v0.4.0
v0.3.0
What's Changed
- SOL-149478: MCP minimum documentation to support release by @solace-wmaryam in #57
- fix(server): close broker pool on graceful shutdown [SOL-149926] by @solace-aross in #59
- fix(config): redact userinfo in broker-URL validation errors [SOL-149923] by @solace-aross in #56
- SOL-149904: Skip env var substitution in YAML comments by @solace-aross in #60
- fix(semp): wrap cookie jar in atomic SafeCookieJar to remove 401 race [SOL-149922] by @solace-aross in #55
- SOL-149989: Consolidate client auth config to single client_auth.mode enum by @solace-aross in #62
- fix(semp): cap broker response body at 16 MiB [SOL-149920] by @solace-aross in #54
- fix: cap semp.max_concurrent_per_broker at 1024 [SOL-149924] by @solace-aross in #51
- fix(server): set ReadTimeout and IdleTimeout on the MCP HTTP server [SOL-149914] by @solace-aross in #53
- fix(semp): set granular timeouts on the SEMP HTTP transport [SOL-149925] by @solace-aross in #58
- test(config): add client_auth.mode to PR 51's max-concurrent fixtures [SOL-150117] by @solace-aross in #66
- SOL-150126: Refactor directory structure of the test folder by @helen-zhu-solace in #65
- chore: add Makefile with build/test/lint/docker targets by @solace-aross in #68
- SOL-150167: fix broken broker healthcheck in e2e-basic-mcp by @helen-zhu-solace in #70
- chore: ignore git worktree directories by @solace-aross in #69
- SOL-149789: Define and enforce a contract for broker aliases by @amitmorade in #64
- fix(config): warn on insecure_skip_verify=true in production mode [SOL-149928] by @solace-aross in #52
- SOL-150200: Backport E2E harness cleanups by @helen-zhu-solace in #73
- fix(config): reject unknown YAML fields in config decoder [SOL-149927] by @solace-aross in #49
- docs(readme): add scannable tools table after Quickstart by @solace-aross in #77
- SOL-148426: Implement Basic Health Endpoints by @solace-wmaryam in #67
- SOL-150064: Restore e2e OAuth integration test — add TLS to test Keycloak by @solace-wmaryam in #72
- DOC-8001: Docs edits on 4 md files by @SeanWray89 in #63
- SOL-149606 Capture per-user identity in tool-invocation audit logs (production OAuth mode) by @amitmorade in #74
- SOL-150316: Removing get-dmr-status tool by @solace-awaheed in #78
- fix(auth): bound OIDC HTTP client timeout for JWKS refresh [SOL-150219] by @solace-aross in #75
- SOL-150024: E2E Monitoring Suite by @helen-zhu-solace in #71
- SOL-150080: Adding SAM integration to the docs by @solace-awaheed in #76
- SOL-150328: Fix slow-consumer detection clarity in broker MCP tools by @solace-awaheed in #79
- SOL-150344: Update slow-consumer and clean up e2e-monitoring test by @helen-zhu-solace in #81
- SOL-150364: add followPages, fix per-page count for list-client-subsc… by @solace-awaheed in #80
- SOL-148432: Implement Advanced Monitoring Tools (Replication, Discards, Slow Subscribers) by @solace-lootii in #61
New Contributors
- @SeanWray89 made their first contribution in #63
- @solace-awaheed made their first contribution in #78
Full Changelog: v0.2.0...v0.3.0