CoplayDev/unity-mcp · critical · ConnectionError

MCP for Unity requires FRAMING=1, got: {text!r}

Error message

MCP for Unity requires FRAMING=1, got: {text!r}

What it means

Raised during the stdio TCP handshake (unity_connection.py:103). After connecting, the server reads the first line and expects it to contain the literal 'FRAMING=1'. When config.require_framing is True (the default) and the line lacks it, the server sends a best-effort advisory to the peer and refuses the connection, embedding whatever text was actually received as {text!r}.

Source

Thrown at Server/src/transport/legacy/unity_connection.py:103

                                break
                            buf.extend(chunk)
                            if b"\n" in buf:
                                break
                        except socket.timeout:
                            break
                    text = bytes(buf).decode('ascii', errors='ignore').strip()

                    if 'FRAMING=1' in text:
                        self.use_framing = True
                        logger.debug(
                            'MCP for Unity handshake received: FRAMING=1 (strict)')
                    else:
                        if require_framing:
                            # Best-effort plain-text advisory for legacy peers
                            with contextlib.suppress(Exception):
                                self.sock.sendall(
                                    b'MCP for Unity requires FRAMING=1\n')
                            raise ConnectionError(
                                f'MCP for Unity requires FRAMING=1, got: {text!r}')
                        else:
                            self.use_framing = False
                            logger.warning(
                                'MCP for Unity handshake missing FRAMING=1; proceeding in legacy mode by configuration')
                finally:
                    self.sock.settimeout(config.connection_timeout)
                return True
            except Exception as e:
                logger.error(f"Failed to connect to Unity: {str(e)}")
                try:
                    if self.sock:
                        self.sock.close()
                except Exception:
                    pass
                self.sock = None
                return False

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Update the MCPForUnity Unity package to a version that matches the Python server so it emits FRAMING=1.
  2. Confirm the resolved port actually belongs to the MCPForUnity bridge (check ~/.unity-mcp status files / port registry), not another process.
  3. Wait for Unity to finish booting before issuing commands.
  4. As a temporary interop escape hatch, set config.require_framing=False to allow legacy (unframed) mode — the server then logs a warning and proceeds.

Example fix

// before — strict (default)
# config.require_framing == True  -> raises on legacy peers

// after — opt into legacy interop explicitly
from core.config import config
config.require_framing = False
Defensive patterns

Strategy: validation

Validate before calling

from core.config import config

def framing_interop_ok() -> bool:
    # True only if the peer is known to emit FRAMING=1 (matched versions)
    return config.require_framing or config.require_framing is False  # see note

Type guard

def is_framing_handshake_error(e: BaseException) -> bool:
    return (isinstance(e, ConnectionError)
            and 'requires FRAMING=1' in str(e))

Try / catch

try:
    conn.connect()
except ConnectionError as e:
    if 'requires FRAMING=1' in str(e):
        # version mismatch — either upgrade the Unity package or allow legacy mode
        from core.config import config
        config.require_framing = False
        conn.sock = None
        conn.connect()
    else:
        raise

Prevention

When it happens

Trigger: send_command -> connect() where the peer on the discovered port is either an older Unity editor that does not speak the framing protocol, a different service entirely, or a Unity bridge still mid-boot that wrote something other than the FRAMING=1 banner.

Common situations: Version skew between the Python server and the MCPForUnity Unity package (server newer/stricter than the editor), a stale port pointed at another listener, or Unity not fully initialized when the first command fires.

Related errors


AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13). Data as JSON: /api/errors/192ebf52cf1e054d. Report an issue: GitHub.