diff --git a/src/godotiq/bridge/protocol.py b/src/godotiq/bridge/protocol.py
index fe178ea..1b00ec5 100644
--- a/src/godotiq/bridge/protocol.py
+++ b/src/godotiq/bridge/protocol.py
@@ -16,6 +16,7 @@ TOOL_TIMEOUTS: dict[str, float] = {
     "scene_tree": 5.0,
     "node_ops": 10.0,
     "build_scene": 30.0,
+    "check_errors": 15.0,
 }
 
 SCREENSHOT_MAX_RETRIES: int = 3
diff --git a/src/godotiq/tools/bridge/__init__.py b/src/godotiq/tools/bridge/__init__.py
index a0dde86..34704e9 100644
--- a/src/godotiq/tools/bridge/__init__.py
+++ b/src/godotiq/tools/bridge/__init__.py
@@ -25,6 +25,7 @@ from godotiq.tools.bridge.save_scene import save_scene as _save_scene
 from godotiq.tools.bridge.camera import camera as _camera
 from godotiq.tools.bridge.ui_map import ui_map as _ui_map
 from godotiq.tools.bridge.build_scene import build_scene as _build_scene
+from godotiq.tools.bridge.check_errors import check_errors as _check_errors
 from godotiq.tools.output_limit import apply_output_limit, _CHAR_LIMITS
 
 
