Skip to content

fix(mcp): allow inline stdio env assignments - #3861

Merged
akshaydeo merged 1 commit into
maximhq:mainfrom
Shushmitaaaa:fix-mcp-stdio-env-validation
Jun 1, 2026
Merged

akshaydeo merged 1 commit into
maximhq:mainfrom
Shushmitaaaa:fix-mcp-stdio-env-validation

Conversation

@Shushmitaaaa

Copy link
Copy Markdown
Contributor

Summary

Fixes STDIO MCP env validation so inline KEY=value entries are treated as explicit environment assignments instead of looking up the full KEY=value string as an environment variable name.

Changes

  • Split STDIO env entries on the first =
  • Skip host environment lookup for inline KEY=value assignments
  • Preserve validation for referenced env vars like API_KEY
  • Reject empty env assignment names like =value
  • Added regression tests for inline assignments, referenced env vars, and empty names

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

Validated the focused MCP package tests from the core module.

cd core
go test ./mcp

@CLAassistant

CLAassistant commented May 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved environment-variable handling for STDIO clients: inline assignments like NAME=value are accepted, referenced variables must be set (otherwise a clear error is shown), and empty variable names are rejected with a specific error.
  • Tests

    • Added unit tests covering inline env assignments, set vs. unset referenced variables, and empty-name validation.

Walkthrough

The PR updates STDIO connection environment handling to parse each StdioConfig.Envs entry as either NAME or NAME=value. Inline assignments are accepted without host checks; plain NAME entries must be non-empty and exist in the host environment. Four tests cover accepted inline assignments, set referenced vars, missing vars (error), and empty-name errors.

Changes

STDIO Environment Variable Validation

Layer / File(s) Summary
STDIO environment parsing
core/mcp/clientmanager.go
createSTDIOConnection now parses env entries as NAME or NAME=value, accepts inline assignments without checking the host environment, rejects empty env names, and errors when a plain NAME entry is unset.
Environment validation test suite
core/mcp/clientmanager_test.go
Adds four tests verifying inline env assignments succeed, set referenced env vars succeed, missing referenced env vars produce an error mentioning the variable is not set, and empty env assignment names are rejected with a specific error.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Poem

I hop through envs both near and far,
Splitting keys and values like a star,
Inline assigns I now allow,
Empty names get a stern bow,
Tests at dawn confirm the spar. 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: allowing inline KEY=value environment assignments in STDIO MCP configuration.
Description check ✅ Passed The description covers the summary, specific changes, type of change, affected areas, and testing instructions. While the breaking changes section is not explicitly checked and security considerations are not addressed, the core required information is present and complete.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

@greptile-apps

greptile-apps Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 4/5

The change is a focused, low-risk fix to env validation logic with no impact on transport setup or connection lifecycle.

The core fix in clientmanager.go is correct and handles all edge cases well. The only gap is a missing happy-path test for the referenced-var branch, which means a future inversion of that check would not be caught by these tests.

core/mcp/clientmanager_test.go — the referenced-var success path is untested.

Important Files Changed

Filename Overview
core/mcp/clientmanager.go Validation loop uses strings.Cut to distinguish inline assignments from plain var-name references; logic is correct for all edge cases including empty names and values with embedded equals signs.
core/mcp/clientmanager_test.go New file adds three focused regression tests; happy-path coverage for a referenced env var that IS set to a non-empty value is absent.

Reviews (1): Last reviewed commit: "fix(mcp): allow inline stdio env assignm..." | Re-trigger Greptile

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 28, 2026
Comment thread core/mcp/clientmanager_test.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
core/mcp/clientmanager_test.go (1)

11-25: ⚡ Quick win

Add a regression case where inline env value contains =.

Given the parser now splits on the first =, add a case like Envs: []string{"TEST_STDIO_ENV_ASSIGNMENT=a=b"} and assert success. This guards the exact contract and prevents accidental full-split regressions.

