Compare commits

..

2 Commits

Author SHA1 Message Date
Alex
f990a05fc0 docs: fix locale-prefixed links in security pages
Address Copilot review feedback to use locale-prefixed paths for
MCP security links (/en/mcp/security, /ko/mcp/security, etc.) to
keep users in their selected language.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-02 13:13:17 -07:00
Iris Clawd
e0887276c3 docs: add top-level Security Policy page across all languages
Create a dedicated Security Policy page (docs/{en,pt-BR,ko,ar}/security.mdx)
with vulnerability reporting instructions pointing to the Bugcrowd VDP
(crewai-vdp-ess@submit.bugcrowd.com), consistent with the updated security
policy from PR #5096.

The page is added to the Documentation tab navigation (after Telemetry)
across all versions and languages in docs.json.

This is a top-level security page, not buried inside MCP docs.
2026-04-02 13:12:56 -07:00
15 changed files with 310 additions and 172 deletions

View File

@@ -139,7 +139,19 @@ mode: "wide"
- **الالتزام بمواصفات ترخيص MCP**: إذا كنت تنفذ المصادقة والترخيص، اتبع بدقة [مواصفات ترخيص MCP](https://modelcontextprotocol.io/specification/draft/basic/authorization).
- **تدقيقات أمنية منتظمة**: إذا كان خادم MCP يتعامل مع بيانات حساسة، فكر في إجراء تدقيقات أمنية دورية.
## 5. قراءة إضافية
## 5. الإبلاغ عن الثغرات الأمنية
إذا اكتشفت ثغرة أمنية في CrewAI، يرجى الإبلاغ عنها بشكل مسؤول من خلال برنامج الكشف عن الثغرات (VDP) الخاص بنا على Bugcrowd:
**أرسل التقارير إلى:** [crewai-vdp-ess@submit.bugcrowd.com](mailto:crewai-vdp-ess@submit.bugcrowd.com)
<Warning>
**لا تكشف** عن الثغرات عبر issues العامة على GitHub أو pull requests أو وسائل التواصل الاجتماعي. لن تتم مراجعة التقارير المقدمة عبر قنوات غير Bugcrowd.
</Warning>
لمزيد من التفاصيل، راجع [سياسة الأمان](https://github.com/crewAIInc/crewAI/blob/main/.github/security.md) الخاصة بنا.
## 6. قراءة إضافية
لمزيد من المعلومات التفصيلية حول أمان MCP، راجع التوثيق الرسمي:
- **[أمان نقل MCP](https://modelcontextprotocol.io/docs/concepts/transports#security-considerations)**

22
docs/ar/security.mdx Normal file
View File

@@ -0,0 +1,22 @@
---
title: سياسة الأمان
description: تعرف على كيفية الإبلاغ عن الثغرات الأمنية وممارسات الأمان في CrewAI.
icon: shield
mode: "wide"
---
## الإبلاغ عن الثغرات الأمنية
إذا اكتشفت ثغرة أمنية في CrewAI، يرجى الإبلاغ عنها بشكل مسؤول من خلال برنامج الكشف عن الثغرات (VDP) الخاص بنا على Bugcrowd:
**أرسل التقارير إلى:** [crewai-vdp-ess@submit.bugcrowd.com](mailto:crewai-vdp-ess@submit.bugcrowd.com)
<Warning>
**لا تكشف** عن الثغرات عبر issues العامة على GitHub أو pull requests أو وسائل التواصل الاجتماعي. لن تتم مراجعة التقارير المقدمة عبر قنوات غير Bugcrowd.
</Warning>
لمزيد من التفاصيل، راجع [سياسة الأمان على GitHub](https://github.com/crewAIInc/crewAI/blob/main/.github/security.md).
## موارد الأمان
- **[اعتبارات أمان MCP](/ar/mcp/security)** — أفضل الممارسات لدمج خوادم MCP بأمان مع وكلاء CrewAI، بما في ذلك أمان النقل ومخاطر حقن الأوامر ونصائح تنفيذ الخادم.

View File

@@ -369,6 +369,12 @@
"pages": [
"en/telemetry"
]
},
{
"group": "Security",
"pages": [
"en/security"
]
}
]
},
@@ -839,6 +845,12 @@
"pages": [
"en/telemetry"
]
},
{
"group": "Security",
"pages": [
"en/security"
]
}
]
},
@@ -1308,6 +1320,12 @@
"pages": [
"en/telemetry"
]
},
{
"group": "Security",
"pages": [
"en/security"
]
}
]
},
@@ -1777,6 +1795,12 @@
"pages": [
"en/telemetry"
]
},
{
"group": "Security",
"pages": [
"en/security"
]
}
]
},
@@ -2247,6 +2271,12 @@
"pages": [
"en/telemetry"
]
},
{
"group": "Security",
"pages": [
"en/security"
]
}
]
},
@@ -2715,6 +2745,12 @@
"pages": [
"en/telemetry"
]
},
{
"group": "Security",
"pages": [
"en/security"
]
}
]
},
@@ -3186,6 +3222,12 @@
"pages": [
"en/telemetry"
]
},
{
"group": "Security",
"pages": [
"en/security"
]
}
]
},
@@ -3671,6 +3713,12 @@
"pages": [
"pt-BR/telemetry"
]
},
{
"group": "Segurança",
"pages": [
"pt-BR/security"
]
}
]
},
@@ -4125,6 +4173,12 @@
"pages": [
"pt-BR/telemetry"
]
},
{
"group": "Segurança",
"pages": [
"pt-BR/security"
]
}
]
},
@@ -4579,6 +4633,12 @@
"pages": [
"pt-BR/telemetry"
]
},
{
"group": "Segurança",
"pages": [
"pt-BR/security"
]
}
]
},
@@ -5033,6 +5093,12 @@
"pages": [
"pt-BR/telemetry"
]
},
{
"group": "Segurança",
"pages": [
"pt-BR/security"
]
}
]
},
@@ -5486,6 +5552,12 @@
"pages": [
"pt-BR/telemetry"
]
},
{
"group": "Segurança",
"pages": [
"pt-BR/security"
]
}
]
},
@@ -5939,6 +6011,12 @@
"pages": [
"pt-BR/telemetry"
]
},
{
"group": "Segurança",
"pages": [
"pt-BR/security"
]
}
]
},
@@ -6393,6 +6471,12 @@
"pages": [
"pt-BR/telemetry"
]
},
{
"group": "Segurança",
"pages": [
"pt-BR/security"
]
}
]
},
@@ -6890,6 +6974,12 @@
"pages": [
"ko/telemetry"
]
},
{
"group": "보안",
"pages": [
"ko/security"
]
}
]
},
@@ -7356,6 +7446,12 @@
"pages": [
"ko/telemetry"
]
},
{
"group": "보안",
"pages": [
"ko/security"
]
}
]
},
@@ -7822,6 +7918,12 @@
"pages": [
"ko/telemetry"
]
},
{
"group": "보안",
"pages": [
"ko/security"
]
}
]
},
@@ -8288,6 +8390,12 @@
"pages": [
"ko/telemetry"
]
},
{
"group": "보안",
"pages": [
"ko/security"
]
}
]
},
@@ -8753,6 +8861,12 @@
"pages": [
"ko/telemetry"
]
},
{
"group": "보안",
"pages": [
"ko/security"
]
}
]
},
@@ -9218,6 +9332,12 @@
"pages": [
"ko/telemetry"
]
},
{
"group": "보안",
"pages": [
"ko/security"
]
}
]
},
@@ -9684,6 +9804,12 @@
"pages": [
"ko/telemetry"
]
},
{
"group": "보안",
"pages": [
"ko/security"
]
}
]
},
@@ -10181,6 +10307,12 @@
"pages": [
"ar/telemetry"
]
},
{
"group": "الأمان",
"pages": [
"ar/security"
]
}
]
},
@@ -10647,6 +10779,12 @@
"pages": [
"ar/telemetry"
]
},
{
"group": "الأمان",
"pages": [
"ar/security"
]
}
]
},
@@ -11113,6 +11251,12 @@
"pages": [
"ar/telemetry"
]
},
{
"group": "الأمان",
"pages": [
"ar/security"
]
}
]
},
@@ -11579,6 +11723,12 @@
"pages": [
"ar/telemetry"
]
},
{
"group": "الأمان",
"pages": [
"ar/security"
]
}
]
},
@@ -12044,6 +12194,12 @@
"pages": [
"ar/telemetry"
]
},
{
"group": "الأمان",
"pages": [
"ar/security"
]
}
]
},
@@ -12509,6 +12665,12 @@
"pages": [
"ar/telemetry"
]
},
{
"group": "الأمان",
"pages": [
"ar/security"
]
}
]
},
@@ -12975,6 +13137,12 @@
"pages": [
"ar/telemetry"
]
},
{
"group": "الأمان",
"pages": [
"ar/security"
]
}
]
},
@@ -13291,4 +13459,4 @@
"reddit": "https://www.reddit.com/r/crewAIInc/"
}
}
}
}

