diff --git a/pyproject.toml b/pyproject.toml
index 2959656..c0671fb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,7 +9,7 @@ description = "The definitive MCP for AI-assisted Godot development"
 readme = "README.md"
 license = "MIT"
 requires-python = ">=3.10"
-dependencies = ["mcp>=1.0.0"]
+dependencies = ["mcp>=1.0.0", "websockets>=14.0"]
 
 [project.optional-dependencies]
 dev = ["pytest>=7.0", "pytest-asyncio>=0.21"]
diff --git a/src/godotiq/bridge/session.py b/src/godotiq/bridge/session.py
new file mode 100644
index 0000000..663f863
--- /dev/null
+++ b/src/godotiq/bridge/session.py
@@ -0,0 +1,66 @@
+"""Shared bridge connection manager — singleton with async lock."""
+
+from __future__ import annotations
+
+import asyncio
+import os
+from typing import Optional
+
+from godotiq.bridge.connection import BridgeConnection, BridgeConnectionError
+
+_bridge: Optional[BridgeConnection] = None
+_bridge_lock: Optional[asyncio.Lock] = None
+
+DEFAULT_PORT = 6007
+
+
+async def get_bridge() -> BridgeConnection:
+    """Return a connected bridge instance, creating one if needed.
+
+    Lazily initializes the async lock and auto-reconnects if the
+    previous connection was lost.
+    """
+    global _bridge, _bridge_lock
+
+    if _bridge_lock is None:
+        _bridge_lock = asyncio.Lock()
+
+    async with _bridge_lock:
+        if _bridge is not None and _bridge.is_connected:
+            return _bridge
+
+        if _bridge is not None:
+            await _bridge.disconnect()
+
+        port = int(os.environ.get("GODOTIQ_ADDON_PORT", str(DEFAULT_PORT)))
+        _bridge = BridgeConnection(port=port)
+        await _bridge.connect()
+        return _bridge
+
+
+async def get_bridge_or_none() -> Optional[BridgeConnection]:
+    """Return a connected bridge or None on failure.
+
+    Used by editor_context for graceful fallback when the addon
+    is not running.
+    """
+    try:
+        return await get_bridge()
+    except Exception:
+        return None
+
+
+async def close_bridge() -> None:
+    """Disconnect and discard the shared bridge instance.
+
+    Called in the server lifespan's finally block.
+    """
+    global _bridge, _bridge_lock
+
+    if _bridge_lock is None:
+        _bridge_lock = asyncio.Lock()
+
+    async with _bridge_lock:
+        if _bridge is not None:
+            await _bridge.disconnect()
+            _bridge = None
diff --git a/src/godotiq/server.py b/src/godotiq/server.py
index 38992cd..5cf38b9 100644
--- a/src/godotiq/server.py
+++ b/src/godotiq/server.py
@@ -33,7 +33,11 @@ async def godotiq_lifespan(server):
     else:
         session = None
         logger.warning("No Godot project found. Tools will return errors.")
-    yield {"session": session}
+    try:
+        yield {"session": session}
+    finally:
+        from godotiq.bridge.session import close_bridge
+        await close_bridge()
 
 
 mcp = FastMCP(name="godotiq", lifespan=godotiq_lifespan)
@@ -51,6 +55,7 @@ from godotiq.tools import code  # noqa: E402, F401
 from godotiq.tools import spatial  # noqa: E402, F401
 from godotiq.tools import assets  # noqa: E402, F401
 from godotiq.tools import animation  # noqa: E402, F401
+from godotiq.tools import bridge  # noqa: E402, F401
 
 
 def main() -> None:
diff --git a/src/godotiq/tools/bridge/__init__.py b/src/godotiq/tools/bridge/__init__.py
index e5fbd7a..dd62416 100644
--- a/src/godotiq/tools/bridge/__init__.py
+++ b/src/godotiq/tools/bridge/__init__.py
@@ -1 +1,136 @@
-"""Intelligent Bridge tools — runtime communication with Godot addon."""
+"""Bridge tools — MCP wrappers for runtime communication with the Godot addon."""
+
+from __future__ import annotations
+
+from mcp.server.fastmcp import Context
+
+from godotiq.server import mcp
+from godotiq.bridge.connection import BridgeConnectionError, BridgeTimeoutError, BridgeError
+
+from godotiq.tools.bridge.screenshot import screenshot as _screenshot
+from godotiq.tools.bridge.run import run as _run
+from godotiq.tools.bridge.perf_snapshot import perf_snapshot as _perf_snapshot
+from godotiq.tools.bridge.editor_context import editor_context as _editor_context
+
+
+@mcp.tool(
+    name="godotiq_screenshot",
+    annotations={
+        "readOnlyHint": True,
+        "destructiveHint": False,
+        "idempotentHint": False,
+        "openWorldHint": True,
+    },
+)
+async def godotiq_screenshot(
+    viewport: str = "game",
+    scale: float = 0.5,
+    format: str = "webp",
+    ctx: Context = None,
+) -> dict:
+    """Capture a screenshot from the running Godot game.
+
+    Args:
+        viewport: Which viewport to capture ("game").
+        scale: Image scale factor (0.0-1.0). Values outside range clamped to 0.5.
+        format: Image format ("webp", "png", "jpg"). Invalid values fall back to "webp".
+        ctx: MCP context (unused).
+
+    Returns:
+        Dict with image (base64), format, width, height.
+    """
+    try:
+        return await _screenshot(viewport=viewport, scale=scale, format=format)
+    except BridgeConnectionError as e:
+        return {"error": str(e), "hint": "Enable the GodotIQ addon in Godot editor and ensure it is running."}
+    except BridgeTimeoutError as e:
+        return {"error": str(e), "hint": "The game may not be running or the operation timed out."}
+    except BridgeError as e:
+        return {"error": f"[{e.code}] {e.error_message}"}
+
+
+@mcp.tool(
+    name="godotiq_run",
+    annotations={
+        "readOnlyHint": False,
+        "destructiveHint": True,
+        "idempotentHint": False,
+        "openWorldHint": True,
+    },
+)
+async def godotiq_run(
+    action: str = "play",
+    scene: str = "main",
+    ctx: Context = None,
+) -> dict:
+    """Start or stop the Godot game from the editor.
+
+    Args:
+        action: "play" to start, "stop" to halt the running game.
+        scene: Which scene to run — "main", "current", or a res:// path.
+        ctx: MCP context (unused).
+
+    Returns:
+        Dict with action and scene fields.
+    """
+    try:
+        return await _run(action=action, scene=scene)
+    except BridgeConnectionError as e:
+        return {"error": str(e), "hint": "Enable the GodotIQ addon in Godot editor and ensure it is running."}
+    except BridgeTimeoutError as e:
+        return {"error": str(e), "hint": "The game may not be running or the operation timed out."}
+    except BridgeError as e:
+        return {"error": f"[{e.code}] {e.error_message}"}
+
+
+@mcp.tool(
+    name="godotiq_perf_snapshot",
+    annotations={
+        "readOnlyHint": True,
+        "destructiveHint": False,
+        "idempotentHint": False,
+        "openWorldHint": True,
+    },
+)
+async def godotiq_perf_snapshot(ctx: Context = None) -> dict:
+    """Capture a performance snapshot from the running Godot game.
+
+    Args:
+        ctx: MCP context (unused).
+
+    Returns:
+        Dict with fps, draw_calls, triangles, objects, texture_mem, buffer_mem,
+        video_mem, total_nodes, orphan_nodes.
+    """
+    try:
+        return await _perf_snapshot()
+    except BridgeConnectionError as e:
+        return {"error": str(e), "hint": "Enable the GodotIQ addon in Godot editor and ensure it is running."}
+    except BridgeTimeoutError as e:
+        return {"error": str(e), "hint": "The game may not be running or the operation timed out."}
+    except BridgeError as e:
+        return {"error": f"[{e.code}] {e.error_message}"}
+
+
+@mcp.tool(
+    name="godotiq_editor_context",
+    annotations={
+        "readOnlyHint": True,
+        "destructiveHint": False,
+        "idempotentHint": True,
+        "openWorldHint": True,
+    },
+)
+async def godotiq_editor_context(ctx: Context = None) -> dict:
+    """Get the current editor state from the Godot addon.
+
+    Returns connected editor state (open scenes, selected nodes, game state,
+    project path) when the addon is running, or a fallback when disconnected.
+
+    Args:
+        ctx: MCP context (unused).
+
+    Returns:
+        Dict with editor context and addon_connected flag.
+    """
+    return await _editor_context()
diff --git a/src/godotiq/tools/bridge/editor_context.py b/src/godotiq/tools/bridge/editor_context.py
new file mode 100644
index 0000000..ef965e7
--- /dev/null
+++ b/src/godotiq/tools/bridge/editor_context.py
@@ -0,0 +1,8 @@
+"""Editor context tool implementation — stub for Section 06."""
+
+from __future__ import annotations
+
+
+async def editor_context() -> dict:
+    """Get the current editor state from the Godot addon."""
+    raise NotImplementedError("Section 06 not yet implemented")
diff --git a/src/godotiq/tools/bridge/perf_snapshot.py b/src/godotiq/tools/bridge/perf_snapshot.py
new file mode 100644
index 0000000..25ff0b0
--- /dev/null
+++ b/src/godotiq/tools/bridge/perf_snapshot.py
@@ -0,0 +1,8 @@
+"""Performance snapshot tool implementation — stub for Section 06."""
+
+from __future__ import annotations
+
+
+async def perf_snapshot() -> dict:
+    """Capture a performance snapshot from the running Godot game."""
+    raise NotImplementedError("Section 06 not yet implemented")
diff --git a/src/godotiq/tools/bridge/run.py b/src/godotiq/tools/bridge/run.py
new file mode 100644
index 0000000..0eb681d
--- /dev/null
+++ b/src/godotiq/tools/bridge/run.py
@@ -0,0 +1,11 @@
+"""Run tool implementation — stub for Section 06."""
+
+from __future__ import annotations
+
+
+async def run(
+    action: str = "play",
+    scene: str = "main",
+) -> dict:
+    """Start or stop the Godot game from the editor."""
+    raise NotImplementedError("Section 06 not yet implemented")
diff --git a/src/godotiq/tools/bridge/screenshot.py b/src/godotiq/tools/bridge/screenshot.py
new file mode 100644
index 0000000..f8095ba
--- /dev/null
+++ b/src/godotiq/tools/bridge/screenshot.py
@@ -0,0 +1,12 @@
+"""Screenshot tool implementation — stub for Section 06."""
+
+from __future__ import annotations
+
+
+async def screenshot(
+    viewport: str = "game",
+    scale: float = 0.5,
+    format: str = "webp",
+) -> dict:
+    """Capture a screenshot from the running Godot game."""
+    raise NotImplementedError("Section 06 not yet implemented")
