@idosgames/mcp 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idosgames/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "MCP server that serves the iDosGames Module & Skills Registry to AI coding agents (Claude Code, Codex, Cursor…): list/pull composable game modules and the host scaffold, and load skills for @idosgames/core, the module contract, and composition.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/registry/host.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
13
|
"path": "package.json",
|
|
14
|
-
"content": "{\n \"name\": \"@idosgames/host-starter\",\n \"version\": \"0.0.0\",\n \"private\": true,\n \"type\": \"module\",\n \"description\": \"The seed project for the AI Coder: a host shell that composes feature modules. Fresh projects start here with zero modules; the developer/agent plugs modules into src/modules.ts.\",\n \"scripts\": {\n \"dev\": \"vite\",\n \"build\": \"vite build\",\n \"preview\": \"vite preview\",\n \"typecheck\": \"tsc --noEmit -p tsconfig.json\"\n },\n \"//\": \"Versions are pinned exactly: this is a seed for AI Coder projects, which build offline against a dependency allowlist baked at these versions (see scripts/pack-builder.mjs). Modules bring their own engine deps (three/phaser) when added.\",\n \"dependencies\": {\n \"@idosgames/app-shell\": \"0.1.16\",\n \"@idosgames/core\": \"0.10.
|
|
14
|
+
"content": "{\n \"name\": \"@idosgames/host-starter\",\n \"version\": \"0.0.0\",\n \"private\": true,\n \"type\": \"module\",\n \"description\": \"The seed project for the AI Coder: a host shell that composes feature modules. Fresh projects start here with zero modules; the developer/agent plugs modules into src/modules.ts.\",\n \"scripts\": {\n \"dev\": \"vite\",\n \"build\": \"vite build\",\n \"preview\": \"vite preview\",\n \"typecheck\": \"tsc --noEmit -p tsconfig.json\"\n },\n \"//\": \"Versions are pinned exactly: this is a seed for AI Coder projects, which build offline against a dependency allowlist baked at these versions (see scripts/pack-builder.mjs). Modules bring their own engine deps (three/phaser) when added.\",\n \"dependencies\": {\n \"@idosgames/app-shell\": \"0.1.16\",\n \"@idosgames/core\": \"0.10.1\",\n \"@idosgames/module-sdk\": \"0.1.11\",\n \"@idosgames/react\": \"0.2.3\",\n \"@idosgames/wallet\": \"0.2.3\",\n \"@tanstack/react-query\": \"5.101.2\",\n \"react\": \"19.2.7\",\n \"react-dom\": \"19.2.7\",\n \"wagmi\": \"3.7.2\"\n },\n \"devDependencies\": {\n \"@types/react\": \"19.2.17\",\n \"@types/react-dom\": \"19.2.3\",\n \"@vitejs/plugin-react\": \"6.0.4\",\n \"typescript\": \"5.9.3\",\n \"vite\": \"8.1.5\"\n }\n}\n"
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
"path": "src/config.ts",
|
package/registry/index.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedFromCommit": "
|
|
2
|
+
"generatedFromCommit": "fbf353854ab674684ce8d8dc71eb50f66f4fc858",
|
|
3
3
|
"runtimePackages": {
|
|
4
|
-
"@idosgames/core": "0.10.
|
|
4
|
+
"@idosgames/core": "0.10.1",
|
|
5
5
|
"@idosgames/wallet": "0.2.3",
|
|
6
6
|
"@idosgames/module-sdk": "0.1.11",
|
|
7
7
|
"@idosgames/react": "0.2.3",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
"version": "0.1.0",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@idosgames/core": "0.10.
|
|
49
|
+
"@idosgames/core": "0.10.1",
|
|
50
50
|
"@idosgames/module-sdk": "0.1.11",
|
|
51
51
|
"@idosgames/react": "0.2.3",
|
|
52
52
|
"@idosgames/wallet": "0.2.3",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
},
|
|
93
93
|
"version": "0.1.0",
|
|
94
94
|
"dependencies": {
|
|
95
|
-
"@idosgames/core": "0.10.
|
|
95
|
+
"@idosgames/core": "0.10.1",
|
|
96
96
|
"@idosgames/module-sdk": "0.1.11",
|
|
97
97
|
"@idosgames/react": "0.2.3",
|
|
98
98
|
"@idosgames/wallet": "0.2.3",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "acquisition-attribution",
|
|
3
3
|
"description": "Understand how a game built on the iDosGames TypeScript SDK (@idosgames/core) knows where a player came from, and how playtime reaches the publisher's analytics. Covers automatic capture of utm_* / ad click ids / ?ref= invite codes / idos_click tokens / Telegram start_param at launch, delivery with the login request, the deferred install match, the universal idosgames.com/go/{titleID} link, and the playtime tracker behind DAU/MAU and retention. Use this whenever the user asks about attribution, UTM tags, ad campaigns, install tracking, \"where did this player come from\", invite links, deep links carrying a referral code, session counting, playtime, DAU or MAU in the iDosGames SDK — and BEFORE writing any code that reads the URL or localStorage for campaign or referral parameters.",
|
|
4
|
-
"content": "---\nname: acquisition-attribution\ndescription: >-\n Understand how a game built on the iDosGames TypeScript SDK (@idosgames/core)\n knows where a player came from, and how playtime reaches the publisher's\n analytics. Covers automatic capture of utm_* / ad click ids / ?ref= invite\n codes / idos_click tokens / Telegram start_param at launch, delivery with\n the login request, the deferred install match, the universal\n idosgames.com/go/{titleID} link, and the playtime tracker behind DAU/MAU and\n retention. Use this whenever the user asks about attribution, UTM tags, ad\n campaigns, install tracking, \"where did this player come from\", invite\n links, deep links carrying a referral code, session counting, playtime, DAU\n or MAU in the iDosGames SDK — and BEFORE writing any code that reads the URL\n or localStorage for campaign or referral parameters.\n---\n\n# Acquisition and attribution (iDosGames TS SDK)\n\nTwo things run by themselves in every client created with\n`createIDosGamesClient`, and **the correct amount of code you write for either\nis zero**:\n\n1. **`AcquisitionCapture`** reads the launch URL (and Telegram launch\n parameters) the moment the client is created, keeps what it found, and\n attaches it to whichever sign-in the player eventually uses.\n2. **`PlaytimeTracker`** counts how long the player actually plays and reports\n it, starting at login.\n\nThis skill exists mostly so you do **not** re-implement either one. If you find\nyourself writing `new URLSearchParams(location.search).get(\"utm_source\")` or a\n`setInterval` that posts playtime, stop: the SDK already did it, and a second\nimplementation competes with the first.\n\n## Why it matters\n\nEvery acquisition number a publisher sees — which campaign brought which\nplayer, retention split by source, invite conversion, K-factor — is derived\nfrom a signal the client sends **once**, with the login. And every engagement\nnumber — DAU, WAU, MAU, stickiness, average session, the retention cohorts on\ntop of them — is derived from what the playtime tracker posts. Neither has a\nfallback: nothing else on the platform writes those records.\n\n## What gets captured\n\nAt client construction, from the launch URL and the platform adapter:\n\n| Source | Lands in |\n| ---------------------------------------------------- | ----------------------------------------------------------- |\n| `utm_source/medium/campaign/term/content` | the matching `Utm*` fields |\n| `gclid`, `fbclid`, `ttclid`, `msclkid`, `yclid` | `ClickID` (whichever appears; ad networks never mix theirs) |\n| `?ref=` / `?r=` (bare code, or with a `ref_` prefix) | `ReferralCode`, `ChannelHint: \"query\"` |\n| `idos_click` | `ClaimToken` — an exact click receipt we issued |\n| Telegram `start_param` | `ReferralCode`, `ChannelHint: \"telegram\"` |\n| `document.referrer` | `Referrer` |\n\nPlus, on **every** login regardless of tags: `OsVersion`, and `AppVersion` if\nyou set one.\n\n`AppVersion` is the only piece the SDK cannot find on its own — the web has no\n`Application.version` — so pass it when you create the client:\n\n```ts\nconst client = createIDosGamesClient({\n titleID: \"MYTITLE\",\n appVersion: \"1.4.2\",\n});\n```\n\nLeave it out and the player is attributed without a build number, which makes\n\"did the 1.5 release change retention?\" unanswerable for that title.\n\n⚠ **Those device facts are not decoration and must not be stripped as\n\"empty signal\".** They are how the server matches an install back to a click\nthat happened in a browser before the app existed (see Deferred match). The\nserver deliberately does not treat them as a signal on their own — that is what\nlets the match run at all.\n\nThe captured signal is **persisted with a 30-day TTL**, because the login often\nhappens much later than the launch: after a redirect to a sign-in screen, after\nan e-mail confirmation, after a reload. Holding it in memory would lose it for\nexactly the players who arrived through a campaign or an invite. It is cleared\nafter a successful login — the next sign-in by the same person must not be\nre-attributed to a month-old campaign.\n\n## The methods you may actually call\n\n```ts\nimport { AcquisitionCapture } from \"@idosgames/core\";\n```\n\n| Call | When you need it |\n| --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| `AcquisitionCapture.parseReferralCode(input)` | A player pasted something into an \"enter a code\" box. Accepts a bare code, a code with separators, or the whole invite link. |\n| `AcquisitionCapture.detectDevicePlatform(ua)` | Only if you are building a landing page that registers clicks. See the warning below. |\n\nEverything else on the instance (`capture()`, `buildForLogin()`, `clear()`) is\ndriven by the client. Calling them yourself does not add data; `clear()` in\nparticular throws away a signal that has not been delivered.\n\n`client.referral.activateReferralCode` already runs `parseReferralCode` on its\ninput, so for the ordinary \"enter a friend's code\" field you do not even need\nthat — pass the raw text straight through.\n\n## Playtime\n\n`PlaytimeTracker` starts on `auth:loggedIn` and stops on `auth:loggedOut`.\nNothing to wire.\n\n- Flushes every **200 s**; a gap of **300 s** with the tab hidden ends the\n session. Both numbers are copied from the Unity SDK on purpose: different\n constants would make the same behaviour produce different session counts per\n platform, and a publisher comparing web against mobile would be comparing two\n different definitions of \"a session\".\n- Time with the tab in the background is **not** counted.\n- The buffer survives a reload, and a failed flush is put back rather than\n dropped — under-reported playtime is invisible downstream, so it is never\n discarded silently.\n\n## Deferred match — how a store install finds its click\n\nThere is no way to carry a parameter through an app store. So:\n\n1. The universal link `idosgames.com/go/{titleID}?ref=CODE` registers the click\n with the backend and gets a `ClaimToken`.\n2. Where we control the destination (the web build), the token travels in the\n URL and the match is **exact**.\n3. Where we do not (Google Play, App Store), the server matches the first\n launch to the click by a **fingerprint**: network, platform family, major OS\n version, country, plus a daily salt.\n\n⚠ **A fingerprint match is a guess and is reported as one.** Behind a mobile\ncarrier's NAT hundreds of people share it. Such touches are marked\n`Trust: \"Inferred\"` and shown on their own row in the publisher's report — do\nnot build UI that presents them as certain.\n\n⚠ **If you build a page that registers clicks, report the platform of the\nDEVICE (`\"Android\"` / `\"iOS\"`), never `\"Web\"`.** The fingerprint is compared\nbetween two different programs — your page in a browser and the installed game\n— and the game reports its own platform. Send `\"Web\"` from a phone and the keys\nnever line up, which turns the whole deferred match into dead code in exactly\nits main case. `AcquisitionCapture.detectDevicePlatform(navigator.userAgent)`\nreturns the right string.\n\n## Gotchas\n\n- **Do not read the URL yourself for campaign or referral parameters.** The SDK\n captured them at construction and the launch URL is frequently gone by the\n time your screen mounts. Read `client.data.user.state?.Referral` for the\n outcome instead.\n- **Do not build invite links from a template.** The server returns a\n ready-made one (`UserReferralStateResponse.InviteUrl`); a client-assembled\n link is an open redirect, and every title would word it differently. See the\n `referral-system` skill.\n- **The link always carries the title** (`/go/{titleID}?ref=...`) because a\n referral code is unique only inside a title. A link shaped like `/i/{code}`\n cannot exist.\n- **`/go/{titleID}` is deliberately not `/play/...`** — the platform publishes\n applications as well as games.\n- **A game embedded in an iframe does not inherit the page's query string.**\n If you host a build inside your own page, forward `ref` and `idos_click` into\n the iframe `src` yourself, or arrivals through an invite will look like\n ordinary launches — silently.\n- **Telegram `start_param` is the one channel the server actually trusts** (it\n arrives inside data signed by the publisher's bot). The server reads its own\n copy; a code you place in the request body is ignored on a Telegram sign-in,\n so do not try to override it.\n- **Nothing here works before login.** The signal rides on the sign-in request;\n a title that never signs a player in reports nothing, and its DAU stays zero.\n",
|
|
4
|
+
"content": "---\nname: acquisition-attribution\ndescription: >-\n Understand how a game built on the iDosGames TypeScript SDK (@idosgames/core)\n knows where a player came from, and how playtime reaches the publisher's\n analytics. Covers automatic capture of utm_* / ad click ids / ?ref= invite\n codes / idos_click tokens / Telegram start_param at launch, delivery with\n the login request, the deferred install match, the universal\n idosgames.com/go/{titleID} link, and the playtime tracker behind DAU/MAU and\n retention. Use this whenever the user asks about attribution, UTM tags, ad\n campaigns, install tracking, \"where did this player come from\", invite\n links, deep links carrying a referral code, session counting, playtime, DAU\n or MAU in the iDosGames SDK — and BEFORE writing any code that reads the URL\n or localStorage for campaign or referral parameters.\n---\n\n# Acquisition and attribution (iDosGames TS SDK)\n\nTwo things run by themselves in every client created with\n`createIDosGamesClient`, and **the correct amount of code you write for either\nis zero**:\n\n1. **`AcquisitionCapture`** reads the launch URL (and Telegram launch\n parameters) the moment the client is created, keeps what it found, and\n attaches it to whichever sign-in the player eventually uses.\n2. **`PlaytimeTracker`** counts how long the player actually plays and reports\n it, starting at login.\n\nThis skill exists mostly so you do **not** re-implement either one. If you find\nyourself writing `new URLSearchParams(location.search).get(\"utm_source\")` or a\n`setInterval` that posts playtime, stop: the SDK already did it, and a second\nimplementation competes with the first.\n\n## Why it matters\n\nEvery acquisition number a publisher sees — which campaign brought which\nplayer, retention split by source, invite conversion, K-factor — is derived\nfrom a signal the client sends **once**, with the login. And every engagement\nnumber — DAU, WAU, MAU, stickiness, average session, the retention cohorts on\ntop of them — is derived from what the playtime tracker posts. Neither has a\nfallback: nothing else on the platform writes those records.\n\n## What gets captured\n\nAt client construction, from the launch URL and the platform adapter:\n\n| Source | Lands in |\n| ---------------------------------------------------- | ----------------------------------------------------------- |\n| `utm_source/medium/campaign/term/content` | the matching `Utm*` fields |\n| `gclid`, `fbclid`, `ttclid`, `msclkid`, `yclid` | `ClickID` (whichever appears; ad networks never mix theirs) |\n| `?ref=` / `?r=` (bare code, or with a `ref_` prefix) | `ReferralCode`, `ChannelHint: \"query\"` |\n| `idos_click` | `ClaimToken` — an exact click receipt we issued |\n| Telegram `start_param` | `ReferralCode`, `ChannelHint: \"telegram\"` |\n| Telegram `start_param` beginning `a1_` | a whole packed mark set — see below |\n| `document.referrer` | `Referrer` |\n\nPlus, on **every** login regardless of tags: `OsVersion`, and `AppVersion` if\nyou set one.\n\n`AppVersion` is the only piece the SDK cannot find on its own — the web has no\n`Application.version` — so pass it when you create the client:\n\n```ts\nconst client = createIDosGamesClient({\n titleID: \"MYTITLE\",\n appVersion: \"1.4.2\",\n});\n```\n\nLeave it out and the player is attributed without a build number, which makes\n\"did the 1.5 release change retention?\" unanswerable for that title.\n\n⚠ **Those device facts are not decoration and must not be stripped as\n\"empty signal\".** They are how the server matches an install back to a click\nthat happened in a browser before the app existed (see Deferred match). The\nserver deliberately does not treat them as a signal on their own — that is what\nlets the match run at all.\n\nThe captured signal is **persisted with a 30-day TTL**, because the login often\nhappens much later than the launch: after a redirect to a sign-in screen, after\nan e-mail confirmation, after a reload. Holding it in memory would lose it for\nexactly the players who arrived through a campaign or an invite. It is cleared\nafter a successful login — the next sign-in by the same person must not be\nre-attributed to a month-old campaign.\n\n## The methods you may actually call\n\n```ts\nimport { AcquisitionCapture } from \"@idosgames/core\";\n```\n\n| Call | When you need it |\n| --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| `AcquisitionCapture.parseReferralCode(input)` | A player pasted something into an \"enter a code\" box. Accepts a bare code, a code with separators, or the whole invite link. |\n| `AcquisitionCapture.detectDevicePlatform(ua)` | Only if you are building a landing page that registers clicks. See the warning below. |\n\nEverything else on the instance (`capture()`, `buildForLogin()`, `clear()`) is\ndriven by the client. Calling them yourself does not add data; `clear()` in\nparticular throws away a signal that has not been delivered.\n\n`client.referral.activateReferralCode` already runs `parseReferralCode` on its\ninput, so for the ordinary \"enter a friend's code\" field you do not even need\nthat — pass the raw text straight through.\n\n## Playtime\n\n`PlaytimeTracker` starts on `auth:loggedIn` and stops on `auth:loggedOut`.\nNothing to wire.\n\n- Flushes every **200 s**; a gap of **300 s** with the tab hidden ends the\n session. Both numbers are copied from the Unity SDK on purpose: different\n constants would make the same behaviour produce different session counts per\n platform, and a publisher comparing web against mobile would be comparing two\n different definitions of \"a session\".\n- Time with the tab in the background is **not** counted.\n- The buffer survives a reload, and a failed flush is put back rather than\n dropped — under-reported playtime is invisible downstream, so it is never\n discarded silently.\n\n## Deferred match — how a store install finds its click\n\nThere is no way to carry a parameter through an app store. So:\n\n1. The universal link `idosgames.com/go/{titleID}?ref=CODE` registers the click\n with the backend and gets a `ClaimToken`.\n2. Where we control the destination (the web build), the token travels in the\n URL and the match is **exact**.\n3. Where we do not (Google Play, App Store), the server matches the first\n launch to the click by a **fingerprint**: network, platform family, major OS\n version, country, plus a daily salt.\n\n⚠ **A fingerprint match is a guess and is reported as one.** Behind a mobile\ncarrier's NAT hundreds of people share it. Such touches are marked\n`Trust: \"Inferred\"` and shown on their own row in the publisher's report — do\nnot build UI that presents them as certain.\n\n⚠ **If you build a page that registers clicks, report the platform of the\nDEVICE (`\"Android\"` / `\"iOS\"`), never `\"Web\"`.** The fingerprint is compared\nbetween two different programs — your page in a browser and the installed game\n— and the game reports its own platform. Send `\"Web\"` from a phone and the keys\nnever line up, which turns the whole deferred match into dead code in exactly\nits main case. `AcquisitionCapture.detectDevicePlatform(navigator.userAgent)`\nreturns the right string.\n\n## Gotchas\n\n- **Do not read the URL yourself for campaign or referral parameters.** The SDK\n captured them at construction and the launch URL is frequently gone by the\n time your screen mounts. Read `client.data.user.state?.Referral` for the\n outcome instead.\n- **Do not build invite links from a template.** The server returns a\n ready-made one (`UserReferralStateResponse.InviteUrl`); a client-assembled\n link is an open redirect, and every title would word it differently. See the\n `referral-system` skill.\n- **The link always carries the title** (`/go/{titleID}?ref=...`) because a\n referral code is unique only inside a title. A link shaped like `/i/{code}`\n cannot exist.\n- **`/go/{titleID}` is deliberately not `/play/...`** — the platform publishes\n applications as well as games.\n- **A game embedded in an iframe does not inherit the page's query string.**\n If you host a build inside your own page, forward `ref` and `idos_click` into\n the iframe `src` yourself, or arrivals through an invite will look like\n ordinary launches — silently.\n- **Telegram `start_param` is the one channel the server actually trusts** (it\n arrives inside data signed by the publisher's bot). The server reads its own\n copy; a code you place in the request body is ignored on a Telegram sign-in,\n so do not try to override it.\n- **A `start_param` may carry a whole mark set, not just a code.** Telegram's\n `startapp` accepts only `A-Z a-z 0-9 _ -`, so `key=value&...` cannot travel\n there; the invite page base64url-encodes it behind an `a1_` prefix and the\n SDK unpacks it for you. Two things follow. Never show a raw `start_param` to\n the player as their invite code — decode it first, or a blob appears on\n screen. And if you generate Telegram links yourself, either use the same\n format or send a bare code; an invented one is read as a code verbatim.\n The prefix is versioned on purpose: a future `a2_` will ship alongside `a1_`,\n never in place of it, so links already sent out keep working.\n- **Android carries its marks through Google Play, not through us.** The invite\n page appends `&referrer=` to the store link; Play hands that string to the\n app on first launch. Build your own store links the same way, or installs\n from them fall back to a fingerprint guess that breaks whenever the player\n switches network between tapping and launching.\n- **Nothing here works before login.** The signal rides on the sign-in request;\n a title that never signs a player in reports nothing, and its DAU stays zero.\n",
|
|
5
5
|
"references": []
|
|
6
6
|
}
|