{"id":50103164,"url":"https://github.com/rumi-chan/league-client-mcp","last_synced_at":"2026-06-09T00:00:43.095Z","repository":{"id":340398360,"uuid":"1163934350","full_name":"rumi-chan/league-client-mcp","owner":"rumi-chan","description":"Connect Claude, Antigravity to League Client via MCP \u0026 Pengu Loader.","archived":false,"fork":false,"pushed_at":"2026-03-09T13:12:37.000Z","size":2932,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-09T17:58:49.058Z","etag":null,"topics":["league-of-legends","mcp","pengu-loader"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rumi-chan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-22T11:38:54.000Z","updated_at":"2026-03-09T13:15:03.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rumi-chan/league-client-mcp","commit_stats":null,"previous_names":["rumi-chan/league-client-mcp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rumi-chan/league-client-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumi-chan%2Fleague-client-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumi-chan%2Fleague-client-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumi-chan%2Fleague-client-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumi-chan%2Fleague-client-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rumi-chan","download_url":"https://codeload.github.com/rumi-chan/league-client-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumi-chan%2Fleague-client-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34085321,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["league-of-legends","mcp","pengu-loader"],"created_at":"2026-05-23T09:00:21.572Z","updated_at":"2026-06-09T00:00:43.090Z","avatar_url":"https://github.com/rumi-chan.png","language":"TypeScript","funding_links":[],"categories":["Developer Tools"],"sub_categories":[],"readme":"# league-client-mcp\n\n`league-client-mcp` gives an MCP client live access to the League of Legends desktop client.\nIt is two pieces working together:\n\n- `mcp-server/`: a Node.js MCP server that exposes tools over stdio\n- `lol-plugin/`: a Pengu Loader plugin that runs inside the League client and executes those tool calls\n\nWith both running, an AI assistant can inspect the DOM, inject CSS or JavaScript, call the\nLCU API, interact with the UI, and export finished plugins back to Pengu Loader.\n\n\u003cvideo src=\"https://github.com/user-attachments/assets/b05a1aeb-8241-4933-bba9-fe31419fdb91\" autoplay loop muted playsinline\u003e\u003c/video\u003e\n\n## How it works\n\n```text\nAI client\n  -\u003e MCP over stdio\n  -\u003e mcp-server/\n  -\u003e WebSocket bridge at ws://127.0.0.1:8080\n  -\u003e lol-plugin/ inside the League client\n  -\u003e DOM, CSS, JavaScript, and LCU fetch()\n```\n\nIf League or Pengu Loader is not running, the server has nothing to talk to and the tools will\nfail. This repo assumes a live client.\n\n## What you can do with it\n\n- Snapshot the current League page and inspect selectors before changing anything\n- Inject CSS to prototype layout or visual changes\n- Run one-off JavaScript in the client\n- Inject persistent plugins that survive SPA navigation\n- Click buttons, type into inputs, and wait for pages to load\n- Call the LCU API from inside the client without handling auth yourself\n- Export an injected plugin to Pengu Loader so it loads on startup\n\n## Prerequisites\n\n- Node.js 18 or newer\n- `pnpm` for the Pengu Loader plugin\n- [Pengu Loader](https://github.com/PenguLoader/PenguLoader) installed\n- League of Legends running when you want to use the MCP tools\n\n## Installation\n\n### 1. Clone the repo\n\n```bash\ngit clone https://github.com/rumi-chan/league-client-mcp.git\ncd league-client-mcp\n```\n\n### 2. Build the MCP server\n\n```bash\ncd mcp-server\nnpm install\nnpm run build\n```\n\n### 3. Build the Pengu Loader plugin\n\nSet the Pengu Loader path in `lol-plugin/package.json`:\n\n```json\n\"config\": {\n  \"penguPath\": \"C:\\\\path\\\\to\\\\your\\\\pengu-loader\"\n}\n```\n\nThen build the plugin:\n\n```bash\ncd lol-plugin\npnpm install\npnpm build\n```\n\nIf you are not using watch mode, copy `lol-plugin/dist/index.js` into a plugin folder inside\nPengu Loader's `plugins` directory.\n\n### 4. Register the MCP server in your client\n\nAny MCP client that can launch a local stdio server should work. The command looks like this:\n\n```json\n{\n  \"mcpServers\": {\n    \"league-client-mcp\": {\n      \"command\": \"node\",\n      \"args\": [\"C:/path/to/league-client-mcp/mcp-server/dist/server.js\"]\n    }\n  }\n}\n```\n\nThis is the same basic shape used by Claude Desktop, Cursor, Windsurf, Codex CLI, and other\nlocal MCP clients.\n\n## Normal workflow\n\n1. Start League of Legends with Pengu Loader active.\n2. Start the MCP server with `npm start` from `mcp-server/`.\n3. Connect from your AI client.\n4. Map the current page with `get_lol_dom_snapshot`.\n5. Prototype styling with `inject_lol_css`.\n6. Add behavior with `inject_lol_plugin`.\n7. Reload the injected plugin while iterating.\n8. Export the finished plugin to Pengu Loader.\n9. Reload the League client to make the exported plugin load on startup.\n\nThe shortest useful loop usually looks like this:\n\n```text\nget_lol_dom_snapshot\ninject_lol_css\nquery_lol_element\ninject_lol_plugin\nreload_lol_plugin\nexport_plugin_to_pengu\nreload_lol_client\n```\n\n## Tool list\n\nThere are 16 MCP tools in the server.\n\n### DOM inspection\n\n- `get_lol_dom_snapshot`: returns a sanitized HTML snapshot of the current page\n- `query_lol_element`: returns details for one element, including text, bounds, and styles\n- `wait_for_lol_element`: waits until a selector appears in the DOM\n\n### CSS and JavaScript\n\n- `inject_lol_css`: replaces the shared global style tag\n- `execute_lol_javascript`: runs one-off async JavaScript in the client\n\n### Plugin management\n\n- `inject_lol_plugin`: injects a named persistent plugin with optional scoped CSS\n- `reload_lol_plugin`: tears down and re-runs one injected plugin\n- `remove_lol_plugin`: removes an injected plugin and calls its cleanup function\n- `export_plugin_to_pengu`: writes an injected plugin to Pengu Loader's plugins folder\n\n### Client and UI interaction\n\n- `click_lol_element`: clicks an element by selector\n- `type_into_lol_element`: types into an input or textarea and dispatches native events\n- `get_lol_client_state`: returns URL, title, viewport, and injected plugin names\n- `get_lol_performance_metrics`: reports heap, DOM, stylesheet, and paint data\n- `get_lol_screenshot`: saves a screenshot of the League client window on Windows\n- `reload_lol_client`: reloads the whole client\n\n### LCU\n\n- `lcu_request`: sends an HTTP request to the League Client Update API from inside the client\n\nFor the longer endpoint catalog and agent-specific workflow notes, see\n[`AGENTS.md`](AGENTS.md).\n\n## Writing a plugin\n\nPersistent plugins must return a cleanup function. If they do not, reload and removal will break.\n\n```js\nconst el = Object.assign(document.createElement(\"div\"), { id: \"my-plugin\" });\ndocument.body.appendChild(el);\n\nasync function render() {\n  const summoner = await fetch(\"/lol-summoner/v1/current-summoner\").then((r) =\u003e r.json());\n  el.textContent = `${summoner.displayName} Lv.${summoner.summonerLevel}`;\n}\n\nconst interval = setInterval(render, 5000);\nconst observer = new MutationObserver(() =\u003e {\n  clearTimeout(window.__myPluginTimer);\n  window.__myPluginTimer = setTimeout(render, 350);\n});\n\nobserver.observe(document.body, { childList: true, subtree: false });\nrender();\n\nreturn () =\u003e {\n  clearInterval(interval);\n  observer.disconnect();\n  clearTimeout(window.__myPluginTimer);\n  document.getElementById(\"my-plugin\")?.remove();\n};\n```\n\nSome practical rules:\n\n- Use `get_lol_dom_snapshot` before guessing selectors\n- Use `!important` when injecting CSS into the League client\n- Debounce DOM-driven rerenders because the client is a SPA and updates asynchronously\n- Prefer `inject_lol_plugin` over raw CSS when you need state, timers, or LCU fetches\n\n## Development mode\n\nFor the plugin:\n\n```bash\ncd lol-plugin\npnpm dev\n```\n\nWatch mode rebuilds on save, copies the output into the configured Pengu Loader plugin\ndirectory, and notifies the client over a local WebSocket on port `3000`.\n\nFor the MCP server:\n\n```bash\ncd mcp-server\nnpm run dev\n```\n\nThat runs the server with `tsx` and skips the build step while you are iterating.\n\n## Repo layout\n\n```text\nleague-client-mcp/\n|-- mcp-server/\n|   `-- src/server.ts\n|-- lol-plugin/\n|   `-- src/index.ts\n|-- AGENTS.md\n|-- CLAUDE.md\n|-- GEMINI.md\n|-- .cursor/rules/\n|-- .windsurf/rules/\n`-- .github/copilot-instructions.md\n```\n\n`AGENTS.md` is the main instruction file for this repo. The other agent-specific files point back\nto it or adapt it for their own client.\n\n## Notes\n\n- `inject_lol_css` replaces the previous injected stylesheet. It is not additive.\n- `export_plugin_to_pengu` exports a plugin that is already injected. It does not build one from disk.\n- `get_lol_screenshot` is Windows-only.\n- `wait_for_lol_element` is the safer way to handle page changes after a click.\n\n## Contributing\n\nPull requests are welcome. If you are planning a larger change, open an issue first so the scope\nis clear before the work starts.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frumi-chan%2Fleague-client-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frumi-chan%2Fleague-client-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frumi-chan%2Fleague-client-mcp/lists"}