Suggested test addition
 func TestCreateSTDIOConnectionAllowsInlineEnvAssignments(t *testing.T) {
 	t.Parallel()
@@
 	_, _, err := (&MCPManager{}).createSTDIOConnection(context.Background(), config, nil)
 	require.NoError(t, err)
+
+	configWithEqualsInValue := &schemas.MCPClientConfig{
+		Name:           "test-stdio-client",
+		ConnectionType: schemas.MCPConnectionTypeSTDIO,
+		StdioConfig: &schemas.MCPStdioConfig{
+			Command: "echo",
+			Envs:    []string{"TEST_STDIO_ENV_ASSIGNMENT=a=b"},
+		},
+	}
+
+	_, _, err = (&MCPManager{}).createSTDIOConnection(context.Background(), configWithEqualsInValue, nil)
+	require.NoError(t, err)
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/mcp/clientmanager_test.go` around lines 11 - 25, Update the test
TestCreateSTDIOConnectionAllowsInlineEnvAssignments (which exercises
MCPManager.createSTDIOConnection) to include a regression case where an env
value contains an extra '=' (for example Envs:
[]string{"TEST_STDIO_ENV_ASSIGNMENT=a=b"}) and assert the call still returns no
error; this ensures the parser only splits on the first '=' and doesn't drop or
mis-split the value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@core/mcp/clientmanager_test.go`:
- Around line 11-25: Update the test
TestCreateSTDIOConnectionAllowsInlineEnvAssignments (which exercises
MCPManager.createSTDIOConnection) to include a regression case where an env
value contains an extra '=' (for example Envs:
[]string{"TEST_STDIO_ENV_ASSIGNMENT=a=b"}) and assert the call still returns no
error; this ensures the parser only splits on the first '=' and doesn't drop or
mis-split the value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 366227f6-cc4b-44f9-89ed-24dd1fc67a6e

📥 Commits

Reviewing files that changed from the base of the PR and between ab74128 and bafa8eb.

📒 Files selected for processing (2)
  • core/mcp/clientmanager.go
  • core/mcp/clientmanager_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/mcp/clientmanager.go

@greptile-apps

greptile-apps Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Greptile encountered an error while reviewing this PR. Please reach out to support@greptile.com for assistance.

@Shushmitaaaa

Copy link
Copy Markdown
Contributor Author

Added the referenced-env happy path test as suggested.

@Pratham-Mishra04

Copy link
Copy Markdown
Collaborator

Hey @Shushmitaaaa thanks for the PR! It looks good - will be merging in a while

akshaydeo commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Merge activity

  • Jun 1, 5:54 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 1, 5:55 AM UTC: Graphite couldn't merge this PR because it failed for an unknown reason (Fast-forward merges are not supported for forked repositories. Please create a branch in the target repository in order to merge).

@akshaydeo
akshaydeo merged commit 270c965 into maximhq:main Jun 1, 2026
5 checks passed
akshaydeo added a commit that referenced this pull request Jun 4, 2026
## Summary

Releases core v1.5.16, framework v1.3.16, transports v1.5.8, and bumps all plugins to pick up the new core and framework versions. This release adds `file://` scheme support for pricing URLs, paginated virtual key fetching, and fixes several correctness issues across Bedrock, OpenAI→Anthropic conversion, MCP stdio, and streaming responses.

## Changes

- **File scheme pricing URLs** — Pricing source URLs now accept `file://`, enabling local filesystem pricing data for air-gapped and self-hosted deployments (#4045)
- **Paginated virtual key fetch** — Virtual key retrieval is now paginated to avoid loading all keys into memory at once for large deployments (#3957)
- **Preserve model pool entries on pricing reload** — Non-pricing model pool entries are no longer dropped when pricing data is reloaded (#3999)
- **Bedrock `outputAssessments` type** — Corrected the type of `outputAssessments` in Bedrock response structs (#4028)
- **`Model` field in `TextCompletionChunkResponse`** — Added the missing `Model` field to text completion chunk responses (#3970)
- **Orphaned tool results in OpenAI→Anthropic conversion** — Orphaned tool results no longer cause rejections from the Anthropic API (#3919)
- **MCP inline stdio env assignments** — MCP stdio server configs now correctly parse inline environment variable assignments (#3861)

## Type of change

- [x] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [x] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [x] Plugins
- [ ] UI (React)
- [ ] Docs

## How to test

```sh
go version
go test ./...
```

- To test `file://` pricing URLs, configure a pricing URL using the `file:///path/to/pricing.json` scheme and verify pricing data loads correctly from the local file.
- To test paginated virtual key fetch, create a large number of virtual keys and confirm they are all returned correctly without memory issues.
- To test orphaned tool results, send a request through the OpenAI→Anthropic conversion flow containing a tool result with no matching tool call and verify it is accepted rather than rejected.
- To test MCP inline stdio env, configure an MCP stdio server with inline env var assignments (e.g. `KEY=value`) and verify the server starts correctly.

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

Closes #4045, #3957, #3999, #4028, #3970, #3919, #3861

## Security considerations

No new security implications. This release does not touch auth, secrets handling, or sandboxing.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [ ] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
@akshaydeo akshaydeo mentioned this pull request Jun 5, 2026
18 tasks
akshaydeo added a commit that referenced this pull request Jun 6, 2026
## Summary

This PR bumps the Go toolchain version from `1.26.3` to `1.26.4` across all modules and CI workflows, and cuts a new release (`core` v1.5.17, `framework` v1.3.17, `transports` v1.5.9, `plugins/compat` v0.1.16, `plugins/governance` v1.5.17, and associated plugin versions) incorporating a large batch of features and fixes accumulated since the previous release.

## Changes

- **Go 1.26.4** — Updated `go-version` in all GitHub Actions workflows (`e2e-tests`, `helm-release`, `pr-tests`, `release-cli`, `release-pipeline`, `snyk`) and all `go.mod` files (core, framework, transports, cli, all plugins, examples, and test modules).
- **Core (v1.5.17)** — OpenAI compaction support, multi-customer logs and usage tracking, multiple team/business unit support, `request_headers` wildcard pattern capture for OTel and Maxim plugins, xAI `x_search` tool, fetch URL validation with SSRF hardening, `file://` pricing URL scheme, virtual key provider fan-out filtering, and a broad set of fixes including Anthropic prompt cache key, empty thinking block stripping, OpenAI stream usage event cleanup, Gemini numeric schema constraints, stale connection retries, Azure Claude diagnostic strip, and passthrough budget handling.
- **Framework (v1.3.17)** — Scope-aware budgets and limits wired from model configs, provider-level governance, multiple customer budget support with `calendar_aligned` windows, paginated virtual key fetch, `config.json` source-of-truth flow, FTS index cap reduction, sync worker drift fix, cascade deletes for model configs, and high-scale virtual key flow improvements.
- **Transports (v1.5.9)** — Full changelog covering all of the above plus UI improvements (log navigation, customer detail sheet, `BudgetDisplay` component, inline loading shell, materialized view alias), SCIM provisioning fields, Helm/config schema additions (`roles`, `per_user_oauth`), client IP resolution from forwarded headers, and dependency upgrades (`recharts` to 3.8.1, `golang.org/x` CVE remediation).
- **Plugins** — `governance` v1.5.17 adds team budget/rate-limit exporters, ghost node reconciliation fix, and VK double usage counting fix; `logging` v1.5.17 adds wildcard header capture and file attachment rendering; `otel` v1.2.17 adds `disable_content_logging` and multiple collectors support; `maxim` v1.6.17 adds `request_headers` wildcard capture; `compat` v0.1.16 fixes `max_tokens` preservation during param filtering.

## Type of change

- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [x] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [x] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

```sh
# Verify Go version
go version  # should report go1.26.4

# Run core tests
cd core && go test ./...

# Run framework tests
cd framework && go test ./...

# Run transports tests
cd transports && go test ./...

# Run plugin tests
cd plugins/governance && go test ./...
cd plugins/logging && go test ./...
cd plugins/otel && go test ./...

# UI
cd ui
pnpm i
pnpm build
pnpm test
```

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

#4053, #4066, #4041, #4012, #3976, #3947, #3991, #4045, #3957, #3938, #3937, #3939, #3981, #3998, #3997, #4092, #4091, #4079, #4080, #4086, #3929, #3994, #4028, #3970, #3919, #3861, #3664, #3999, #4088, #4070, #4051, #4043, #4057, #4023, #3941, #3955, #4024, #3956, #3967, #3925, #3992, #3900

## Security considerations

- Fetch URL validation hardened against SSRF by tightening IP checks for private networks and link-local addresses (#4092, #3947, #3991).
- Transitive `golang.org/x` dependencies (crypto, net, sys, text) bumped to address Docker Scout CVEs (#3900).

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [x] I verified the CI pipeline passes locally if applicable

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * OpenAI compaction, multi-customer/team logstore support, request-header wildcard capture, enhanced governance (provider-level & scope-aware limits), disable-content-logging option, support for multiple OpenTelemetry collectors, SSRF hardening and URL validation.

* **Chores**
  * Bumped Go toolchain across modules and updated component/plugin version releases.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@akshaydeo akshaydeo mentioned this pull request Jun 7, 2026
akshaydeo added a commit that referenced this pull request Jun 7, 2026
## ✨ Features

- **OpenAI Compaction** — Added OpenAI conversation compaction support
across core, framework, logging, and the API surface (#4053)
- **Multi-Customer & Org Hierarchy** — Logs and usage tracking now
support multiple customers, teams, and business units, including
business unit CRUD, team assignment, and governance endpoints in the
OpenAPI spec (#4066, #4041, #4082)
- **Provider-Level Governance** — Budgets & limits are now scope-aware
and can be applied at the virtual-key top level and per provider, wired
from the model configs table, with UI filters for scope and providers
(#3938, #3937, #3939, #3981, #3962)
- **Customer Budgets** — Customers support multiple budgets and
`calendar_aligned` budget windows (#3998, #3997)
- **Virtual Key Attribution & Controls** — Added a `created_by` user
attribution column and a `blacklisted_models` column for virtual key
provider configs (#3672, #3653)
- **Request Header Capture** — OTel and Maxim observability plugins
capture `request_headers` by pattern, with wildcard support (e.g.
`x-custom-*`); logging gained the same wildcard header capture (#4012,
#3958)
- **OTel Content Controls & Collectors** — New `disable_content_logging`
option drops message/tool content from exported spans, plus support for
multiple OTel collectors (#4064, #3894)
- **xAI x_search** — Added xAI `x_search` tool support (#3976)
- **URL Validation** — Added fetch URL validation with private-network
configuration and link-local blocking (#3947, #3991)
- **File Scheme Pricing URLs** — Pricing source URLs now accept the
`file://` scheme for air-gapped and self-hosted deployments (#4045)
- **Paginated Virtual Keys** — Virtual key fetching is paginated to
handle deployments with very large numbers of keys (#3957)
- **Client IP Resolution** — Resolve client IP from
`X-Forwarded-For`/`X-Real-IP` headers
- **SCIM Provisioning** — Added `attributeType`/`attributeValue` SCIM
provisioning fields
- **Helm/Config Schema** — Added `roles` RBAC governance config and
`per_user_oauth` MCP auth to the Helm chart and config schema (#4004,
#4009)
- **Log Navigation UI** — Added a "View logs" menu item to customer,
team, and virtual key tables, clickable links in log detail views, a
customer detail sheet, and a reusable `BudgetDisplay` component (#4073,
#4054, #4026, #4055)
- **Faster First Paint** — Added an inline loading shell to `#root`
before React mounts (#4063)
- **Materialized View Alias** — Added an `alias` column to the
materialized view with filter support (#4078)

## 🐞 Fixed

- **Fetch URL IP Checks** — Hardened fetch URL IP checks against SSRF
(#4092)
- **Mantle Model Matching** — Broadened Mantle model matching to all
`gpt` variants (#4091)
- **Empty Thinking Blocks** — Strip thinking blocks when the signature
is empty (#4079)
- **OpenAI Stream Usage** — Removed usage from the `responses.created`
event in the OpenAI stream (#4080)
- **Prompt Cache Key** — Set the prompt cache key from the Anthropic
integration (#4086)
- **Upstream Failure Status** — Map upstream connection failures to 502
instead of 400 (#3929) (thanks
[@chris-colinsky](https://github.com/chris-colinsky)!)
- **Gemini Schema Constraints** — Accept numeric schema integer
constraints for Gemini (#3994) (thanks
[@yanhao98](https://github.com/yanhao98)!)
- **Files Provider Param** — Accept the `?provider=` query param on `GET
/v1/files` (#3971) (thanks [@alexef](https://github.com/alexef)!)
- **Optional Batch Model** — Made the `model` field optional on `POST
/v1/batches` (#3973) (thanks [@alexef](https://github.com/alexef)!)
- **Helm Azure Config** — Added missing `azure_key_config` fields to the
Helm schema (#3996) (thanks
[@axelray-dev](https://github.com/axelray-dev)!)
- **Text Completion Chunk Model** — Added the missing `Model` field to
`TextCompletionChunkResponse` (#3970) (thanks
[@kuishou68](https://github.com/kuishou68)!)
- **MCP Inline stdio Env** — MCP stdio server configs accept inline
environment variable assignments (#3861) (thanks
[@Shushmitaaaa](https://github.com/Shushmitaaaa)!)
- **Orphaned Tool Results** — Orphaned tool results in the OpenAI to
Anthropic conversion flow are no longer rejected by the Anthropic API
(#3919)
- **Node Usage Reconciliation** — Added a monotonic `inc_number` log
cursor so node usage reconciliation does not skip late async log writes
(#3664)
- **Bedrock Output Assessments** — Corrected the type of
`outputAssessments` in Bedrock responses (#4028)
- **Model Pool Pricing Reloads** — Preserve non-pricing model pool
entries across pricing reloads (#3999)
- **Ghost Node Reconciliation** — Replicate the VK hierarchy flow for
ghost node reconciliation (#4088)
- **VK Double Usage Counting** — Fixed double usage counting when
creating a virtual key (#4070)
- **Model Config Lifecycle** — Cascade deletes for model configs and
removal of stale in-memory model configs (#4051, #4043)
- **FTS Index Cap** — Reduced the FTS index `left()` cap from 800k to
250k chars to stay within the tsvector limit (#4057)
- **Sync Worker Drift** — Reduced the sync worker ticker period to 5m to
prevent threshold drift (#4023)
- **Passthrough** — Fixed passthrough budgets, gated passthrough models
per VK, model extraction for Azure passthrough, and restricted
fallbacks/provider selection to the VK boundary (#3941, #3988, #3983,
#3924)
- **Provider Response Headers** — Strip provider response headers and
add a content-type filter (#3955, #4024)
- **Stream Handling** — Drain non-SSE stream readers and retry stale
connections (#3956, #3967)
- **Azure Claude** — Strip Azure diagnostic property for Claude models
(#3925)
- **Compat max_tokens** — Preserve chat `max_tokens` during param
filtering (#3992)
- **Raw Request Flag** — Removed the raw request flag from providers
that don't support it (#4058)
- **UI Fixes** — Standardized page container layout, virtual key model
configs UI, and dashboard chart tooltips (#4046, #4052, #4044)

## 🔧 Maintenance

- **Dependency Upgrades** — Bumped transitive `golang.org/x`
dependencies (crypto, net, sys, text) for Docker Scout CVE remediation
and `recharts` to 3.8.1; cascaded version bumps across all modules
(#3900, #4003)
akhsaul pushed a commit to akhsaul/bifrost that referenced this pull request Aug 27, 2026
akhsaul pushed a commit to akhsaul/bifrost that referenced this pull request Aug 27, 2026
## Summary

Releases core v1.5.16, framework v1.3.16, transports v1.5.8, and bumps all plugins to pick up the new core and framework versions. This release adds `file://` scheme support for pricing URLs, paginated virtual key fetching, and fixes several correctness issues across Bedrock, OpenAI→Anthropic conversion, MCP stdio, and streaming responses.

## Changes

- **File scheme pricing URLs** — Pricing source URLs now accept `file://`, enabling local filesystem pricing data for air-gapped and self-hosted deployments (maximhq#4045)
- **Paginated virtual key fetch** — Virtual key retrieval is now paginated to avoid loading all keys into memory at once for large deployments (maximhq#3957)
- **Preserve model pool entries on pricing reload** — Non-pricing model pool entries are no longer dropped when pricing data is reloaded (maximhq#3999)
- **Bedrock `outputAssessments` type** — Corrected the type of `outputAssessments` in Bedrock response structs (maximhq#4028)
- **`Model` field in `TextCompletionChunkResponse`** — Added the missing `Model` field to text completion chunk responses (maximhq#3970)
- **Orphaned tool results in OpenAI→Anthropic conversion** — Orphaned tool results no longer cause rejections from the Anthropic API (maximhq#3919)
- **MCP inline stdio env assignments** — MCP stdio server configs now correctly parse inline environment variable assignments (maximhq#3861)

## Type of change

- [x] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [x] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [x] Plugins
- [ ] UI (React)
- [ ] Docs

## How to test

```sh
go version
go test ./...
```

- To test `file://` pricing URLs, configure a pricing URL using the `file:///path/to/pricing.json` scheme and verify pricing data loads correctly from the local file.
- To test paginated virtual key fetch, create a large number of virtual keys and confirm they are all returned correctly without memory issues.
- To test orphaned tool results, send a request through the OpenAI→Anthropic conversion flow containing a tool result with no matching tool call and verify it is accepted rather than rejected.
- To test MCP inline stdio env, configure an MCP stdio server with inline env var assignments (e.g. `KEY=value`) and verify the server starts correctly.

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

Closes maximhq#4045, maximhq#3957, maximhq#3999, maximhq#4028, maximhq#3970, maximhq#3919, maximhq#3861

## Security considerations

No new security implications. This release does not touch auth, secrets handling, or sandboxing.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [ ] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
akhsaul pushed a commit to akhsaul/bifrost that referenced this pull request Aug 27, 2026
## ✨ Features

- **OpenAI Compaction** — Added OpenAI conversation compaction support
across core, framework, logging, and the API surface (maximhq#4053)
- **Multi-Customer & Org Hierarchy** — Logs and usage tracking now
support multiple customers, teams, and business units, including
business unit CRUD, team assignment, and governance endpoints in the
OpenAPI spec (maximhq#4066, maximhq#4041, maximhq#4082)
- **Provider-Level Governance** — Budgets & limits are now scope-aware
and can be applied at the virtual-key top level and per provider, wired
from the model configs table, with UI filters for scope and providers
(maximhq#3938, maximhq#3937, maximhq#3939, maximhq#3981, maximhq#3962)
- **Customer Budgets** — Customers support multiple budgets and
`calendar_aligned` budget windows (maximhq#3998, maximhq#3997)
- **Virtual Key Attribution & Controls** — Added a `created_by` user
attribution column and a `blacklisted_models` column for virtual key
provider configs (maximhq#3672, maximhq#3653)
- **Request Header Capture** — OTel and Maxim observability plugins
capture `request_headers` by pattern, with wildcard support (e.g.
`x-custom-*`); logging gained the same wildcard header capture (maximhq#4012,
maximhq#3958)
- **OTel Content Controls & Collectors** — New `disable_content_logging`
option drops message/tool content from exported spans, plus support for
multiple OTel collectors (maximhq#4064, maximhq#3894)
- **xAI x_search** — Added xAI `x_search` tool support (maximhq#3976)
- **URL Validation** — Added fetch URL validation with private-network
configuration and link-local blocking (maximhq#3947, maximhq#3991)
- **File Scheme Pricing URLs** — Pricing source URLs now accept the
`file://` scheme for air-gapped and self-hosted deployments (maximhq#4045)
- **Paginated Virtual Keys** — Virtual key fetching is paginated to
handle deployments with very large numbers of keys (maximhq#3957)
- **Client IP Resolution** — Resolve client IP from
`X-Forwarded-For`/`X-Real-IP` headers
- **SCIM Provisioning** — Added `attributeType`/`attributeValue` SCIM
provisioning fields
- **Helm/Config Schema** — Added `roles` RBAC governance config and
`per_user_oauth` MCP auth to the Helm chart and config schema (maximhq#4004,
maximhq#4009)
- **Log Navigation UI** — Added a "View logs" menu item to customer,
team, and virtual key tables, clickable links in log detail views, a
customer detail sheet, and a reusable `BudgetDisplay` component (maximhq#4073,
maximhq#4054, maximhq#4026, maximhq#4055)
- **Faster First Paint** — Added an inline loading shell to `#root`
before React mounts (maximhq#4063)
- **Materialized View Alias** — Added an `alias` column to the
materialized view with filter support (maximhq#4078)

## 🐞 Fixed

- **Fetch URL IP Checks** — Hardened fetch URL IP checks against SSRF
(maximhq#4092)
- **Mantle Model Matching** — Broadened Mantle model matching to all
`gpt` variants (maximhq#4091)
- **Empty Thinking Blocks** — Strip thinking blocks when the signature
is empty (maximhq#4079)
- **OpenAI Stream Usage** — Removed usage from the `responses.created`
event in the OpenAI stream (maximhq#4080)
- **Prompt Cache Key** — Set the prompt cache key from the Anthropic
integration (maximhq#4086)
- **Upstream Failure Status** — Map upstream connection failures to 502
instead of 400 (maximhq#3929) (thanks
[@chris-colinsky](https://github.com/chris-colinsky)!)
- **Gemini Schema Constraints** — Accept numeric schema integer
constraints for Gemini (maximhq#3994) (thanks
[@yanhao98](https://github.com/yanhao98)!)
- **Files Provider Param** — Accept the `?provider=` query param on `GET
/v1/files` (maximhq#3971) (thanks [@alexef](https://github.com/alexef)!)
- **Optional Batch Model** — Made the `model` field optional on `POST
/v1/batches` (maximhq#3973) (thanks [@alexef](https://github.com/alexef)!)
- **Helm Azure Config** — Added missing `azure_key_config` fields to the
Helm schema (maximhq#3996) (thanks
[@axelray-dev](https://github.com/axelray-dev)!)
- **Text Completion Chunk Model** — Added the missing `Model` field to
`TextCompletionChunkResponse` (maximhq#3970) (thanks
[@kuishou68](https://github.com/kuishou68)!)
- **MCP Inline stdio Env** — MCP stdio server configs accept inline
environment variable assignments (maximhq#3861) (thanks
[@Shushmitaaaa](https://github.com/Shushmitaaaa)!)
- **Orphaned Tool Results** — Orphaned tool results in the OpenAI to
Anthropic conversion flow are no longer rejected by the Anthropic API
(maximhq#3919)
- **Node Usage Reconciliation** — Added a monotonic `inc_number` log
cursor so node usage reconciliation does not skip late async log writes
(maximhq#3664)
- **Bedrock Output Assessments** — Corrected the type of
`outputAssessments` in Bedrock responses (maximhq#4028)
- **Model Pool Pricing Reloads** — Preserve non-pricing model pool
entries across pricing reloads (maximhq#3999)
- **Ghost Node Reconciliation** — Replicate the VK hierarchy flow for
ghost node reconciliation (maximhq#4088)
- **VK Double Usage Counting** — Fixed double usage counting when
creating a virtual key (maximhq#4070)
- **Model Config Lifecycle** — Cascade deletes for model configs and
removal of stale in-memory model configs (maximhq#4051, maximhq#4043)
- **FTS Index Cap** — Reduced the FTS index `left()` cap from 800k to
250k chars to stay within the tsvector limit (maximhq#4057)
- **Sync Worker Drift** — Reduced the sync worker ticker period to 5m to
prevent threshold drift (maximhq#4023)
- **Passthrough** — Fixed passthrough budgets, gated passthrough models
per VK, model extraction for Azure passthrough, and restricted
fallbacks/provider selection to the VK boundary (maximhq#3941, maximhq#3988, maximhq#3983,
maximhq#3924)
- **Provider Response Headers** — Strip provider response headers and
add a content-type filter (maximhq#3955, maximhq#4024)
- **Stream Handling** — Drain non-SSE stream readers and retry stale
connections (maximhq#3956, maximhq#3967)
- **Azure Claude** — Strip Azure diagnostic property for Claude models
(maximhq#3925)
- **Compat max_tokens** — Preserve chat `max_tokens` during param
filtering (maximhq#3992)
- **Raw Request Flag** — Removed the raw request flag from providers
that don't support it (maximhq#4058)
- **UI Fixes** — Standardized page container layout, virtual key model
configs UI, and dashboard chart tooltips (maximhq#4046, maximhq#4052, maximhq#4044)

## 🔧 Maintenance

- **Dependency Upgrades** — Bumped transitive `golang.org/x`
dependencies (crypto, net, sys, text) for Docker Scout CVE remediation
and `recharts` to 3.8.1; cascaded version bumps across all modules
(maximhq#3900, maximhq#4003)
occcat pushed a commit to occcat/bifrost that referenced this pull request Sep 2, 2026
occcat pushed a commit to occcat/bifrost that referenced this pull request Sep 2, 2026
## Summary

Releases core v1.5.16, framework v1.3.16, transports v1.5.8, and bumps all plugins to pick up the new core and framework versions. This release adds `file://` scheme support for pricing URLs, paginated virtual key fetching, and fixes several correctness issues across Bedrock, OpenAI→Anthropic conversion, MCP stdio, and streaming responses.

## Changes

- **File scheme pricing URLs** — Pricing source URLs now accept `file://`, enabling local filesystem pricing data for air-gapped and self-hosted deployments (maximhq#4045)
- **Paginated virtual key fetch** — Virtual key retrieval is now paginated to avoid loading all keys into memory at once for large deployments (maximhq#3957)
- **Preserve model pool entries on pricing reload** — Non-pricing model pool entries are no longer dropped when pricing data is reloaded (maximhq#3999)
- **Bedrock `outputAssessments` type** — Corrected the type of `outputAssessments` in Bedrock response structs (maximhq#4028)
- **`Model` field in `TextCompletionChunkResponse`** — Added the missing `Model` field to text completion chunk responses (maximhq#3970)
- **Orphaned tool results in OpenAI→Anthropic conversion** — Orphaned tool results no longer cause rejections from the Anthropic API (maximhq#3919)
- **MCP inline stdio env assignments** — MCP stdio server configs now correctly parse inline environment variable assignments (maximhq#3861)

## Type of change

- [x] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [x] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [x] Plugins
- [ ] UI (React)
- [ ] Docs

## How to test

```sh
go version
go test ./...
```

- To test `file://` pricing URLs, configure a pricing URL using the `file:///path/to/pricing.json` scheme and verify pricing data loads correctly from the local file.
- To test paginated virtual key fetch, create a large number of virtual keys and confirm they are all returned correctly without memory issues.
- To test orphaned tool results, send a request through the OpenAI→Anthropic conversion flow containing a tool result with no matching tool call and verify it is accepted rather than rejected.
- To test MCP inline stdio env, configure an MCP stdio server with inline env var assignments (e.g. `KEY=value`) and verify the server starts correctly.

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

Closes maximhq#4045, maximhq#3957, maximhq#3999, maximhq#4028, maximhq#3970, maximhq#3919, maximhq#3861

## Security considerations

No new security implications. This release does not touch auth, secrets handling, or sandboxing.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [ ] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
occcat pushed a commit to occcat/bifrost that referenced this pull request Sep 2, 2026
## ✨ Features

- **OpenAI Compaction** — Added OpenAI conversation compaction support
across core, framework, logging, and the API surface (maximhq#4053)
- **Multi-Customer & Org Hierarchy** — Logs and usage tracking now
support multiple customers, teams, and business units, including
business unit CRUD, team assignment, and governance endpoints in the
OpenAPI spec (maximhq#4066, maximhq#4041, maximhq#4082)
- **Provider-Level Governance** — Budgets & limits are now scope-aware
and can be applied at the virtual-key top level and per provider, wired
from the model configs table, with UI filters for scope and providers
(maximhq#3938, maximhq#3937, maximhq#3939, maximhq#3981, maximhq#3962)
- **Customer Budgets** — Customers support multiple budgets and
`calendar_aligned` budget windows (maximhq#3998, maximhq#3997)
- **Virtual Key Attribution & Controls** — Added a `created_by` user
attribution column and a `blacklisted_models` column for virtual key
provider configs (maximhq#3672, maximhq#3653)
- **Request Header Capture** — OTel and Maxim observability plugins
capture `request_headers` by pattern, with wildcard support (e.g.
`x-custom-*`); logging gained the same wildcard header capture (maximhq#4012,
maximhq#3958)
- **OTel Content Controls & Collectors** — New `disable_content_logging`
option drops message/tool content from exported spans, plus support for
multiple OTel collectors (maximhq#4064, maximhq#3894)
- **xAI x_search** — Added xAI `x_search` tool support (maximhq#3976)
- **URL Validation** — Added fetch URL validation with private-network
configuration and link-local blocking (maximhq#3947, maximhq#3991)
- **File Scheme Pricing URLs** — Pricing source URLs now accept the
`file://` scheme for air-gapped and self-hosted deployments (maximhq#4045)
- **Paginated Virtual Keys** — Virtual key fetching is paginated to
handle deployments with very large numbers of keys (maximhq#3957)
- **Client IP Resolution** — Resolve client IP from
`X-Forwarded-For`/`X-Real-IP` headers
- **SCIM Provisioning** — Added `attributeType`/`attributeValue` SCIM
provisioning fields
- **Helm/Config Schema** — Added `roles` RBAC governance config and
`per_user_oauth` MCP auth to the Helm chart and config schema (maximhq#4004,
maximhq#4009)
- **Log Navigation UI** — Added a "View logs" menu item to customer,
team, and virtual key tables, clickable links in log detail views, a
customer detail sheet, and a reusable `BudgetDisplay` component (maximhq#4073,
maximhq#4054, maximhq#4026, maximhq#4055)
- **Faster First Paint** — Added an inline loading shell to `#root`
before React mounts (maximhq#4063)
- **Materialized View Alias** — Added an `alias` column to the
materialized view with filter support (maximhq#4078)

## 🐞 Fixed

- **Fetch URL IP Checks** — Hardened fetch URL IP checks against SSRF
(maximhq#4092)
- **Mantle Model Matching** — Broadened Mantle model matching to all
`gpt` variants (maximhq#4091)
- **Empty Thinking Blocks** — Strip thinking blocks when the signature
is empty (maximhq#4079)
- **OpenAI Stream Usage** — Removed usage from the `responses.created`
event in the OpenAI stream (maximhq#4080)
- **Prompt Cache Key** — Set the prompt cache key from the Anthropic
integration (maximhq#4086)
- **Upstream Failure Status** — Map upstream connection failures to 502
instead of 400 (maximhq#3929) (thanks
[@chris-colinsky](https://github.com/chris-colinsky)!)
- **Gemini Schema Constraints** — Accept numeric schema integer
constraints for Gemini (maximhq#3994) (thanks
[@yanhao98](https://github.com/yanhao98)!)
- **Files Provider Param** — Accept the `?provider=` query param on `GET
/v1/files` (maximhq#3971) (thanks [@alexef](https://github.com/alexef)!)
- **Optional Batch Model** — Made the `model` field optional on `POST
/v1/batches` (maximhq#3973) (thanks [@alexef](https://github.com/alexef)!)
- **Helm Azure Config** — Added missing `azure_key_config` fields to the
Helm schema (maximhq#3996) (thanks
[@axelray-dev](https://github.com/axelray-dev)!)
- **Text Completion Chunk Model** — Added the missing `Model` field to
`TextCompletionChunkResponse` (maximhq#3970) (thanks
[@kuishou68](https://github.com/kuishou68)!)
- **MCP Inline stdio Env** — MCP stdio server configs accept inline
environment variable assignments (maximhq#3861) (thanks
[@Shushmitaaaa](https://github.com/Shushmitaaaa)!)
- **Orphaned Tool Results** — Orphaned tool results in the OpenAI to
Anthropic conversion flow are no longer rejected by the Anthropic API
(maximhq#3919)
- **Node Usage Reconciliation** — Added a monotonic `inc_number` log
cursor so node usage reconciliation does not skip late async log writes
(maximhq#3664)
- **Bedrock Output Assessments** — Corrected the type of
`outputAssessments` in Bedrock responses (maximhq#4028)
- **Model Pool Pricing Reloads** — Preserve non-pricing model pool
entries across pricing reloads (maximhq#3999)
- **Ghost Node Reconciliation** — Replicate the VK hierarchy flow for
ghost node reconciliation (maximhq#4088)
- **VK Double Usage Counting** — Fixed double usage counting when
creating a virtual key (maximhq#4070)
- **Model Config Lifecycle** — Cascade deletes for model configs and
removal of stale in-memory model configs (maximhq#4051, maximhq#4043)
- **FTS Index Cap** — Reduced the FTS index `left()` cap from 800k to
250k chars to stay within the tsvector limit (maximhq#4057)
- **Sync Worker Drift** — Reduced the sync worker ticker period to 5m to
prevent threshold drift (maximhq#4023)
- **Passthrough** — Fixed passthrough budgets, gated passthrough models
per VK, model extraction for Azure passthrough, and restricted
fallbacks/provider selection to the VK boundary (maximhq#3941, maximhq#3988, maximhq#3983,
maximhq#3924)
- **Provider Response Headers** — Strip provider response headers and
add a content-type filter (maximhq#3955, maximhq#4024)
- **Stream Handling** — Drain non-SSE stream readers and retry stale
connections (maximhq#3956, maximhq#3967)
- **Azure Claude** — Strip Azure diagnostic property for Claude models
(maximhq#3925)
- **Compat max_tokens** — Preserve chat `max_tokens` during param
filtering (maximhq#3992)
- **Raw Request Flag** — Removed the raw request flag from providers
that don't support it (maximhq#4058)
- **UI Fixes** — Standardized page container layout, virtual key model
configs UI, and dashboard chart tooltips (maximhq#4046, maximhq#4052, maximhq#4044)

## 🔧 Maintenance

- **Dependency Upgrades** — Bumped transitive `golang.org/x`
dependencies (crypto, net, sys, text) for Docker Scout CVE remediation
and `recharts` to 3.8.1; cascaded version bumps across all modules
(maximhq#3900, maximhq#4003)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants