We're excited to announce the v0.25.0 release of the Obot Platform. This release adds tool call enforcement for local AI clients, MCP tunnels for reaching MCP servers on private networks, Agent Auth Scopes, and a new set of Obot editions.
Big Updates
Tool Call Enforcement for Local AI Clients
Obot can now control which tool calls Claude Code, Codex, and Cursor are allowed to run on enrolled devices. Administrators define an allowlist as part of device management and Obot Sentry checks each tool call against it before the client runs the tool. A call runs only when an allow rule matches it.
A rule can cover a broad category, such as all Obot-hosted MCP servers or all built-in agent tools, or it can name a single MCP server by URL, hostname, npm or PyPI package, or connector display name. Enforcement fails closed, so Obot Sentry blocks any call it cannot match or cannot get a decision on. A new Enforcement Decisions view under Device Management records every call that was checked and shows why it was allowed or blocked.
Note: Tool call enforcement is experimental and is not yet recommended for production use, so test your allowlist on non-production devices first. Enforcement is also not supported for Visual Studio Code, because its pre-tool hook does not say which MCP server a tool belongs to. Local tool call auditing for Visual Studio Code continues to work. See #7425 for details.
See the docs for details.
MCP Tunnels
Obot can now reach remote MCP servers that run on a private network and are not routable from the Obot deployment. An obot tunnel process runs on a machine that can reach both Obot and the private MCP server, and it opens an outbound, authenticated WebSocket connection that Obot sends requests through. The machine running the tunnel does not need an inbound port.
Tunnels are especially useful if you use Obot Cloud, where we run Obot for you and it sits outside your network. You run the tunnel process inside your network, and you do not have to expose the server to the internet or open a port in your firewall.
Administrators create a tunnel under MCP Management > MCP Tunnels, and each tunnel carries a list of allowed URLs that Obot checks on every request. A remote MCP catalog entry then selects the tunnel by its ID. Tunnels also work across replicas.
See the docs for details.
Agent Auth Scopes
We reworked how you set up access for an autonomous or headless agent, so you can grant an agent only what it needs to do its job. What used to be called API keys are now called Agent Auth Scopes, and the change is the start of a larger effort to extend Obot's authorization model to more agentic workloads. You create a scope and Obot generates an API key that the agent uses instead of signing in through a browser.
A scope can be limited to specific MCP servers or to every server you can reach. On top of that, it can grant access to the Obot API, the LLM proxy, skill downloads, and device scans, and it can carry an expiration date.
The interface moved to match. Users now reach scopes from the top level of the Obot app navigation, and administrators reach them under Auth Management, which was previously called User Management.
See the docs for details.
Obot Community Edition and Usage Limits
Obot is now available in three editions. You can upgrade from one to the next inside the app without changing images or redeploying. The default Obot edition supports up to 100 users and 100 devices, with the GitHub, Google, and Local auth providers. Obot Community keeps the same limits and adds enterprise-grade auth providers such as Entra, Okta, JumpCloud, and Auth0. Obot Enterprise removes the limits and includes enterprise support.
See the docs for details and read the Upgrade Notes below before you upgrade.
Improvements
- Model access policies now accept only LLM models. Non-LLM models are pruned from the default policy, and Obot warns you to remove them from a custom policy.
- The getting started guides now cover device management and MCP filters, and the Obot Sentry guide has more detailed install steps.
- Missing Kubernetes secret bindings are now highlighted when you configure an MCP server.
- The license provider now handles multi-replica deployments better and no longer depends on a single replica.
- Auth provider HTTP calls no longer hold a database transaction open while they run.
- Provider model IDs that contain slashes now resolve correctly.
- OAuth error redirect descriptions are now sanitized before they are returned.
- The local auth provider login form now treats the password as sensitive input.
- Copying a code snippet no longer includes a trailing newline.
- Entries in the MDM download package are now stamped with a modification time.
Upgrade Notes
Obot end user licensing has changed. Starting with v0.25.0, Obot is offered in three editions, which are Obot, Obot Community, and Obot Enterprise. The code remains 100 percent MIT licensed, and parts that were previously closed source, including the enterprise auth providers and model providers, are now open source. Before you upgrade, check how the change affects your deployment:
- If you already have an Enterprise license, nothing changes for you.
- If you run without a license and have more than 100 users or devices, existing users and devices keep working, but you will not be able to add new ones.
- Model providers that previously required an enterprise license are now available at every edition.
- If you run without an enterprise license and use GitHub or Google as your auth provider, you are now subject to the 100 user limit, which did not apply to you before.
Tool call enforcement is not supported for Visual Studio Code. Claude Code, Codex, and Cursor support enforcement. Visual Studio Code does not, because its pre-tool hook does not say which MCP server a tool belongs to. Local tool call auditing for Visual Studio Code continues to work. See #7425 for details.
What's Changed
- fix: make the license provider more HA by @thedadams in #7292
- chore: update vulnerable dependencies by @calvinmclean in #7261
- fix: don't hold a DB transaction across auth provider HTTP calls by @ibuildthecloud in #7228
- chore: update vulnerable UI dependencies by @calvinmclean in #7304
- docs: update example k8s values file by @cloudnautique in #7306
- feat: tool-call enforcement backend for MDM configurations by @g-linville in #7282
- chore: remove Bifrost LLM dispatch by @calvinmclean in #7233
- chore: use CODEOWNERS for dependency reviews by @calvinmclean in #7316
- fix: intialize composite clients upfront by @thedadams in #7315
- feat: add Community Edition enrollment API and UI by @thedadams in #7303
- fix: highlight missing Kubernetes secret bindings by @calvinmclean in #7246
- enhance: admin devices & mcp filters getting started guide by @ivyjeong13 in #7319
- feat(tunnels): add managed MCP WebSocket tunneling by @thedadams in #7311
- fix: always set peer config in helm chart by @thedadams in #7327
- chore: update "getting started" obot sentry guide steps & text by @ivyjeong13 in #7326
- fix: send spec-ful issuer by @thedadams in #7328
- chore: add logging for oauth errors by @thedadams in #7329
- enhance: update My Api Keys -> Agent Auth Scope by @ivyjeong13 in #7323
- fix: remove undesired fields from the tunnels table by @thedadams in #7338
- feat: add support for user limits by @thedadams in #7322
- fix: resolve provider model IDs with slashes by @calvinmclean in #7307
- fix: ui changes for agent auto scope details & text updates by @ivyjeong13 in #7344
- fix(license): validate community email domains by @thedadams in #7342
- fix: prefer tunnel display name to id in errors by @thedadams in #7337
- chore(ui): update MCP tunnels by @thedadams in #7340
- fix: disallow removing in-use allowed URLs for tunnels by @thedadams in #7339
- fix(ui): offer community license from resolve dialog by @thedadams in #7345
- enhance: return user limit and user count in version API by @thedadams in #7349
- fix(ui): show disconnected MCP tunnel status by @thedadams in #7343
- feat: add ui for enforcement and backend tweaks by @g-linville in #7332
- chore: change Community Edition to Obot Community by @thedadams in #7351
- fix: use sensitive input for local auth login by @ivyjeong13 in #7346
- chore: change to forbidden status for too many users by @thedadams in #7360
- fix: disable interaction w/ "getting started" guides & add steps in obot-sentry guide by @ivyjeong13 in #7359
- fix: community edition license ui updates by @ivyjeong13 in #7352
- fix: reject resource URLs without an MCP ID by @thedadams in #7361
- docs: add enforcement by @g-linville in #7362
- fix(ui): avoid duplicate tunnel disconnected status by @thedadams in #7365
- fix: stamp MDM download zip entries with a modification time by @njhale in #7363
- chore: update docs w/ reskin api keys -> agent auth scopes by @ivyjeong13 in #7364
- enhance(devices): add limits similar to users by @thedadams in #7368
- fix: update licensing page & add community logo by @ivyjeong13 in #7370
- fix: strip trailing newline when copying code snippets by @njhale in #7372
- Route OAuth debugger requests through MCP tunnels by @thedadams in #7355
- fix(oauth): sanitize error redirect descriptions by @thedadams in #7369
- fix: ensure backend APIs are not authorized by UI by @thedadams in #7375
- chore: general ui cleanup by @ivyjeong13 in #7358
- docs/architecture diagram image by @cjellick in #7408
- docs: mention Cursor settings for enforcement by @g-linville in #7373
- fix: ensure caches are started before start the server by @thedadams in #7411
- fix: limit models & model access policy to llm/llm-mini by @ivyjeong13 in #7341
- fix: use creatable capabilities constant in agent auth scope details view by @ivyjeong13 in #7416
- fix(docs): disable Codex web search for Azure and Bedrock by @calvinmclean in #7418
- chore: bump obot-sentry default version to v0.1.4 by @njhale in #7421
- fix: set correct tab when linking to /admin/devices by @g-linville in #7419
- fix(ui): more general ui cleanup by @ivyjeong13 in #7422
- chore: update CLAUDE.md by @g-linville in #7415
- chore: enhancement UI: improve table by @g-linville in #7427
- fix: sticky audit log table headers when scrolling by @ivyjeong13 in #7428
- Docs: Explain new license tiers by @cjellick in #7424
- Docs: Cut v0.25.0 docs version by @cjellick in #7429
Full Changelog: v0.24.1...v0.25.0