diff --git a/openhands/usage/settings/mcp-settings.mdx b/openhands/usage/settings/mcp-settings.mdx
index bf2d3956..6ebb10a4 100644
--- a/openhands/usage/settings/mcp-settings.mdx
+++ b/openhands/usage/settings/mcp-settings.mdx
@@ -192,3 +192,66 @@ Other options include:
- **Custom FastAPI/Express servers**: Build your own HTTP wrapper around stdio MCP servers.
- **Docker-based proxies**: Containerized solutions for better isolation.
- **Cloud-hosted MCP services**: Third-party services that provide MCP endpoints.
+
+---
+
+## Security with Maybe Don't
+
+[Maybe Don't](https://maybedont.ai) provides AI guardrails — real-time monitoring and policy enforcement for AI agents. It sits between OpenHands and your downstream MCP servers, validating every tool call against configurable policies (CEL rules and AI-powered analysis) before forwarding it to the downstream server.
+
+
+ Maybe Don't works as a transparent proxy. Your existing MCP server configurations stay the same — you just route them through Maybe Don't.
+
+
+### Quick Start
+
+Start Maybe Don't with Docker, configuring a downstream MCP server via environment variables:
+
+```bash
+docker run -d --name maybe-dont \
+ -p 8080:8080 \
+ -e MAYBE_DONT_SERVER_LISTEN_ADDR=0.0.0.0:8080 \
+ -e MAYBE_DONT_REQUEST_VALIDATION_AI_ENABLED=false \
+ -e MAYBE_DONT_NATIVE_TOOLS_AUDIT_REPORT_ENABLED=false \
+ -e MAYBE_DONT_DOWNSTREAM_MCP_SERVERS_FILESYSTEM_TYPE=http \
+ -e MAYBE_DONT_DOWNSTREAM_MCP_SERVERS_FILESYSTEM_URL=http://host.docker.internal:8081/sse \
+ ghcr.io/maybedont/maybe-dont:latest
+```
+
+
+ The `LISTEN_ADDR` must be `0.0.0.0` inside Docker so the port mapping works. AI validation is disabled here for a minimal setup — enable it by setting `MAYBE_DONT_VALIDATION_AI_API_KEY` instead. See [maybedont.ai/docs](https://maybedont.ai/docs) for full configuration options.
+
+
+Then point OpenHands at Maybe Don't instead of the downstream server directly:
+
+```toml
+[mcp]
+shttp_servers = [
+ "http://localhost:8080/mcp"
+]
+```
+
+Maybe Don't discovers tools from all downstream servers and exposes them through a single endpoint. Policy rules can target specific tools or servers using name prefixes (e.g., `filesystem__read_file`).
+
+For more complex setups, you can volume-mount a `maybe-dont.yaml` config file instead of using environment variables:
+
+```bash
+docker run -d --name maybe-dont \
+ -p 8080:8080 \
+ -e MAYBE_DONT_SERVER_LISTEN_ADDR=0.0.0.0:8080 \
+ -v ./config:/home/maybedont/.config/maybe-dont:ro \
+ ghcr.io/maybedont/maybe-dont:latest
+```
+
+### What It Validates
+
+- **Deterministic rules (CEL)**: Pattern-matching on tool names, arguments, and other request fields. Fast, predictable, and auditable.
+- **AI-powered rules**: Context-aware validation using an LLM for nuanced decisions that pattern matching can't handle.
+
+Both rule types support `audit_only` mode, so you can observe what would be blocked before enforcing policies.
+
+
+ Maybe Don't also provides a [security analyzer integration](/sdk/guides/security#maybe-dont-security-analyzer) for validating *all* agent actions (shell commands, file operations, browser actions) — not just MCP tool calls.
+
+
+For full documentation, see [maybedont.ai/docs](https://maybedont.ai/docs).
diff --git a/sdk/guides/security.mdx b/sdk/guides/security.mdx
index bbd30fad..050a5499 100644
--- a/sdk/guides/security.mdx
+++ b/sdk/guides/security.mdx
@@ -445,6 +445,229 @@ agent = Agent(llm=llm, tools=tools, security_analyzer=security_analyzer)
+### Maybe Don't Security Analyzer
+
+> A ready-to-run example is available [here](#ready-to-run-example-maybe-dont)!
+
+[Maybe Don't](https://maybedont.ai) provides AI guardrails — real-time monitoring and policy enforcement for AI agents. It evaluates agent actions against configurable policies (deterministic CEL rules and AI-powered analysis). The `MaybeDontAnalyzer` sends each action to Maybe Don't's validation endpoint and maps the response to a `SecurityRisk` level.
+
+This provides two complementary layers of protection:
+
+- **Security analyzer** (this section): Validates *all* agent actions before execution — shell commands, file operations, browser actions, and tool calls.
+- **[MCP proxy](/openhands/usage/settings/mcp-settings#security-with-maybe-dont)**: Validates and proxies MCP tool calls at execution time, with response validation.
+
+#### Setup
+
+Start Maybe Don't:
+
+```bash
+docker run -d --name maybe-dont \
+ -p 8080:8080 \
+ -e MAYBE_DONT_SERVER_LISTEN_ADDR=0.0.0.0:8080 \
+ -e MAYBE_DONT_REQUEST_VALIDATION_AI_ENABLED=false \
+ -e MAYBE_DONT_NATIVE_TOOLS_AUDIT_REPORT_ENABLED=false \
+ ghcr.io/maybedont/maybe-dont:latest
+```
+
+
+ AI validation is disabled here for a minimal setup. Enable it by setting `MAYBE_DONT_VALIDATION_AI_API_KEY` with your OpenAI API key. See [maybedont.ai/docs](https://maybedont.ai/docs) for full configuration.
+
+
+Configure the analyzer:
+
+```python icon="python" focus={3,5-8}
+from openhands.sdk.security import MaybeDontAnalyzer
+from openhands.sdk.security.confirmation_policy import ConfirmRisky
+
+analyzer = MaybeDontAnalyzer(gateway_url="http://localhost:8080")
+
+conversation = Conversation(agent=agent, workspace=".")
+conversation.set_security_analyzer(analyzer)
+conversation.set_confirmation_policy(ConfirmRisky())
+```
+
+The `gateway_url` can also be set via the `MAYBE_DONT_GATEWAY_URL` environment variable. When neither is provided, it defaults to `http://localhost:8080`.
+
+#### How It Works
+
+When the agent produces an action, the analyzer:
+
+1. Extracts the tool name, arguments, and agent reasoning from the `ActionEvent`.
+2. Sends a validation request to Maybe Don't's `POST /api/v1/action/validate` endpoint.
+3. Maps the `risk_level` response directly to a `SecurityRisk`:
+
+| `risk_level` | `SecurityRisk` | Meaning |
+|---|---|---|
+| `high` | HIGH | Policy denied the action |
+| `medium` | MEDIUM | Policy would deny, but running in audit-only mode |
+| `low` | LOW | Policy evaluated and approved |
+| `unknown` | UNKNOWN | No policies configured, or Maybe Don't unreachable |
+
+With the default `ConfirmRisky()` policy, HIGH and UNKNOWN actions require user confirmation. MEDIUM and LOW actions proceed automatically.
+
+#### Ready-to-run Example Maybe Dont
+
+
+Full Maybe Don't security analyzer example: [examples/01_standalone_sdk/40_maybedont_security_analyzer.py](https://github.com/OpenHands/software-agent-sdk/blob/main/examples/01_standalone_sdk/40_maybedont_security_analyzer.py)
+
+
+Validate agent actions against configurable security policies with Maybe Don't:
+
+```python icon="python" expandable examples/01_standalone_sdk/40_maybedont_security_analyzer.py
+"""OpenHands Agent SDK — Maybe Don't Security Analyzer Example
+
+This example shows how to use the MaybeDontAnalyzer to validate agent actions
+against policy rules configured in a Maybe Don't Gateway before execution.
+
+Prerequisites:
+ 1. A running Maybe Don't instance. Quick start with Docker:
+
+ docker run -d --name maybe-dont -p 8080:8080 \
+ -e MAYBE_DONT_SERVER_LISTEN_ADDR=0.0.0.0:8080 \
+ -e MAYBE_DONT_REQUEST_VALIDATION_AI_ENABLED=false \
+ -e MAYBE_DONT_NATIVE_TOOLS_AUDIT_REPORT_ENABLED=false \
+ ghcr.io/maybedont/maybe-dont:latest
+
+ For configuration, see: https://maybedont.ai/docs
+
+ 2. Set environment variables:
+ - LLM_API_KEY: Your LLM provider API key
+ - MAYBE_DONT_GATEWAY_URL: Maybe Don't URL (default: http://localhost:8080)
+
+The Maybe Don't Gateway supports two layers of protection:
+ - Security Analyzer (this example): Pre-execution validation of ALL actions
+ - MCP Proxy (separate config): Execution-time validation of MCP tool calls
+
+For more information, see: https://maybedont.ai/docs
+"""
+
+import os
+import signal
+from collections.abc import Callable
+
+from pydantic import SecretStr
+
+from openhands.sdk import LLM, Agent, BaseConversation, Conversation
+from openhands.sdk.conversation.state import (
+ ConversationExecutionStatus,
+ ConversationState,
+)
+from openhands.sdk.security.confirmation_policy import ConfirmRisky
+from openhands.sdk.security.maybedont import MaybeDontAnalyzer
+from openhands.sdk.tool import Tool
+from openhands.tools.file_editor import FileEditorTool
+from openhands.tools.terminal import TerminalTool
+
+
+# Clean ^C exit: no stack trace noise
+signal.signal(signal.SIGINT, lambda *_: (_ for _ in ()).throw(KeyboardInterrupt()))
+
+
+def _print_blocked_actions(pending_actions) -> None:
+ print(f"\n🔒 Maybe Don't blocked {len(pending_actions)} high-risk action(s):")
+ for i, action in enumerate(pending_actions, start=1):
+ snippet = str(action.action)[:100].replace("\n", " ")
+ print(f" {i}. {action.tool_name}: {snippet}...")
+
+
+def confirm_high_risk_in_console(pending_actions) -> bool:
+ """
+ Return True to approve, False to reject.
+ Defaults to 'no' on EOF/KeyboardInterrupt.
+ """
+ _print_blocked_actions(pending_actions)
+ while True:
+ try:
+ ans = (
+ input(
+ "\nThese actions were flagged as HIGH RISK by Maybe Don't. "
+ "Do you want to execute them anyway? (yes/no): "
+ )
+ .strip()
+ .lower()
+ )
+ except (EOFError, KeyboardInterrupt):
+ print("\n❌ No input received; rejecting by default.")
+ return False
+
+ if ans in ("yes", "y"):
+ print("✅ Approved — executing high-risk actions...")
+ return True
+ if ans in ("no", "n"):
+ print("❌ Rejected — skipping high-risk actions...")
+ return False
+ print("Please enter 'yes' or 'no'.")
+
+
+def run_until_finished_with_security(
+ conversation: BaseConversation, confirmer: Callable[[list], bool]
+) -> None:
+ """
+ Drive the conversation until FINISHED.
+ - If WAITING_FOR_CONFIRMATION: ask the confirmer.
+ * On approve: set execution_status = IDLE.
+ * On reject: conversation.reject_pending_actions(...).
+ """
+ while conversation.state.execution_status != ConversationExecutionStatus.FINISHED:
+ if (
+ conversation.state.execution_status
+ == ConversationExecutionStatus.WAITING_FOR_CONFIRMATION
+ ):
+ pending = ConversationState.get_unmatched_actions(conversation.state.events)
+ if not pending:
+ raise RuntimeError(
+ "⚠️ Agent is waiting for confirmation but no pending actions "
+ "were found. This should not happen."
+ )
+ if not confirmer(pending):
+ conversation.reject_pending_actions("User rejected high-risk actions")
+ continue
+
+ print("▶️ Running conversation.run()...")
+ conversation.run()
+
+
+# Configure LLM
+api_key = os.getenv("LLM_API_KEY")
+assert api_key is not None, "LLM_API_KEY environment variable is not set."
+model = os.getenv("LLM_MODEL", "anthropic/claude-sonnet-4-5-20250929")
+base_url = os.getenv("LLM_BASE_URL")
+llm = LLM(
+ usage_id="maybedont-security",
+ model=model,
+ base_url=base_url,
+ api_key=SecretStr(api_key),
+)
+
+# Tools
+tools = [
+ Tool(name=TerminalTool.name),
+ Tool(name=FileEditorTool.name),
+]
+
+# Agent
+agent = Agent(llm=llm, tools=tools)
+
+# Conversation with Maybe Don't security analyzer
+# The analyzer calls the Maybe Don't Gateway to validate actions before execution.
+# Gateway URL defaults to http://localhost:8080, or set MAYBE_DONT_GATEWAY_URL.
+conversation = Conversation(
+ agent=agent, persistence_dir="./.conversations", workspace="."
+)
+conversation.set_security_analyzer(MaybeDontAnalyzer())
+conversation.set_confirmation_policy(ConfirmRisky())
+
+print("\n1) Safe command (LOW risk - should execute automatically)...")
+conversation.send_message("List files in the current directory")
+conversation.run()
+
+print("\n2) Potentially risky command (may require confirmation)...")
+conversation.send_message("Delete all files in the /tmp directory recursively")
+run_until_finished_with_security(conversation, confirm_high_risk_in_console)
+```
+
+
+
---
## Configurable Security Policy