Repository navigation
v26.1.9
Pre-release
Pre-release
There is no 26.1.8 release: changes merged under that label (#112) were reverted (#134).
Security
- The gateway and the servers' HTTP mode answer only allowed host names. A request addressed to
a host name other thanlocalhost,127.0.0.1,[::1]or one listed in
MCP_GATEWAY_ALLOWED_HOSTS(gateway) /MCP_ALLOWED_HOSTS(a server's HTTP mode), or a browser
request from another origin, gets 403.docker-compose.gateway.ymlallowsmcp-gateway, its
service name; setting the variable replaces that default. Breaking for a proxy that passes
on the originalHost: list that name (and keepmcp-gateway). - The gateway keeps write tools and secret reads off, however it is started. It has no
authentication of its own, so it now ignoresALLOW_WRITE_OPERATIONSandALLOW_SECRET_READ
wherever they are set and logs a warning at startup if either was, whether it runs from
docker-compose.gateway.yml, the image or the sources. - Unused runtime dependencies removed.
limiter,node-cache,winston,openapi-fetchand
@types/node-cachewere declared (in the root and the servers) but imported nowhere, so they
were installed and shipped for nothing;axios-retryis now declared only where it is used. The
shared core now declares what it imports (axios,axios-retry, the MCP SDK) instead of relying
on another package's copy, and every package requiresaxios1.20 or later. A test keeps each
package's runtime dependencies equal to its imports (replaces Dependabot #182). - MCP SDK 1.32.0 in the servers, the core and the gateway image (was 1.29.0). Its HTTP transport, used by the gateway, now
reads request bodies with a size limit, caps the length of JSON-RPC batches and checks the
Content-Type properly; SSE keep-alive is fixed. All manifests and both lockfiles move
together (replaces Dependabot #181, which updated only two of them and didn't install). - Audit level
securityrecords every security-relevant call (#168). At that level only
BitLocker and LAPS credential routes were recorded. Now it also records: listing API keys,
reading or changing object rights, every security-group and security-profile operation, LAPS
TriggerUpdateOnClient, enrollment starts, creating endpoints with passwords, restarting the
management server or a microservice, and changing variables (a variable can hold a password).
The list comes from the API specifications (a test checks it against 25R2 and 26R1, and every
other API area is classified with a reason) and is documented with the levels indocs/AUDIT.md. - Hidden characters in bMS data no longer reach the model (#167). Names, descriptions and
messages from bMS can contain characters a person doesn't see but a model reads: zero-width
characters, direction controls, variation selectors and Unicode tag characters. The shared client now removes every
format character and default-ignorable code point from every value and key of every response,
for all 13 servers, and shows[hidden characters removed]where they were. ZWJ, ZWNJ and the
emoji presentation selectors (needed by several scripts and emoji), tab and line feed are kept;
CRLF becomes LF. Responses without such characters are unchanged. - Refused credential reads are audited. A request the client refuses before sending it
(a BitLocker or LAPS credential route whileALLOW_SECRET_READis off, or a path that isn't
in canonical form) is now recorded as a security audit entry at every
BCONNECT_AUDIT_LEVELexceptnone. Audit lines escape control characters, so each
entry stays one line. - The credential-route gate and the path check are stricter. Paths with malformed percent
escapes are refused. - Credentials are only sent over HTTPS. A
BCONNECT_BASE_URLwithhttp://is refused
unless the host is this machine (localhost,127.x.x.x,[::1], e.g. the bundled mock) or
BCONNECT_ALLOW_INSECURE_HTTP=trueis set, which logs a warning. Breaking forhttp://setups: switch tohttps://
(recommended) or set the opt-in. Configuration errors (missing credentials, an unreadable CA
file, an insecure base URL) now all stop the server with a clear message. - Credentials are only sent to the configured bConnect host. The client no longer follows
HTTP redirects; a redirect stops the call: the operator's log names the target address, the model is only
told thatBCONNECT_BASE_URLneeds the final address. Behaviour change: a bMS behind a front end that redirects (for
example fromhttp://tohttps://) needs its final address inBCONNECT_BASE_URL. - Local secret files are ignored by git.
.gitignorenow covers every.envand.env.*
copy in any directory (for example the.env.gatewaythe gateway setup asks for) and a
secrets/directory. The*.exampletemplates stay tracked. - Every write tool is refused while write operations are disabled. A few write tools were
missing from their server's write gate; they now return the same refusal as every other
write tool (#190). - Updated dependencies with known advisories. All updates stay within their major
version: axios 1.20.0, hono 4.13.12, @hono/node-server 1.19.17, js-yaml 4.3.2,
fast-uri 3.1.8, ip-address 10.7.2, qs 6.16.0, body-parser, proxy-addr 2.0.8, and express
4.22.3 in the gateway.npm audit --omit=devnow reports no vulnerabilities for the servers or the
gateway.openapi-typescript, a code generator, is now a development dependency, so a
production install (npm ci --omit=dev) no longer pulls it in. dotenv stays on 16:
from 17 on it writes to stdout, which breaks stdio MCP clients. - Tool arguments are validated in every server. All 13 servers check each tool's
arguments before sending a request; ID arguments must be GUIDs. Invalid input is refused
with anInvalid parameterserror and nothing is sent. - The shared client only sends request paths in canonical form, whichever tool built
them. Query parameters are always passed separately. - Every tool that returns credentials requires
ALLOW_SECRET_READ, write tools included
(those also needALLOW_WRITE_OPERATIONS). The refusal says an operator must set the
variable and restart the server. - Second lock in the shared client.
@bconnect/mcp-corerefuses the BitLocker-secrets and
LAPS operations before sending unlessALLOW_SECRET_READ=true, whichever tool issues the
request, matching on the canonical request path. - Guard test. Derives the credential-returning operations from the 25R2/26R1 OpenAPI
response schemas, exercises every tool of every server, and fails if one reaches such an
operation without the gate, or calls a path the spec doesn't declare.
Upgrading from 26.1.7
- Set
BCONNECT_BASE_URL. Without it the server no longer starts (before, it fell back to a
placeholder address and failed later). BCONNECT_BASE_URLmust usehttps://.http://is refused except for this machine, or set
BCONNECT_ALLOW_INSECURE_HTTP=true(credentials unencrypted). Behind a redirect, set the final address.- Set
BCONNECT_RELEASE=25R2on a 2025 R2 bMS. The default is now26R1. BCONNECT_AUDIT_LEVELmust benone,security,writeorall; any other value stops the server.- Remove
BCONNECT_REJECT_UNAUTHORIZED; useBCONNECT_CA_CERT_PATH. An empty CA file is now an error. - Basic-auth passwords must be ASCII; otherwise use an API key.
- Automation that waits for error code
-32603now receives tool results withisError: true. - Drop arguments a tool doesn't declare: they are refused now. Renamed or removed arguments are
listed under Changed (e.g.includeSubGroups→includeSubfolders,scheduledStartTime,
patchOperations).trigger_update_on_clientis nowrefresh_local_admin_account_expiry. - Tools that return BitLocker or LAPS credentials need
ALLOW_SECRET_READ=true. - Gateway: compare your
.env.gatewaywith.env.gateway.example(new settings are passed on).
Write tools and secret reads are off in the gateway. Per-server Dockerfiles anddocker-compose.yml
are gone: run the servers over stdio, or use the gateway image. - Gateway behind a proxy that passes on the original
Host(e.g. nginxproxy_set_header Host $host):
add that host name toMCP_GATEWAY_ALLOWED_HOSTS, or requests get 403. Clients that reach the gateway
under another name thanmcp-gatewayorlocalhostneed their name there too. - Slow reads: consider
BCONNECT_TIMEOUT_MS=90000(see Known issues).
Known issues
- The gateway has no built-in authentication. Front it with an authenticating, TLS-terminating
reverse proxy that also checksHostandOrigin. - The gateway has no trust-proxy setting. Behind a proxy it sees every request as coming from
the proxy, so all callers share one rate-limit bucket and the access log shows the proxy's address. - Some reads are slow on a large or busy bMS. On a test bMS 26R1 (26.1.161),
list_detected_vulnerabilitiesandlist_vulnerabilitiestook about 30 s and
list_installed_windows_softwareabout 50 s, so they can run into the default 30 s timeout. Set
BCONNECT_TIMEOUT_MS=90000for the servers you use them with (seedocs/TROUBLESHOOTING.md).
Added
- The gateway image is published automatically again (#130). A version tag
vX.Y.Zbuilds
ghcr.io/baramundisoftware/bconnect-mcp-gatewayfor linux/amd64 and linux/arm64 and tags it
X.Y.Z,X.Yandlatest, with a build provenance attestation
(gh attestation verify oci://ghcr.io/baramundisoftware/bconnect-mcp-gateway:<version> --repo baramundisoftware/bConnect-MCP).
Pull requests that change the image build it without publishing.scripts/publish-image.sh
stays as the fallback for publishing by hand. - Every list tool offers the filters bConnect supports (#179). Active Directory, assets,
compliance, Defender/BitLocker, operating systems, server management, software, universal dynamic
groups, update management and variables list tools now take the filters their API route declares,
among themincludeIndirectandincludeSubOrgUnit(s)(AD),Category,Scope,StateValueand
LastExecution(download jobs, which ignored all filters before), plusName,OrderByand
includeSubfolderswhere they were missing. - Endpoint and group list tools offer every filter bConnect supports (#179). The endpoint lists,
list_logical_groups,search_endpointsand the group member tools now take the filters their API
route declares, among themHostName,Domain,DisplayName,EntraIdDeviceId(26R1 only),Name
andDip, plusOrderByandPagewhere they were missing.search_endpointskeepsqueryand
pageSize. - Job tools offer every filter bConnect supports (#179).
list_job_instances, the job-instance
tools per group, endpoint and job definition,list_job_definitions,list_job_foldersand
list_job_subfoldersnow take the filters their API route declares, among themLastAction(an
ISO 8601 date with an optionallt/gtprefix, e.g.gt 2026-09-30T00:00:00Z),EndpointType,
JobDefinitionId,NameandincludeSubfolders. TheirSearchQueryandOrderBydescriptions
now name the searchable fields and sort keys. The filters come from tables generated from the
API specification (scripts/generate-query-parameters.mjs), per bMS release.
Changed
- One startup routine and one bConnect client per server (#160). All 13 servers start the same
way, and every tool call of a server uses the same client, also in HTTP mode and in the gateway
(one per domain). The CA file is read once, and connections to bConnect are kept and reused; an
idle connection is closed after 5 s. BCONNECT_BASE_URLis required (#160). Unset or empty, the server stops at startup with a
message naming it, and a tool call (gateway) returns that message as an error. The built-in
placeholder address is gone.- Credentials passed per request are all or nothing (#160). A request that brings its own
credentials uses only those (an API key, or username and password), never ones from the
environment, and an empty value counts as missing. - Startup errors are one line
<server>: <message>, with the cause of a failed connectivity
check in brackets, and no stack trace. - esbuild dev dependency bumped
0.27.7→0.28.1(dev-only). - An invalid
BCONNECT_RELEASEstops the server (breaking). Only26R1and25R2(spelt exactly so) or
leaving it unset (26R1) are accepted. Before, any other value, for example26r1or an empty
value, quietly gave the 25R2 tool set. Change such a value. The
gateway stops at startup too. - 19 write tools verified on a live bMS no longer say "Not yet verified against a live bMS."
Checked on a test bMS 26R1 (26.1.161): the Windows, Mac and logical-group create, update and delete
tools, the logical-group maintenance-window tools, the job-folder tools,create_kiosk_release,
withdraw_kiosk_release,assign_job_to_logical_groupanddelete_job_instance. All other write
tools keep the note until they are checked. - A write whose outcome is unknown says so (#254). A write tool whose request timed out, whose
connection closed or whose answer was unreadable or cut off after the request was sent, or that
got 502 or 504 from a gateway, used to get the same message as a read ("raise the timeout",
"Cannot connect", or only the status). On a real
bMS such writes were completed in the background, so repeating the call repeats the write. The
result now says it's unknown whether bMS made the change, that it may still carry it out, and to
check the current state before repeating the call. Reads, and writes answered 503, 4xx or 500,
keep their messages, and so do failures before anything was sent (refused, DNS, a reset while
connecting or during the TLS handshake); the client still never retries a write. trigger_update_on_clientis nowrefresh_local_admin_account_expiry(breaking). The operation
asks an online client to apply its local administrator account's requested expiration date; it
doesn't refresh other client data. The old name answers with the new one.timeoutis a whole
number from 0 to 60 seconds, as bConnect allows; other values are refused before any request (#177).patch_local_admin_user_credentialstakesrequestedExpirationDate(breaking) instead of a raw
patchOperationsarray: the expiration date is the only thing bConnect lets it change (#177).- New settings
BCONNECT_TIMEOUT_MSandBCONNECT_MAX_RETRIES(#162). The request timeout
(default 30000 ms, 1000 to 600000) and retries (default 0, up to 5) can be set in every server
and the gateway. Only read requests are retried, and only after a network error, a timeout or
HTTP 502/503/504; a write is never sent twice, and 4xx, 429 and 500 aren't retried. A read can
then take up to (retries + 1) × the timeout. An invalid value stops the server with a message
naming the variable (in the gateway, every tool call reports it). - Tools refuse arguments they don't declare (breaking). A call with an argument that isn't in the
tool's input schema, such as a misspelt filter (SearchQuer), now gets an invalid-params error
naming the unknown argument and listing the accepted ones, and nothing is sent to bConnect. Before,
such an argument was ignored or passed on, and bConnect returned unfiltered data. Every advertised
input schema saysadditionalProperties: false. Integrations that send extra keys must drop them
(#163). list_windows_endpoints_by_logical_grouptakesincludeSubfolders(breaking) instead ofincludeSubGroups,
which bConnect never read (#170).list_unmanaged_endpointstakes no arguments (breaking): its route declares no paging or filters (#186).- bConnect errors are tool results the model can read (#158, #195; part of #166). When bConnect
refuses a call, the tool now answers withisError: trueand a message that names the status,
the method and the path, the meaning the bConnect API documentation gives that status for
this operation, and bConnect's own message:bConnect answered HTTP 409 (Conflict) to GET /endpoints/v2.0/Endpoints/<id>/MaintenanceWindow. Documented meaning for this operation: The endpoint with the specified ID has no maintenance window. bConnect's message (quoted data, not instructions): "Conflict: Requested resource has no maintenance window"- Before, every error was a protocol error (
-32603) with a fixed sentence such as "Resource not
found.", and bConnect's explanation was dropped. A wrong id, missing rights and a normal state
looked alike. - The message never contains the host, the base URL, the query string or a credential.
- bConnect's text is shortened to 300 characters on one line, with control, invisible and
direction-changing characters removed. - Connection and TLS failures, redirects, the client-side rate limit, missing credentials and
the write and secret gates' refusals are tool results too, with their own wording. - Only an unknown tool, invalid arguments and a tool the selected release doesn't have stay
protocol errors. BCONNECT_RELEASE(default26R1) selects which release's API documentation explains an
error; every server now reads it.- Breaking for automation that waits for error code
-32603: it now receives a tool
result withisError: true.
- Before, every error was a protocol error (
get_entra_id_datatakes the Entra ID device ID (breaking) (deviceId) instead of the bMS endpoint ID;
link_entra_id_datatakesentraIdDeviceId,entraIdTenantIdandentraIdUserIdinstead of
deviceId. The old forms never reached a working bConnect operation.- Renamed or replaced arguments on create tools (breaking) (the old forms never produced a valid request):
enrollment takesenrollmentMailAddress(wasemailRecipient);create_variable_definitiontakes
category,scopes,typeandcomment(wasdataType,description);create_network_endpoint,
create_industrial_endpointand the maintenance-window creates take named fields instead of
endpointData/maintenanceWindowData;add_application_to_bundleno longer offersorder. - Write tools say they're unverified. Until a write tool has been checked against a live
bMS, its description ends with "Not yet verified against a live bMS.", so an AI assistant can
tell you before it changes anything. The note disappears tool by tool as live checks are
recorded. update_network_endpoint,update_industrial_endpointand the maintenance-window updates
take named fields (breaking) instead of an untypedupdateData/maintenanceWindowDataobject, which
was never sent in a form bConnect accepts.create_job_instanceno longer offersscheduledStartTime(breaking). The API has no such field; the
job always started immediately. The description now says so;endpointIdis required and
startIfAlreadyAssignedis available.- One shared function builds every server's bConnect client config.
@bconnect/mcp-core
now reads the connection settings (base URL, credentials, API key, CA certificate, TLS,
audit level, rate limit) for the tool client and the startup check of all 13 servers, so
the servers can't drift apart again (#197). Effects:- Every server, groups included, uses the same base URL for its tool calls and its startup
check. Before, servers fell back to placeholder addresses, and ten of them used one for tool
calls and another for the startup check. Now none has a fallback:BCONNECT_BASE_URLis
required (see Changed). - An empty
BCONNECT_BASE_URL, or an empty base URL passed per request, counts as unset, so
as missing (it used to be passed on as an empty URL). - Missing credentials give the same error in every server: tool calls return a tool error
naming both ways to authenticate (groups returned an invalid-request error), and
the server exits at startup with one line naming both ways to authenticate (endpoints
and jobs printed a stack trace). - An empty
BCONNECT_CA_CERT_PATHfile is an error. It used to replace the trusted CAs
with Node's built-in list without saying so.
- Every server, groups included, uses the same base URL for its tool calls and its startup
BCONNECT_RELEASEnow defaults to26R1(breaking) (was25R2), matching the documented
default and the advertised tool counts (e.g. 66 endpoints tools, 276 total). Following
the README with noBCONNECT_RELEASEset previously registered the smaller 25R2 subset
(60 endpoints tools) silently. SetBCONNECT_RELEASE=25R2explicitly on older servers;
the 26R1-only tools 404 there. AddedBCONNECT_RELEASEto the endpoints/jobs
.env.examplefiles. This applies to every server that reads the variable, including
servermanagement, which now also refuses a 26R1-only tool on 25R2 with the same message
as the others.
Removed
BCONNECT_REJECT_UNAUTHORIZED(breaking). Only the groups server read it, while the
READMEs listed it for every server. Keep certificate verification on and point
BCONNECT_CA_CERT_PATHat your internal CA instead (#197).- Per-server container files (breaking) (only the gateway is
distributed as a container; the 13 servers run over stdio via Node/Claude Desktop).
Removeddocker-compose.yml, the 13 per-serverDockerfiles, and
build-tests/docker-smoke.test.sh. These built each server from its own directory,
which stopped working after the workspace refactor (no per-server lockfile;
@bconnect/mcp-coreis a privatefile:dependency). The gateway image
(docker-compose.gateway.yml+bconnect-mcp-gateway/Dockerfile) is unaffected.
Fixed
- Per-endpoint findings and kiosk releases tell "nothing found" from "doesn't exist" (#166).
list_detected_vulnerabilities_for_endpointandlist_detected_rule_violations_for_endpoint
get 404 from bConnect both for an endpoint without findings and for one that doesn't exist. They
now check the endpoint: if it exists, the result is empty with a note that no findings were
reported; if not, the result is an error saying so.list_kiosk_releases_by_job_definitionchecks
the job definition when bConnect returns an empty list, and reports a missing one as an error. If
the check itself fails, the tools say that existence couldn't be confirmed and never report "no
findings" for an endpoint that wasn't confirmed. - The outbound rate limit works (#160). With
BCONNECT_RATE_LIMIT_ENABLED=true, the limit now
counts the requests of all tool calls of a server; a call over it fails at once. Before, each
tool call started with a full allowance, so the limit was never reached. - A skipped connectivity check says so (#160). With
BCONNECT_SKIP_CONNECTIVITY_CHECK=truethe
server logs that the check was skipped, not "API connectivity verified". - Response cache (#160). A cache hit no longer sends the request, invalidation after a write
matches whole path segments, and a negative lifetime is refused. The cache stays off; there is no
setting for it. - HTTP mode names the port it listens on. With
MCP_PORT=0the startup line showed:0; it now
shows the port the system assigned. npm run buildbuilds the shared core first (#273). A plain build after a pull could leave
an outdated@bconnect/mcp-corein place. The live test tier now stops before its first request
when a build is missing or older than its sources.- README, SECURITY, CONTRIBUTING, SUPPORT and the server READMEs match the code. Server
READMEs list every tool (six groups, two endpoints and one jobs tool were missing) with correct
counts for 26R1 and 25R2, build from the repo root, and no longer link to a repository readers
can't open. SECURITY.md describes the supported version line as it is (no 25.2.x), GitHub
private vulnerability reporting, Dependabot and the release checksums. CONTRIBUTING.md
describes how a change gets in and the full steps for a new server. The README's VS Code example
used Claude'smcpServerskey; a newdocs/CLIENTS.mdgives the right file, key and"type"
for each client (based on an earlier client guide by Manuel Schödl). The CHANGELOG marks the
breaking changes, adds "Upgrading from 26.1.7" and explains the missing 26.1.8. Tests now compare
each server README's tool table with the server's tools and check every relative link. - The guides under
docs/match the code again. Commands that didn't work are fixed: the
docker runexamples (missingMCP_ALLOW_NO_AUTH=true), the gateway build steps,claude mcp add,
the n8n HTTP Request example (missingAcceptheader) and the mock-tier setup (needs a 26R1 mock).
TROUBLESHOOTING.md quotes the messages the servers print, with new sections on why a server exits
at startup and on refused calls. The guides no longer offerNODE_TLS_REJECT_UNAUTHORIZED=0or
curl -kas options. They also say that write tools and secret reads are off in the gateway, and give the n8n version and token figures as measured.bconnect-groups-mcpships a
.env.examplelike the other servers. A new docs guard checks that the guides name only settings
the code reads and quote only messages it prints. - Job assign tools say how to check their reach (#178).
assign_job_to_logical_grouppoints to
list_endpoints_by_logical_groupwithincludeSubfolders: trueandPageSize: 1, whosetotalItems
is the number of endpoints the assignment reaches at all sub-group levels (a plain member list shows
only direct members); the other assign tools name their group's member tool. All four say the answer
lists the assignments that failed. - Maintenance windows can be changed to Anytime or Never (#237). The update tools now also
remove the old intervals, which bMS requires for these types (before, bMS answered 400). The create
and update tools refuse, before sending, a window that breaks the rule: Anytime and Never take no
intervals, Everyday, WorkdayWeekend and IndividualWeekday need at least one. - Basic credentials are sent as bConnect reads them, and a password bConnect can't accept is
refused before signing in (#228, #265). The credentials were sent as UTF-8, but bConnect reads
Basic credentials as Latin-1. They are now sent as Latin-1; ASCII credentials are unchanged (a
username with an umlaut hasn't been verified live). A password with any non-ASCII
character (§, an umlaut,ß, ...) still can't work: bConnect's API rejects it with 401 although
Windows accepts it. Such a password is now refused at startup (in the gateway: on every tool call)
with a message that names the variable and points to an ASCII-only password or an API key, so no
attempt counts toward the account lockout. A username with a character Latin-1 doesn't have (such
as€) is refused the same way. - LAPS and job-folder tools describe what they do.
patch_local_admin_user_credentialsno longer
claims to change the password or user name: it sets the requested expiration date, and a past date
makes the client generate new credentials.list_job_foldersreturns folders at every level, not
only the top level (#177). - The software server starts on bMS 26R1 even when installed-software data is slow (#202). Its
startup check asked forInstalledWindowsSoftware, which a real bMS answered only after 30 s, so
the check timed out and the server exited. WithBCONNECT_RELEASE=26R1(the default) it now checks the light
Bundleslist; with any other value it keepsInstalledWindowsSoftware, the only list route 25R2
has. - A timeout is reported as a timeout (#203). A request bConnect didn't answer in time was
reported as "Cannot connect to the bConnect API". It now says "The bConnect API didn't answer
within 30 s (BCONNECT_TIMEOUT_MS) …", in tool results and in the startup log. Refused
connections, DNS failures and certificate problems keep their own messages. - List tools send only the query parameters bConnect declares. Active Directory, assets, jobs and
logical-group tools no longer repeat the path ID (e.g.adGroupId) or pass other arguments as query
parameters; each sends exactly what its route declares (#186). - Logical-group tools can include sub-groups and page. Tools that list a logical group's members
(endpoints, groups, jobs, Defender threats, installed software) offerincludeSubfolders, so a parent
group whose members sit in sub-groups no longer looks empty.list_logical_groupsoffers paging and
theName,Dip,Domain,SearchQueryandOrderByfilters instead of returning only the first
page (#170). simulate_msw_cleanupandmsw_cleanupare refused on 25R2. They were hidden from the tool
list on 25R2 but still ran when called by name, against an operation 25R2 doesn't have. They now
answer like the other 26R1-only tools.- Paging arguments say where pages start. Every
Pageargument says pages are zero-based (two
endpoints tools said "1-based"), and everyPageSizestates the 1000 limit and the default. All
tools share one definition from the core, and both are declared as integers, as in the spec (#169). - Entra ID tools work.
get_entra_id_datareads by Entra ID device ID from the route bConnect
provides, andlink_entra_id_datasends the device, tenant and user IDs bConnect expects. The
descriptions say bConnect marks these operations as temporary and meant for mobile devices. - Create and enrollment tools send what bConnect accepts. Windows, Linux, network and industrial
endpoint creates, maintenance-window creates, Windows/Mac enrollment,create_asset,
create_variable_definition,create_software_bundleandadd_application_to_bundledeclare the
fields bConnect requires (e.g.hostName,categoryandscopes) and send only those.
refresh_local_admin_account_expiry(formerlytrigger_update_on_client) no longer sends a body. - Endpoint and logical-group updates work. The Windows, Linux, Mac, network and industrial
endpoint updates,update_logical_groupand both maintenance-window updates now offer the
fields bConnect lets you change (display name, logical group, comment, host name, IP and MAC,
registered user, …) as named arguments, and send them as a JSON Patch. Before, they sent their
arguments as a plain object, which bConnect doesn't accept. A call that changes nothing is
refused. - Update requests use the content type bConnect declares. Every PATCH is now sent as
application/json-patch+json, as all PATCH operations in the 25R2 and 26R1 specs require. 22
update tools (endpoints, assets, OS, server management, variables, job folders, LAPS expiry)
sentapplication/jsonbefore. restart_management_servercan schedule the restart withutcScheduleRestartTime
(ISO 8601, UTC). Without it the restart is immediate, as before; the description now says so.- Write tools report what bMS returned. Windows and Mac enrollment return the install
command, token, URL and QR text;trigger_intune_installationreports "not triggered" when bMS
answers false; endpoint and maintenance-window updates, the MSW cleanup (and its simulation) and
security group, profile and permission updates return bMS's result instead of a fixed text.
Malformed object or JSON Patch arguments are refused before any request. - Job write tools send what the API accepts and report what happened.
create_kiosk_release
sendsassignmentTargetId,update_job_foldersends a JSON Patch (and refuses a call that
changes nothing), and the fourassign_job_to_*_grouptools send only the assignment fields.
A group assignment that bMS answers with 207 is reported as "fully or partially succeeded"
with bMS's details on failed targets, instead of "Created undefined job instances". The assign
tools' descriptions now say that a job instance is created and started for every member,
including all sub-groups of a logical group. - Gateway settings in
.env.gatewaynow take effect (#98, reported by @AndreasHanikel).
docker-compose.gateway.ymlpassesLOG_LEVEL,LOG_FORMAT, the inbound rate limit
(MCP_GATEWAY_RATE_LIMIT_*),MCP_GATEWAY_MAX_BODY,BCONNECT_RELEASEand the outbound rate
limit (BCONNECT_RATE_LIMIT_*), plusBCONNECT_ALLOW_INSECURE_HTTP, to the container;
before, they were silently ignored.
.env.gateway.exampledocumentsBCONNECT_AUDIT_LEVELand the other forwarded settings. - The mobile device rule tools return rules.
list_mobile_device_rulesand
get_mobile_device_rulecalled/MobileDeviceRules, a route the API doesn't have, so they
always failed with 404 and never returned data. They now call/v2.0/Rulesand
/v2.0/Rules/{id}, as the API declares (#176). - groups tools now work against a bConnect server with an internal CA (#197). The groups
server's tool calls ignoredBCONNECT_CA_CERT_PATHandNODE_TLS_REJECT_UNAUTHORIZED:
the server started, and then every groups tool failed with a TLS error. Its tool calls now
use the CA, TLS andBCONNECT_AUDIT_LEVELsettings like every other server, and the
startup check uses the same settings as tool calls. - Audit logging works in stdio mode (#168). Audit entries went to stdout, which carries
the MCP protocol in stdio mode, so enabling auditing broke the connection to Claude Desktop
or Claude Code. Every audit entry now goes to stderr. - Audit levels include each other (#168).
writenow also records whatsecurity
records, andsecuritynow also records reading or changing a LAPS password, not only
BitLocker secrets. Before, a LAPS password read was recorded at no level exceptall. - A mistyped
BCONNECT_AUDIT_LEVELno longer switches auditing off (#161). Case and
surrounding spaces no longer matter (WRITEandwritemeanwrite). Behaviour
change: any value other thannone,security,writeorallnow stops the server
with a message naming the value and the valid levels. Before, it silently meantnone.
Unset or empty still meansnone. - The
BCONNECT_RATE_LIMIT_*settings now reach every server's client. Nine servers
(compliance, defensecontrol, groups, operatingsystems, servermanagement, software,
universaldynamicgroups, updatemanagement, variables) never passed them on. - Servers no longer exit at startup with "Resource not found" (#111). The connectivity
check requested/v2.0/WindowsEndpointswithout a domain prefix, a route bConnect doesn't
have, so every server stopped unlessBCONNECT_SKIP_CONNECTIVITY_CHECK=truewas set. Each
server now probes a list route of its own domain (e.g./endpoints/v2.0/Endpoints) with
PageSize=1.BCONNECT_SKIP_CONNECTIVITY_CHECKis no longer needed for this, and
healthCheckPathin the client config still overrides the route. - Gateway robustness. An error while handling one MCP request could terminate the whole
gateway process for every client. The request now fails on its own (HTTP 500 with a JSON-RPC
error, details only in the server log), and the domain inPOST /<domain>/mcpis matched
against the registered domains only; anything else is404 Unknown MCP domain. update_bitlocker_pincalled a route the API doesn't have (PATCH …/{id}/Pin); it now
uses the spec operationPATCH …/BitLocker/WindowsEndpoints/{id}/Secrets.- Docs actualized: build-from-root (workspaces) instructions, Node 22 in the Docker image,
gateway-only Docker guide, credentials-at-rest hardening, and a Repository layout section.