@@ -773,3 +774,32 @@ async def godotiq_build_scene(
         return {"error": f"[{e.code}] {e.error_message}"}
     except Exception as e:
         return {"error": f"Unexpected error: {e}"}
+
+
+@mcp.tool(
+    name="godotiq_check_errors",
+    annotations={
+        "readOnlyHint": True,
+        "destructiveHint": False,
+        "idempotentHint": True,
+        "openWorldHint": True,
+    },
+)
+async def godotiq_check_errors(scope: str = "scene", ctx: Context = None) -> dict:
+    """Check GDScript files for compilation/parse errors.
+
+    Args:
+        scope: "scene" (current scene + autoloads), "project" (all .gd files),
+               or "res://path/to/script.gd" (single file)
+    """
+    try:
+        result = await _check_errors(scope=scope)
+        return apply_output_limit(result, "normal")
+    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 operation timed out. Try a smaller scope."}
+    except BridgeError as e:
+        return {"error": f"[{e.code}] {e.error_message}"}
+    except Exception as e:
+        return {"error": f"Unexpected error: {e}"}
diff --git a/src/godotiq/tools/bridge/check_errors.py b/src/godotiq/tools/bridge/check_errors.py
new file mode 100644
index 0000000..fcc466e
--- /dev/null
+++ b/src/godotiq/tools/bridge/check_errors.py
@@ -0,0 +1,20 @@
+"""Check GDScript files for compilation/parse errors via the Godot bridge."""
+
+from __future__ import annotations
+
+from godotiq.bridge.session import get_bridge
+
+
+async def check_errors(scope: str = "scene") -> dict:
+    """Check GDScript files for compilation errors.
+
+    Args:
+        scope: "scene" (current scene + autoloads), "project" (all .gd files),
+               or a "res://path/to/script.gd" (single file).
+
+    Returns:
+        Dict with errors array, total count, scripts_checked, and scope.
+    """
+    bridge = await get_bridge()
+    result = await bridge.request("check_errors", params={"scope": scope})
+    return result
diff --git a/tests/test_tools/test_check_errors.py b/tests/test_tools/test_check_errors.py
new file mode 100644
index 0000000..fb24d7e
--- /dev/null
+++ b/tests/test_tools/test_check_errors.py
@@ -0,0 +1,141 @@
+"""Tests for check_errors bridge wrapper and MCP tool registration."""
+
+from __future__ import annotations
+
+import asyncio
+import pytest
+from unittest.mock import AsyncMock, patch
+
+from godotiq.bridge.connection import BridgeConnectionError, BridgeTimeoutError, BridgeError
+from godotiq.tools.bridge.check_errors import check_errors
+
+
+class TestCheckErrorsBridgeWrapper:
+    """Bridge wrapper tests for check_errors."""
+
+    async def test_clean_result(self) -> None:
+        """Returns clean result when bridge reports no errors."""
+        mock_bridge = AsyncMock()
+        mock_bridge.request.return_value = {
+            "errors": [],
+            "total": 0,
+            "scripts_checked": 5,
+            "scope": "scene",
+        }
+        with patch("godotiq.tools.bridge.check_errors.get_bridge", return_value=mock_bridge):
+            result = await check_errors()
+
+        assert result["total"] == 0
+        assert result["errors"] == []
+        assert result["scripts_checked"] == 5
+
+    async def test_forwards_errors(self) -> None:
+        """Forwards errors array from bridge response."""
+        mock_bridge = AsyncMock()
+        mock_bridge.request.return_value = {
+            "errors": [{"file": "res://player.gd", "line": 42, "error": "Identifier not found"}],
+            "total": 1,
+            "scripts_checked": 10,
+            "scope": "scene",
+        }
+        with patch("godotiq.tools.bridge.check_errors.get_bridge", return_value=mock_bridge):
+            result = await check_errors()
+
+        assert result["total"] == 1
+        assert result["errors"][0]["file"] == "res://player.gd"
+
+    async def test_passes_scope_parameter(self) -> None:
+        """Passes scope parameter to bridge.request."""
+        mock_bridge = AsyncMock()
+        mock_bridge.request.return_value = {"errors": [], "total": 0, "scripts_checked": 0, "scope": "project"}
+        with patch("godotiq.tools.bridge.check_errors.get_bridge", return_value=mock_bridge):
+            await check_errors(scope="project")
+
+        mock_bridge.request.assert_called_once_with("check_errors", params={"scope": "project"})
+
+    async def test_defaults_scope_to_scene(self) -> None:
+        """Defaults scope to 'scene' when not specified."""
+        mock_bridge = AsyncMock()
+        mock_bridge.request.return_value = {"errors": [], "total": 0, "scripts_checked": 0, "scope": "scene"}
+        with patch("godotiq.tools.bridge.check_errors.get_bridge", return_value=mock_bridge):
+            await check_errors()
+
+        mock_bridge.request.assert_called_once_with("check_errors", params={"scope": "scene"})
+
+    async def test_propagates_connection_error(self) -> None:
+        """BridgeConnectionError propagates to caller."""
+        mock_bridge = AsyncMock()
+        mock_bridge.request.side_effect = BridgeConnectionError("Not connected")
+        with patch("godotiq.tools.bridge.check_errors.get_bridge", return_value=mock_bridge):
+            with pytest.raises(BridgeConnectionError):
+                await check_errors()
+
+    async def test_propagates_timeout_error(self) -> None:
+        """BridgeTimeoutError propagates to caller."""
+        mock_bridge = AsyncMock()
+        mock_bridge.request.side_effect = BridgeTimeoutError("Timed out")
+        with patch("godotiq.tools.bridge.check_errors.get_bridge", return_value=mock_bridge):
+            with pytest.raises(BridgeTimeoutError):
+                await check_errors()
+
+    async def test_propagates_bridge_error(self) -> None:
+        """BridgeError propagates to caller."""
+        mock_bridge = AsyncMock()
+        mock_bridge.request.side_effect = BridgeError("CHECK_IN_PROGRESS", "Already running")
+        with patch("godotiq.tools.bridge.check_errors.get_bridge", return_value=mock_bridge):
+            with pytest.raises(BridgeError):
+                await check_errors()
+
+
+class TestCheckErrorsMCPRegistration:
+    """MCP tool registration tests."""
+
+    def test_tool_registered(self) -> None:
+        """godotiq_check_errors tool is registered in server tool list."""
+        from godotiq.server import mcp
+        tools = asyncio.get_event_loop().run_until_complete(mcp.list_tools())
+        tool_names = [t.name for t in tools]
+        assert "godotiq_check_errors" in tool_names
+
+    async def test_catches_connection_error(self) -> None:
+        """MCP wrapper catches BridgeConnectionError and returns error+hint."""
+        from godotiq.tools.bridge import godotiq_check_errors
+        mock_bridge = AsyncMock()
+        mock_bridge.request.side_effect = BridgeConnectionError("Not connected")
+        with patch("godotiq.tools.bridge.check_errors.get_bridge", return_value=mock_bridge):
+            result = await godotiq_check_errors(scope="scene")
+
+        assert "error" in result
+        assert "hint" in result
+
+    async def test_catches_timeout_error(self) -> None:
+        """MCP wrapper catches BridgeTimeoutError and returns error+hint."""
+        from godotiq.tools.bridge import godotiq_check_errors
+        mock_bridge = AsyncMock()
+        mock_bridge.request.side_effect = BridgeTimeoutError("Timed out")
+        with patch("godotiq.tools.bridge.check_errors.get_bridge", return_value=mock_bridge):
+            result = await godotiq_check_errors(scope="scene")
+
+        assert "error" in result
+        assert "hint" in result
+        assert "timed out" in result["hint"].lower()
+
+    async def test_catches_bridge_error(self) -> None:
+        """MCP wrapper catches BridgeError and returns formatted error."""
+        from godotiq.tools.bridge import godotiq_check_errors
+        mock_bridge = AsyncMock()
+        mock_bridge.request.side_effect = BridgeError("CHECK_IN_PROGRESS", "Already running")
+        with patch("godotiq.tools.bridge.check_errors.get_bridge", return_value=mock_bridge):
+            result = await godotiq_check_errors(scope="scene")
+
+        assert "error" in result
+        assert "[CHECK_IN_PROGRESS]" in result["error"]
+
+
+class TestCheckErrorsTimeout:
+    """Timeout configuration tests."""
+
+    def test_timeout_configured(self) -> None:
+        """check_errors has 15s timeout in TOOL_TIMEOUTS."""
+        from godotiq.bridge.protocol import TOOL_TIMEOUTS
+        assert TOOL_TIMEOUTS["check_errors"] == 15.0
