Repository navigation
v1.8.6
[1.8.6] — 2026-10-08
serve over HTTP admits clients by network address: /mcp no longer rejects a foreign Host.
Fixed
- A
servenode listening on a network address rejected every external MCP client. The/mcproute is protected against DNS rebinding: rmcp admits only theHostvalues listed in its configuration, and that list defaults to loopback only (localhost,127.0.0.1,::1).serve_httppassed the default configuration and there was no way to extend the list: a client connecting by the server's address (--host 0.0.0.0or[me].ipinserve.toml) got403 Forbidden: Host header is not allowed, withrejected request with disallowed Host header (possible DNS rebinding attempt)in the log. The federation layout hid this: inter-node traffic goes over/federate/*, which does not pass through rmcp, and MCP clients connected to127.0.0.1. Now the defaults are extended with the bind address (--hostor[me].ip, except0.0.0.0and::), the[me].allowed_hostslist fromserve.toml, and theCODE_INDEX_ALLOWED_HOSTSenvironment variable (the same values, comma-separated; it also works in single-repository mode, whereserve.tomlis not read). The check is never disabled: a value neither listed nor among the defaults still gets403.
Compatibility
- A
serve.tomlwithout[me].allowed_hostsparses as before; where clients connect over loopback, behaviour is unchanged. - The list is assembled at service startup: editing
[me].allowed_hostsor the environment variable is applied by restartingserve— as with[me].ipand[pool].
Verification
- A locally built release
bsl-indexer1.8.6 against the same index and database as the live serve; for contrast, the same node and the same registry on the 1.8.5 release asset. Before the fix: aHostheader carrying the node's address —403 Forbidden: Host header is not allowed, withrejected request with disallowed Host headerin the log; a name added to the list was rejected the same way. After the fix: the node's address — 200 and a correctinitialize, a name from[me].allowed_hosts— 200, an unlisted name — 403 with the same log line,127.0.0.1— 200. The bind address is added automatically: a node listening on a network address with a registry without[me].allowed_hostsaccepts that address in the header (with and without the port) — 200, while an unlisted name gets 403; the list in the log starts with the loopback defaults and contains the node's address. The environment variable was verified in single-repository mode (--path, noserve.toml): a name fromCODE_INDEX_ALLOWED_HOSTS— 200, an unlisted one — 403, without the variable — 403. Network-address probes went directly, bypassing the test stand's proxy. - Service routes are unaffected:
/federate/get_statsand/cache-statsanswered 200 with a foreignHostbefore the fix too — they do not pass through rmcp's check; behaviour is preserved. - Tests:
cargo fmt --allandcargo clippy --all-targets --all-features -- -D warnings— clean;cargo test --workspace --all-targets— 0 failed. 5 new: the composition of theHostlist (wildcard addresses, the bind address, config without duplicates, environment string parsing) and parsing of[me].allowed_hostsinserve.tomlalong with backward compatibility. - Federation node (Linux, containers): before the update a request to
/mcpby the node's network address returned 403, after it — 200 with a correct handshake; an unlisted name still gets 403, and federation over/federate/*works. A real MCP client (the official SDK) completes a full session over the network: handshake, tool list, and two calls returning real data from the node. A client from an address outside the allowed list gets{"error":"forbidden","peer":"..."}— the second, independent protection layer.
Russian version of the changelog: CHANGELOG.md.
What's Changed
Full Changelog: v1.8.5...v1.8.6