View File

@@ -156,7 +156,19 @@ If you are developing an MCP server that CrewAI agents might connect to, conside
- **Adherence to MCP Authorization Spec**: If implementing authentication and authorization, strictly follow the [MCP Authorization specification](https://modelcontextprotocol.io/specification/draft/basic/authorization) and relevant [OAuth 2.0 security best practices](https://datatracker.ietf.org/doc/html/rfc9700).
- **Regular Security Audits**: If your MCP server handles sensitive data, performs critical operations, or is publicly exposed, consider periodic security audits by qualified professionals.
## 5. Further Reading
## 5. Reporting Security Vulnerabilities
If you discover a security vulnerability in CrewAI, please report it responsibly through our Bugcrowd Vulnerability Disclosure Program (VDP):
**Submit reports to:** [crewai-vdp-ess@submit.bugcrowd.com](mailto:crewai-vdp-ess@submit.bugcrowd.com)
<Warning>
**Do not** disclose vulnerabilities via public GitHub issues, pull requests, or social media. Reports submitted via channels other than Bugcrowd will not be reviewed.
</Warning>
For full details, see our [Security Policy](https://github.com/crewAIInc/crewAI/blob/main/.github/security.md).
## 6. Further Reading
For more detailed information on MCP security, refer to the official documentation:
- **[MCP Transport Security](https://modelcontextprotocol.io/docs/concepts/transports#security-considerations)**

22
docs/en/security.mdx Normal file
View File

@@ -0,0 +1,22 @@
---
title: Security Policy
description: Learn how to report security vulnerabilities and about CrewAI's security practices.
icon: shield
mode: "wide"
---
## Reporting Security Vulnerabilities
If you discover a security vulnerability in CrewAI, please report it responsibly through our Bugcrowd Vulnerability Disclosure Program (VDP):
**Submit reports to:** [crewai-vdp-ess@submit.bugcrowd.com](mailto:crewai-vdp-ess@submit.bugcrowd.com)
<Warning>
**Do not** disclose vulnerabilities via public GitHub issues, pull requests, or social media. Reports submitted via channels other than Bugcrowd will not be reviewed.
</Warning>
For full details, see our [Security Policy on GitHub](https://github.com/crewAIInc/crewAI/blob/main/.github/security.md).
## Security Resources
- **[MCP Security Considerations](/en/mcp/security)** — Best practices for securely integrating MCP servers with your CrewAI agents, including transport security, prompt injection risks, and server implementation advice.

View File

@@ -156,7 +156,19 @@ CrewAI 에이전트가 연결할 수 있는 MCP 서버를 개발하고 있다면
- **MCP 인증 사양 준수**: 인증 및 권한 부여를 구현할 경우, [MCP Authorization specification](https://modelcontextprotocol.io/specification/draft/basic/authorization) 및 관련 [OAuth 2.0 security best practices](https://datatracker.ietf.org/doc/html/rfc9700)를 엄격히 준수하세요.
- **정기적인 보안 감사**: MCP 서버가 민감한 데이터를 처리하거나, 중요한 작업을 수행하거나, 대외적으로 노출된 경우 자격을 갖춘 전문가의 정기적인 보안 감사를 고려하세요.
## 5. 추가 참고 자료
## 5. 보안 취약점 보고
CrewAI에서 보안 취약점을 발견하셨다면, Bugcrowd 취약점 공개 프로그램(VDP)을 통해 책임감 있게 보고해 주세요:
**보고서 제출:** [crewai-vdp-ess@submit.bugcrowd.com](mailto:crewai-vdp-ess@submit.bugcrowd.com)
<Warning>
공개 GitHub 이슈, 풀 리퀘스트 또는 소셜 미디어를 통해 취약점을 공개하지 **마세요**. Bugcrowd 이외의 채널로 제출된 보고서는 검토되지 않습니다.
</Warning>
자세한 내용은 [보안 정책](https://github.com/crewAIInc/crewAI/blob/main/.github/security.md)을 참조하세요.
## 6. 추가 참고 자료
MCP 보안에 대한 자세한 내용은 공식 문서를 참고하세요:
- **[MCP 전송 보안](https://modelcontextprotocol.io/docs/concepts/transports#security-considerations)**

22
docs/ko/security.mdx Normal file
View File

@@ -0,0 +1,22 @@
---
title: 보안 정책
description: CrewAI의 보안 취약점 보고 방법과 보안 관행에 대해 알아보세요.
icon: shield
mode: "wide"
---
## 보안 취약점 보고
CrewAI에서 보안 취약점을 발견하셨다면, Bugcrowd 취약점 공개 프로그램(VDP)을 통해 책임감 있게 보고해 주세요:
**보고서 제출:** [crewai-vdp-ess@submit.bugcrowd.com](mailto:crewai-vdp-ess@submit.bugcrowd.com)
<Warning>
공개 GitHub 이슈, 풀 리퀘스트 또는 소셜 미디어를 통해 취약점을 공개하지 **마세요**. Bugcrowd 이외의 채널로 제출된 보고서는 검토되지 않습니다.
</Warning>
자세한 내용은 [GitHub 보안 정책](https://github.com/crewAIInc/crewAI/blob/main/.github/security.md)을 참조하세요.
## 보안 리소스
- **[MCP 보안 고려사항](/ko/mcp/security)** — MCP 서버를 CrewAI 에이전트와 안전하게 통합하기 위한 모범 사례로, 전송 보안, 프롬프트 인젝션 위험 및 서버 구현 권장 사항을 포함합니다.

View File

@@ -156,7 +156,19 @@ Se você está desenvolvendo um servidor MCP ao qual agentes CrewAI possam se co
- **Aderência à Especificação de Autorização MCP**: Caso implemente autenticação e autorização, siga estritamente a [especificação de autorização MCP](https://modelcontextprotocol.io/specification/draft/basic/authorization) e as [melhores práticas de segurança OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc9700) relevantes.
- **Auditorias de Segurança Regulares**: Caso seu servidor MCP manipule dados sensíveis, realize operações críticas ou seja exposto publicamente, considere auditorias de segurança periódicas conduzidas por profissionais qualificados.
## 5. Leituras Adicionais
## 5. Reportando Vulnerabilidades de Segurança
Se você descobrir uma vulnerabilidade de segurança no CrewAI, por favor reporte de forma responsável através do nosso Programa de Divulgação de Vulnerabilidades (VDP) no Bugcrowd:
**Envie relatórios para:** [crewai-vdp-ess@submit.bugcrowd.com](mailto:crewai-vdp-ess@submit.bugcrowd.com)
<Warning>
**Não** divulgue vulnerabilidades por meio de issues públicas no GitHub, pull requests ou redes sociais. Relatórios enviados por outros canais que não o Bugcrowd não serão analisados.
</Warning>
Para mais detalhes, consulte nossa [Política de Segurança](https://github.com/crewAIInc/crewAI/blob/main/.github/security.md).
## 6. Leituras Adicionais
Para informações mais detalhadas sobre segurança MCP, consulte a documentação oficial:
- **[Segurança de Transporte MCP](https://modelcontextprotocol.io/docs/concepts/transports#security-considerations)**

22
docs/pt-BR/security.mdx Normal file
View File

@@ -0,0 +1,22 @@
---
title: Política de Segurança
description: Saiba como reportar vulnerabilidades de segurança e sobre as práticas de segurança do CrewAI.
icon: shield
mode: "wide"
---
## Reportando Vulnerabilidades de Segurança
Se você descobrir uma vulnerabilidade de segurança no CrewAI, por favor reporte de forma responsável através do nosso Programa de Divulgação de Vulnerabilidades (VDP) no Bugcrowd:
**Envie relatórios para:** [crewai-vdp-ess@submit.bugcrowd.com](mailto:crewai-vdp-ess@submit.bugcrowd.com)
<Warning>
**Não** divulgue vulnerabilidades por meio de issues públicas no GitHub, pull requests ou redes sociais. Relatórios enviados por outros canais que não o Bugcrowd não serão analisados.
</Warning>
Para mais detalhes, consulte nossa [Política de Segurança no GitHub](https://github.com/crewAIInc/crewAI/blob/main/.github/security.md).
## Recursos de Segurança
- **[Considerações de Segurança MCP](/pt-BR/mcp/security)** — Melhores práticas para integrar servidores MCP com segurança aos seus agentes CrewAI, incluindo segurança de transporte, riscos de injeção de prompt e conselhos de implementação de servidor.

View File

@@ -7,7 +7,6 @@ various transport types, similar to OpenAI's Agents SDK.
from pydantic import BaseModel, Field
from crewai.mcp.filters import ToolFilter
from crewai.mcp.transports.stdio import DEFAULT_ALLOWED_COMMANDS
class MCPServerStdio(BaseModel):
@@ -45,14 +44,6 @@ class MCPServerStdio(BaseModel):
default=None,
description="Optional tool filter for filtering available tools.",
)
allowed_commands: frozenset[str] | None = Field(
default=DEFAULT_ALLOWED_COMMANDS,
description=(
"Optional frozenset of allowed command basenames for security validation. "
"Defaults to common runtimes (python, node, npx, uvx, uv, deno, docker). "
"Set to None to disable the allowlist check."
),
)
cache_tools_list: bool = Field(
default=False,
description="Whether to cache the tool list for faster subsequent access.",

View File

@@ -292,7 +292,6 @@ class MCPToolResolver:
command=mcp_config.command,
args=mcp_config.args,
env=mcp_config.env,
allowed_commands=mcp_config.allowed_commands,
)
server_name = f"{mcp_config.command}_{'_'.join(mcp_config.args)}"
elif isinstance(mcp_config, MCPServerHTTP):

View File

@@ -3,12 +3,11 @@
from crewai.mcp.transports.base import BaseTransport, TransportType
from crewai.mcp.transports.http import HTTPTransport
from crewai.mcp.transports.sse import SSETransport
from crewai.mcp.transports.stdio import DEFAULT_ALLOWED_COMMANDS, StdioTransport
from crewai.mcp.transports.stdio import StdioTransport
__all__ = [
"BaseTransport",
"DEFAULT_ALLOWED_COMMANDS",
"HTTPTransport",
"SSETransport",
"StdioTransport",

View File

@@ -9,22 +9,6 @@ from typing_extensions import Self
from crewai.mcp.transports.base import BaseTransport, TransportType
# Default allowlist for common MCP server runtimes.
# Covers the vast majority of MCP server launch commands.
# Pass ``allowed_commands=None`` to disable validation entirely.
DEFAULT_ALLOWED_COMMANDS: frozenset[str] = frozenset(
{
"python",
"python3",
"node",
"npx",
"uvx",
"uv",
"deno",
"docker",
}
)
class StdioTransport(BaseTransport):
"""Stdio transport for connecting to local MCP servers.
@@ -50,7 +34,6 @@ class StdioTransport(BaseTransport):
command: str,
args: list[str] | None = None,
env: dict[str, str] | None = None,
allowed_commands: frozenset[str] | None = DEFAULT_ALLOWED_COMMANDS,
**kwargs: Any,
) -> None:
"""Initialize stdio transport.
@@ -59,26 +42,9 @@ class StdioTransport(BaseTransport):
command: Command to execute (e.g., "python", "node", "npx").
args: Command arguments (e.g., ["server.py"] or ["-y", "@mcp/server"]).
env: Environment variables to pass to the process.
allowed_commands: Optional frozenset of allowed command basenames.
Defaults to ``DEFAULT_ALLOWED_COMMANDS`` which includes common
runtimes (python, node, npx, uvx, uv, deno, docker). Pass
``None`` to disable the check entirely.
**kwargs: Additional transport options.
"""
super().__init__(**kwargs)
if allowed_commands is not None:
base_command = os.path.basename(command)
# Strip extension for Windows compatibility (e.g., python.exe -> python)
base_command = os.path.splitext(base_command)[0]
if base_command not in allowed_commands:
raise ValueError(
f"Command '{command}' is not in the allowed commands list: "
f"{sorted(allowed_commands)}. "
f"To allow this command, add it to allowed_commands or pass "
f"allowed_commands=None to disable this check."
)
self.command = command
self.args = args or []
self.env = env or {}

View File

@@ -1,28 +0,0 @@
"""Tests for MCPServerStdio allowed_commands config integration."""
from crewai.mcp.config import MCPServerStdio
from crewai.mcp.transports.stdio import DEFAULT_ALLOWED_COMMANDS
class TestMCPServerStdioConfig:
"""Tests for the allowed_commands field on MCPServerStdio."""
def test_default_allowed_commands(self):
"""MCPServerStdio should default to DEFAULT_ALLOWED_COMMANDS."""
config = MCPServerStdio(command="python", args=["server.py"])
assert config.allowed_commands == DEFAULT_ALLOWED_COMMANDS
def test_custom_allowed_commands(self):
"""Users can override allowed_commands in config."""
custom = frozenset({"my-runtime"})
config = MCPServerStdio(
command="my-runtime", args=[], allowed_commands=custom
)
assert config.allowed_commands == custom
def test_none_allowed_commands(self):
"""Users can disable the allowlist via config."""
config = MCPServerStdio(
command="anything", args=[], allowed_commands=None
)
assert config.allowed_commands is None

View File

@@ -1,93 +0,0 @@
"""Tests for StdioTransport command allowlist validation."""
import pytest
from crewai.mcp.transports.stdio import DEFAULT_ALLOWED_COMMANDS, StdioTransport
class TestStdioTransportAllowlist:
"""Tests for the command allowlist feature."""
def test_default_allowed_commands_contains_common_runtimes(self):
"""DEFAULT_ALLOWED_COMMANDS should include all common MCP server runtimes."""
expected = {"python", "python3", "node", "npx", "uvx", "uv", "deno", "docker"}
assert expected == DEFAULT_ALLOWED_COMMANDS
def test_allowed_command_passes_validation(self):
"""Commands in the default allowlist should be accepted."""
for cmd in DEFAULT_ALLOWED_COMMANDS:
transport = StdioTransport(command=cmd, args=["server.py"])
assert transport.command == cmd
def test_allowed_command_with_full_path(self):
"""Full paths to allowed commands should pass (basename is checked)."""
transport = StdioTransport(command="/usr/bin/python3", args=["server.py"])
assert transport.command == "/usr/bin/python3"
def test_disallowed_command_raises_value_error(self):
"""Commands not in the allowlist should raise ValueError."""
with pytest.raises(ValueError, match="not in the allowed commands list"):
StdioTransport(command="malicious-binary", args=["--evil"])
def test_disallowed_command_with_full_path_raises(self):
"""Full paths to disallowed commands should also be rejected."""
with pytest.raises(ValueError, match="not in the allowed commands list"):
StdioTransport(command="/tmp/evil/script", args=[])
def test_allowed_commands_none_disables_validation(self):
"""Setting allowed_commands=None should disable the check entirely."""
transport = StdioTransport(
command="any-custom-binary",
args=["--flag"],
allowed_commands=None,
)
assert transport.command == "any-custom-binary"
def test_custom_allowlist(self):
"""Users should be able to pass a custom allowlist."""
custom = frozenset({"my-server", "python"})
# Allowed
transport = StdioTransport(
command="my-server", args=[], allowed_commands=custom
)
assert transport.command == "my-server"
# Not allowed
with pytest.raises(ValueError, match="not in the allowed commands list"):
StdioTransport(command="node", args=[], allowed_commands=custom)
def test_extended_allowlist(self):
"""Users should be able to extend the default allowlist."""
extended = DEFAULT_ALLOWED_COMMANDS | frozenset({"my-custom-runtime"})
transport = StdioTransport(
command="my-custom-runtime", args=[], allowed_commands=extended
)
assert transport.command == "my-custom-runtime"
# Original defaults still work
transport2 = StdioTransport(
command="python", args=["server.py"], allowed_commands=extended
)
assert transport2.command == "python"
def test_error_message_includes_sorted_allowed_commands(self):
"""The error message should list the allowed commands for discoverability."""
with pytest.raises(ValueError) as exc_info:
StdioTransport(command="bad-cmd", args=[])
error_msg = str(exc_info.value)
assert "bad-cmd" in error_msg
assert "allowed_commands=None" in error_msg
def test_args_and_env_still_work(self):
"""Existing args and env functionality should be unaffected."""
transport = StdioTransport(
command="python",
args=["server.py", "--port", "8080"],
env={"API_KEY": "test123"},
)
assert transport.command == "python"
assert transport.args == ["server.py", "--port", "8080"]
assert transport.env == {"API_KEY": "test123"}