Skip to content

feat: direct PeerJS agent — no relay tab needed - #36

Merged
reifocS merged 12 commits into
mainfrom
feat/agent-p2p
Apr 13, 2026
Merged

feat: direct PeerJS agent — no relay tab needed#36
reifocS merged 12 commits into
mainfrom
feat/agent-p2p

Conversation

@reifocS

@reifocS reifocS commented Mar 29, 2026

Copy link
Copy Markdown
Owner

Summary

The MCP agent joins the game as a real PeerJS peer — no relay browser tab, no WebSocket server, no bridge code.

Architecture

graph LR
    CC["Claude Code<br/>(LLM)"] -- "stdio / MCP" --> MCP["MCP Server<br/>(Node.js)"]
    MCP -- "PeerJS / WebRTC" --> You["Your Browser"]
    MCP -- "PeerJS / WebRTC" --> Opp["Opponent"]

    style MCP fill:#bbf,stroke:#333,stroke-width:2px
Loading

The agent uses node-datachannel to polyfill WebRTC in Node.js, then connects via @vescofire/peersync's PeerJS transport — the same sync engine the browsers use. Shapes, action logs, and card state all flow through the existing sync channels.

How to use

  1. Agent starts and gets a PeerJS peer ID
  2. In Maginet, share your peer ID with Claude: "Connect to peer abc-123"
  3. Claude calls connectToPeer tool → agent joins as a peer
  4. Play normally — the agent's cards sync automatically

What changed vs PR #35 (relay approach)

Relay (#35) P2P (this PR)
Browser changes agentRelay.ts, relay button UI None
Agent connectivity WebSocket server + browser relay Direct PeerJS peer
Relay tab needed? Yes No
Agent visible to all players? Only through relay Directly
Code added to browser ~200 lines 0 lines

Supersedes

Test plan

  • 28 agent tests passing
  • 21 browser tests passing
  • Lint clean
  • Both packages build
  • Manual: start MCP server, connect to browser peer ID, verify shapes sync bidirectionally

reifocS added 10 commits March 29, 2026 15:00
…et-agent

Includes: agent package (state, mcp, scryfall, server, index),
design specs, plans, eslint/vite config, ActionLog cardSrcs,
useCardReducer lastPlayedSrcs.
Replace dual sync client approach with a relay pattern:
- Add agentRelay.ts — bridges WS (agent) ↔ PeerJS (players)
- Relay browser applies agent shapes as local shapes (relay's peer ID)
- Relay forwards all PeerJS players' shapes to agent via WS
- Agent uses simple sync:agent-shapes / sync:remote-shapes messages
- No separate WebSocket transport or agentSyncClient needed
- Add Relay button to SelectionPanel and SetupScreen

The relay browser doesn't play — it bridges. Open a second tab
to play against the agent, or let a remote human connect via PeerJS.
Replace WebSocket server with direct PeerJS peer connectivity.
node-datachannel provides WebRTC polyfill for Node.js.
Verified: polyfill loads, PeerJS creates peer and gets ID.
- Add peer.ts: sets up WebRTC polyfill, creates PeerJS transport and sync client, registers shapes channel
- Add shapesChannel.ts: transport-agnostic shapes sync channel mirroring browser's shapesChannel but without React/Zustand dependencies
- Update mcp.ts: replace AgentWebSocketServer import with inline AgentServer interface
- Delete server.ts and its integration test (replaced by PeerJS peer connectivity)
…server

- Replace AgentWebSocketServer with createAgentPeer (PeerJS/WebRTC)
- Polyfill import is first line, before any PeerJS imports
- Replace --port CLI arg with --peer (optional browser peer ID to auto-connect)
- Agent shapes sync via shapesChannel; remote shapes arrive via onRemoteShapes
- action-log / card-state-sync messages subscribed via agentPeer.onMessage()
- Add connectToPeer MCP tool to connect to a browser by peer ID
- Remove debugMessages tool and all WebSocket-related code
- Rewrite e2e test to use mockServer (no transport dependency)
- Fix mcp.test.ts to import AgentServer from mcp.js instead of server.js
- Add @types/node devDependency to fix process.argv TypeScript errors
@vercel

vercel Bot commented Mar 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
excalightdraw Ready Ready Preview, Comment Mar 29, 2026 5:38pm

- Dynamic import of peerjs and @vescofire/peersync/peerjs to ensure
  WebRTC polyfill globals are set before PeerJS checks for them
- Custom createPeer function handles CJS default export interop
- MCP config uses cwd: "maginet-agent" for correct module resolution
@reifocS
reifocS merged commit fe71b5c into main Apr 13, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant