mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-01-08 22:38:05 -05:00
fix(mcp): authentication for mcp calls in remote runtime (#8856)
This commit is contained in:
@@ -158,7 +158,7 @@ class OpenHandsMCPConfig:
|
||||
return MCPStdioServerConfig(
|
||||
name='tavily',
|
||||
command='npx',
|
||||
args=['-y', 'tavily-mcp@0.1.4'],
|
||||
args=['-y', 'tavily-mcp@0.2.1'],
|
||||
env={'TAVILY_API_KEY': app_config.search_api_key.get_secret_value()},
|
||||
)
|
||||
else:
|
||||
|
||||
@@ -45,7 +45,15 @@ class MCPClient(BaseModel):
|
||||
try:
|
||||
# Use asyncio.wait_for to enforce the timeout
|
||||
async def connect_with_timeout():
|
||||
headers = {'Authorization': f'Bearer {api_key}'} if api_key else {}
|
||||
headers = (
|
||||
{
|
||||
'Authorization': f'Bearer {api_key}',
|
||||
's': api_key, # We need this for action execution server's MCP Router
|
||||
'X-Session-API-Key': api_key, # We need this for Remote Runtime
|
||||
}
|
||||
if api_key
|
||||
else {}
|
||||
)
|
||||
|
||||
if conversation_id:
|
||||
headers['X-OpenHands-Conversation-ID'] = conversation_id
|
||||
|
||||
@@ -887,6 +887,14 @@ fi
|
||||
"""Zip all files in the sandbox and return a path in the local filesystem."""
|
||||
raise NotImplementedError('This method is not implemented in the base class.')
|
||||
|
||||
# ====================================================================
|
||||
# Authentication
|
||||
# ====================================================================
|
||||
|
||||
@property
|
||||
def session_api_key(self) -> str | None:
|
||||
return None
|
||||
|
||||
# ====================================================================
|
||||
# VSCode
|
||||
# ====================================================================
|
||||
|
||||
@@ -436,8 +436,7 @@ class ActionExecutionClient(Runtime):
|
||||
updated_mcp_config.sse_servers.append(
|
||||
MCPSSEServerConfig(
|
||||
url=self.action_execution_server_url.rstrip('/') + '/sse',
|
||||
# No API key by default. Child runtime can override this when appropriate
|
||||
api_key=None,
|
||||
api_key=self.session_api_key,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ class RemoteRuntime(ActionExecutionClient):
|
||||
self.session,
|
||||
)
|
||||
self.available_hosts: dict[str, int] = {}
|
||||
self._session_api_key: str | None = None
|
||||
|
||||
def log(self, level: str, message: str, exc_info: bool | None = None) -> None:
|
||||
getattr(logger, level)(
|
||||
@@ -358,6 +359,15 @@ class RemoteRuntime(ActionExecutionClient):
|
||||
self.session.headers.update(
|
||||
{'X-Session-API-Key': start_response['session_api_key']}
|
||||
)
|
||||
self._session_api_key = start_response['session_api_key']
|
||||
self.log(
|
||||
'debug',
|
||||
f'Session API key setted',
|
||||
)
|
||||
|
||||
@property
|
||||
def session_api_key(self) -> str | None:
|
||||
return self._session_api_key
|
||||
|
||||
@property
|
||||
def vscode_url(self) -> str | None:
|
||||
|
||||
8
poetry.lock
generated
8
poetry.lock
generated
@@ -2459,14 +2459,14 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc
|
||||
|
||||
[[package]]
|
||||
name = "fastmcp"
|
||||
version = "2.5.1"
|
||||
version = "2.5.2"
|
||||
description = "The fast, Pythonic way to build MCP servers."
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "fastmcp-2.5.1-py3-none-any.whl", hash = "sha256:a6fe50693954a6aed89fc6e43f227dcd66e112e3d3a1d633ee22b4f435ee8aed"},
|
||||
{file = "fastmcp-2.5.1.tar.gz", hash = "sha256:0d10ec65a362ae4f78bdf3b639faf35b36cc0a1c8f5461a54fac906fe821b84d"},
|
||||
{file = "fastmcp-2.5.2-py3-none-any.whl", hash = "sha256:4ea46ef35c1308b369eff7c8a10e4c9639bed046fd646449c1227ac7c3856d83"},
|
||||
{file = "fastmcp-2.5.2.tar.gz", hash = "sha256:761c92fb54f561136f631d7d98b4920152978f6f0a66a4cef689a7983fd05c8b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -11741,4 +11741,4 @@ cffi = ["cffi (>=1.11)"]
|
||||
[metadata]
|
||||
lock-version = "2.1"
|
||||
python-versions = "^3.12,<3.14"
|
||||
content-hash = "35d7c81745aee985169bd32fff6c02fbdb56d2902e630f89aa6e99f09f3c1c4e"
|
||||
content-hash = "42d590343d06314e3e2b0b47c82eae65cd1255d1fed0b76a229c702add0a4f55"
|
||||
|
||||
@@ -83,7 +83,7 @@ prompt-toolkit = "^3.0.50"
|
||||
poetry = "^2.1.2"
|
||||
anyio = "4.9.0"
|
||||
pythonnet = "*"
|
||||
fastmcp = "^2.3.3"
|
||||
fastmcp = "^2.5.2"
|
||||
mcpm = "1.12.0"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
|
||||
Reference in New Issue
Block a user