mirror of
https://github.com/FuzzingLabs/fuzzforge_ai.git
synced 2026-08-14 23:00:18 +02:00
fix: document mount paths in execute_hub_tool and inject volumes into persistent sessions
This commit is contained in:
@@ -539,6 +539,7 @@ class HubClient:
|
|||||||
async def start_persistent_session(
|
async def start_persistent_session(
|
||||||
self,
|
self,
|
||||||
config: HubServerConfig,
|
config: HubServerConfig,
|
||||||
|
extra_volumes: list[str] | None = None,
|
||||||
) -> PersistentSession:
|
) -> PersistentSession:
|
||||||
"""Start a persistent Docker container and initialise MCP session.
|
"""Start a persistent Docker container and initialise MCP session.
|
||||||
|
|
||||||
@@ -546,6 +547,7 @@ class HubClient:
|
|||||||
called, allowing multiple tool calls on the same session.
|
called, allowing multiple tool calls on the same session.
|
||||||
|
|
||||||
:param config: Server configuration (must be Docker type).
|
:param config: Server configuration (must be Docker type).
|
||||||
|
:param extra_volumes: Additional host:container volume mounts to inject.
|
||||||
:returns: The created persistent session.
|
:returns: The created persistent session.
|
||||||
:raises HubClientError: If the container cannot be started.
|
:raises HubClientError: If the container cannot be started.
|
||||||
|
|
||||||
@@ -590,6 +592,9 @@ class HubClient:
|
|||||||
for volume in config.volumes:
|
for volume in config.volumes:
|
||||||
cmd.extend(["-v", os.path.expanduser(volume)])
|
cmd.extend(["-v", os.path.expanduser(volume)])
|
||||||
|
|
||||||
|
for extra_vol in (extra_volumes or []):
|
||||||
|
cmd.extend(["-v", extra_vol])
|
||||||
|
|
||||||
for key, value in config.environment.items():
|
for key, value in config.environment.items():
|
||||||
cmd.extend(["-e", f"{key}={value}"])
|
cmd.extend(["-e", f"{key}={value}"])
|
||||||
|
|
||||||
|
|||||||
@@ -345,13 +345,14 @@ class HubExecutor:
|
|||||||
# Persistent session management
|
# Persistent session management
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
async def start_persistent_server(self, server_name: str) -> dict[str, Any]:
|
async def start_persistent_server(self, server_name: str, extra_volumes: list[str] | None = None) -> dict[str, Any]:
|
||||||
"""Start a persistent container session for a server.
|
"""Start a persistent container session for a server.
|
||||||
|
|
||||||
The container stays running between tool calls, allowing stateful
|
The container stays running between tool calls, allowing stateful
|
||||||
interactions (e.g., radare2 sessions, long-running fuzzing).
|
interactions (e.g., radare2 sessions, long-running fuzzing).
|
||||||
|
|
||||||
:param server_name: Name of the hub server to start.
|
:param server_name: Name of the hub server to start.
|
||||||
|
:param extra_volumes: Additional host:container volume mounts to inject.
|
||||||
:returns: Session status dictionary.
|
:returns: Session status dictionary.
|
||||||
:raises ValueError: If server not found.
|
:raises ValueError: If server not found.
|
||||||
|
|
||||||
@@ -362,7 +363,7 @@ class HubExecutor:
|
|||||||
msg = f"Server '{server_name}' not found"
|
msg = f"Server '{server_name}' not found"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
|
||||||
session = await self._client.start_persistent_session(server.config)
|
session = await self._client.start_persistent_session(server.config, extra_volumes=extra_volumes)
|
||||||
|
|
||||||
# Auto-discover tools on the new session
|
# Auto-discover tools on the new session
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -172,9 +172,16 @@ async def execute_hub_tool(
|
|||||||
:return: Tool execution result.
|
:return: Tool execution result.
|
||||||
|
|
||||||
Example identifiers:
|
Example identifiers:
|
||||||
|
- "hub:binwalk-mcp:binwalk_scan"
|
||||||
|
- "hub:yara-mcp:yara_scan_with_rules"
|
||||||
- "hub:nmap:nmap_scan"
|
- "hub:nmap:nmap_scan"
|
||||||
- "nmap:nmap_scan"
|
|
||||||
- "hub:nuclei:nuclei_scan"
|
FILE ACCESS — if set_project_assets was called, the assets directory is
|
||||||
|
mounted read-only inside the container at two standard paths:
|
||||||
|
- /app/uploads/ (used by binwalk, and tools with UPLOAD_DIR)
|
||||||
|
- /app/samples/ (used by yara, capa, and tools with SAMPLES_DIR)
|
||||||
|
Always use /app/uploads/<filename> or /app/samples/<filename> when
|
||||||
|
passing file paths to hub tools — do NOT use the host path.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
@@ -353,7 +360,22 @@ async def start_hub_server(server_name: str) -> dict[str, Any]:
|
|||||||
try:
|
try:
|
||||||
executor = _get_hub_executor()
|
executor = _get_hub_executor()
|
||||||
|
|
||||||
result = await executor.start_persistent_server(server_name)
|
# Inject project assets as Docker volume mounts (same logic as execute_hub_tool).
|
||||||
|
extra_volumes: list[str] = []
|
||||||
|
try:
|
||||||
|
storage = get_storage()
|
||||||
|
project_path = get_project_path()
|
||||||
|
assets_path = storage.get_project_assets_path(project_path)
|
||||||
|
if assets_path:
|
||||||
|
assets_str = str(assets_path)
|
||||||
|
extra_volumes = [
|
||||||
|
f"{assets_str}:/app/uploads:ro",
|
||||||
|
f"{assets_str}:/app/samples:ro",
|
||||||
|
]
|
||||||
|
except Exception: # noqa: BLE001 - never block server start due to asset injection failure
|
||||||
|
extra_volumes = []
|
||||||
|
|
||||||
|
result = await executor.start_persistent_server(server_name, extra_volumes=extra_volumes or None)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
|
|||||||
Reference in New Issue
Block a user