psn-mcp 0.1.0 → 0.2.0

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Timothy Peterson
3
+ Copyright (c) 2026 TMRP
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,37 +1,58 @@
1
1
  # psn-mcp
2
2
 
3
- An [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server for interfacing with the PlayStation Network. Lets MCP clients like Claude look up PSN profiles, friends, online presence, trophies, and play history.
3
+ An [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server for
4
+ interfacing with the PlayStation Network. Lets MCP clients like Claude look up
5
+ PSN profiles, friends, online presence, trophies, and play history.
4
6
 
5
- The PSN API layer is written from scratch in TypeScript on Node's built-in `fetch` — no PSN client dependencies. It authenticates the same way the official PlayStation mobile app does and talks directly to Sony's `m.np.playstation.com` API.
7
+ The PSN API layer is written from scratch in TypeScript on Node's built-in
8
+ `fetch` — no PSN client dependencies. It authenticates the same way the official
9
+ PlayStation mobile app does and talks directly to Sony's `m.np.playstation.com`
10
+ API.
6
11
 
7
12
  ## Requirements
8
13
 
9
- - Node.js 18+
10
- - A PlayStation Network account and its **NPSSO token** (see below)
14
+ - Node.js 24.18+
15
+ - A PlayStation Network account
11
16
 
12
- ## Getting your NPSSO token
17
+ ## Signing in
18
+
19
+ The MCP server can automate NPSSO capture through an isolated browser profile:
20
+
21
+ 1. Start the MCP server without `PSN_NPSSO`.
22
+ 2. Call the `psn_begin_login` tool.
23
+ 3. Sign in to PlayStation in the browser window it opens.
24
+ 4. Call the `psn_complete_login` tool.
25
+
26
+ `psn_complete_login` reads the PlayStation `npsso` browser cookie, verifies it,
27
+ and stores it in `~/.config/psn-mcp/credentials.json` with owner-only file
28
+ permissions. Future server starts use the stored token automatically. Set
29
+ `PSN_NPSSO_FILE` to choose a different credential file.
30
+
31
+ If browser automation is unavailable, you can still configure an NPSSO manually:
13
32
 
14
33
  1. Sign in at [playstation.com](https://www.playstation.com).
15
34
  2. In the same browser, open <https://ca.account.sony.com/api/v1/ssocookie>.
16
- 3. Copy the 64-character `npsso` value from the JSON response.
35
+ 3. Copy the 64-character `npsso` value from the JSON response into `PSN_NPSSO`.
17
36
 
18
- The server exchanges the NPSSO for an OAuth access token on first use and refreshes it automatically. NPSSO tokens expire after about two months; when tools start failing with an auth error, fetch a fresh one.
37
+ The server exchanges the NPSSO for an OAuth access token on first use and
38
+ refreshes it automatically. NPSSO tokens expire after about two months; when
39
+ tools start failing with an auth error, run the login flow again.
19
40
 
20
- > **Note:** this uses your personal account session. What you can see (other users' friends, presence, play history) is governed by normal PSN privacy settings.
41
+ > **Note:** this uses your personal account session. What you can see (other
42
+ > users' friends, presence, play history) is governed by normal PSN privacy
43
+ > settings.
21
44
 
22
45
  ## Usage with an MCP client
23
46
 
24
- No installation needed — run it with `npx`. Add to your client's MCP configuration (e.g. `claude_desktop_config.json`):
47
+ No installation needed — run it with `npx`. Add to your client's MCP
48
+ configuration (e.g. `claude_desktop_config.json`):
25
49
 
26
50
  ```json
27
51
  {
28
52
  "mcpServers": {
29
53
  "psn": {
30
54
  "command": "npx",
31
- "args": ["-y", "psn-mcp"],
32
- "env": {
33
- "PSN_NPSSO": "<your npsso token>"
34
- }
55
+ "args": ["-y", "psn-mcp"]
35
56
  }
36
57
  }
37
58
  }
@@ -40,26 +61,42 @@ No installation needed — run it with `npx`. Add to your client's MCP configura
40
61
  Or for Claude Code:
41
62
 
42
63
  ```sh
43
- claude mcp add psn --env PSN_NPSSO=<your npsso token> -- npx -y psn-mcp
64
+ claude mcp add psn -- npx -y psn-mcp
44
65
  ```
45
66
 
46
67
  ## Tools
47
68
 
48
- | Tool | Description |
49
- | --- | --- |
50
- | `psn_get_profile` | Profile for a user: online id, about-me, avatars, PS Plus status |
51
- | `psn_search_players` | Search PSN players by name; returns online ids and account ids |
52
- | `psn_get_friends` | A user's friends list, resolved to profiles |
53
- | `psn_get_presence` | Online status, current platform, and the game being played |
54
- | `psn_get_trophy_summary` | Trophy level, tier, and total trophy counts |
55
- | `psn_get_trophy_titles` | Games with trophy progress, most recently played first |
56
- | `psn_get_title_trophies` | Full trophy list defined for a game (names, types, groups) |
69
+ | Tool | Description |
70
+ | ------------------------- | ------------------------------------------------------------------ |
71
+ | `psn_auth_status` | Whether PSN credentials are configured or login is in progress |
72
+ | `psn_begin_login` | Open the browser-based PSN login helper |
73
+ | `psn_complete_login` | Capture and save the NPSSO token from the login helper |
74
+ | `psn_cancel_login` | Close the login helper without saving credentials |
75
+ | `psn_get_profile` | Profile for a user: online id, about-me, avatars, PS Plus status |
76
+ | `psn_search_players` | Search PSN players by name; returns online ids and account ids |
77
+ | `psn_get_friends` | A user's friends list, resolved to profiles |
78
+ | `psn_get_presence` | Online status, current platform, and the game being played |
79
+ | `psn_get_trophy_summary` | Trophy level, tier, and total trophy counts |
80
+ | `psn_get_trophy_titles` | Games with trophy progress, most recently played first |
81
+ | `psn_get_title_trophies` | Full trophy list defined for a game (names, types, groups) |
57
82
  | `psn_get_earned_trophies` | Which trophies a user earned in a game, with timestamps and rarity |
58
- | `psn_get_played_games` | Played PS4/PS5 games with play counts and durations |
83
+ | `psn_get_played_games` | Played PS4/PS5 games with play counts and durations |
84
+ | `psn_get_store_deals` | Games on sale, with prices, discounts, and (optional) star ratings |
85
+ | `psn_get_store_product` | Store product details: price, discount, and community star rating |
86
+ | `psn_search_store` | Search the store catalog by name, with current prices |
87
+
88
+ Every user-scoped tool accepts `"me"` (the authenticated account), a PSN online
89
+ id (username), or a numeric account id — online ids are resolved automatically.
59
90
 
60
- Every user-scoped tool accepts `"me"` (the authenticated account), a PSN online id (username), or a numeric account id — online ids are resolved automatically.
91
+ For PS5 titles pass `npServiceName: "trophy2"`; for PS4 and earlier use
92
+ `"trophy"`. `psn_get_trophy_titles` reports the right value per game.
61
93
 
62
- For PS5 titles pass `npServiceName: "trophy2"`; for PS4 and earlier use `"trophy"`. `psn_get_trophy_titles` reports the right value per game.
94
+ The three `store` tools browse the public PlayStation Store and need **no PSN
95
+ account**. They power prompts like _"give me the top 10 games currently on sale
96
+ based on review score"_ — call `psn_get_store_deals` with `includeRatings: true`
97
+ and rank by `starRating.averageRating`. Set `PSN_STORE_LOCALE` (e.g. `en-gb`,
98
+ `de-de`, `ja-jp`) to change the store region and currency; the default is
99
+ `en-us`.
63
100
 
64
101
  ## Architecture
65
102
 
@@ -71,11 +108,22 @@ src/
71
108
  auth.ts NPSSO -> OAuth code -> access token exchange, auto-refresh
72
109
  http.ts Authenticated JSON client for m.np.playstation.com
73
110
  api.ts Typed endpoint wrappers (profiles, trophies, games, search)
111
+ store.ts Public store catalog: deals, search, prices, star ratings
74
112
  types.ts PSN API response types
75
113
  ```
76
114
 
77
- Authentication is lazy: the server starts and lists tools without credentials; the token exchange happens on the first tool call. Access tokens are refreshed ahead of expiry, falling back to a full NPSSO re-exchange if the refresh token has expired.
115
+ The store module works differently from the account API: the store's GraphQL
116
+ endpoint only accepts Sony's whitelisted persisted queries, so it instead reads
117
+ the Apollo state and star-rating payloads that the store server-renders into
118
+ every page's `__NEXT_DATA__` blob. This needs no authentication but is
119
+ inherently coupled to the store's page structure.
120
+
121
+ Authentication is lazy: the server starts and lists tools without credentials;
122
+ the token exchange happens on the first tool call. Access tokens are refreshed
123
+ ahead of expiry, falling back to a full NPSSO re-exchange if the refresh token
124
+ has expired.
78
125
 
79
126
  ## Disclaimer
80
127
 
81
- This project uses undocumented PSN endpoints and is not affiliated with or endorsed by Sony Interactive Entertainment. Use at your own risk.
128
+ This project uses undocumented PSN endpoints and is not affiliated with or
129
+ endorsed by Sony Interactive Entertainment. Use at your own risk.
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js CHANGED
@@ -2,22 +2,27 @@
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { TokenManager } from "./psn/auth.js";
5
+ import { loadStoredNpsso } from "./psn/credentials.js";
5
6
  import { PsnHttpClient } from "./psn/http.js";
6
7
  import { PsnApi } from "./psn/api.js";
8
+ import { PsnStore } from "./psn/store.js";
7
9
  import { registerTools } from "./tools.js";
8
10
  async function main() {
9
- const npsso = process.env.PSN_NPSSO ?? "";
11
+ const npsso = process.env.PSN_NPSSO || (await loadStoredNpsso()) || "";
10
12
  if (!npsso) {
11
13
  // stdout is reserved for the MCP protocol; diagnostics go to stderr.
12
- console.error("warning: PSN_NPSSO is not set - tools will fail until it is configured.\n" +
13
- "Sign in at https://www.playstation.com, then copy the token from " +
14
- "https://ca.account.sony.com/api/v1/ssocookie");
14
+ console.error("warning: no PSN credentials are configured - account tools will fail until login completes.\n" +
15
+ "Call the psn_begin_login MCP tool, sign in to PlayStation in the opened browser, " +
16
+ "then call psn_complete_login.");
15
17
  }
16
18
  // Auth is lazy: the token exchange happens on the first tool call, so the
17
19
  // server starts (and lists tools) even before credentials are configured.
18
- const psn = new PsnApi(new PsnHttpClient(new TokenManager(npsso || "unset")));
20
+ const tokens = new TokenManager(npsso);
21
+ const psn = new PsnApi(new PsnHttpClient(tokens));
22
+ // Store browsing is public web data; no PSN account needed.
23
+ const store = new PsnStore(process.env.PSN_STORE_LOCALE ?? "en-us");
19
24
  const server = new McpServer({ name: "psn-mcp", version: "0.1.0" });
20
- registerTools(server, psn);
25
+ registerTools(server, psn, store, tokens);
21
26
  await server.connect(new StdioServerTransport());
22
27
  console.error("psn-mcp server running on stdio");
23
28
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;IAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,qEAAqE;QACrE,OAAO,CAAC,KAAK,CACX,2EAA2E;YACzE,mEAAmE;YACnE,8CAA8C,CACjD,CAAC;IACJ,CAAC;IAED,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,IAAI,aAAa,CAAC,IAAI,YAAY,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IAE9E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACpE,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE3B,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;AACnD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,MAAM,eAAe,EAAE,CAAC,IAAI,EAAE,CAAC;IACvE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,qEAAqE;QACrE,OAAO,CAAC,KAAK,CACX,+FAA+F;YAC7F,mFAAmF;YACnF,+BAA+B,CAClC,CAAC;IACJ,CAAC;IAED,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,4DAA4D;IAC5D,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,CAAC;IAEpE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACpE,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAE1C,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;AACnD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/psn/api.d.ts CHANGED
@@ -34,3 +34,4 @@ export declare class PsnApi {
34
34
  getEarnedTrophies(accountId: string, npCommunicationId: string, npServiceName: NpServiceName, trophyGroupId?: string, limit?: number, offset?: number): Promise<TrophiesResponse>;
35
35
  getPlayedGames(accountId: string, limit?: number, offset?: number): Promise<PlayedGamesResponse>;
36
36
  }
37
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/psn/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,uBAAuB,EACvB,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjD;;;;;;GAMG;AACH,qBAAa,MAAM;IACL,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,aAAa;IAIhD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAMnD,aAAa,CACX,UAAU,EAAE,MAAM,EAClB,KAAK,SAAK,GACT,OAAO,CAAC,uBAAuB,CAAC;IAkBnC;;;;OAIG;IACG,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBrD,UAAU,CACR,SAAS,EAAE,MAAM,EACjB,KAAK,SAAM,EACX,MAAM,SAAI,GACT,OAAO,CAAC,eAAe,CAAC;IAO3B,gBAAgB,CACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,aAAa,EAAE,aAAa,CAAA;KAAE,CAAC;IAO5C,iBAAiB,CACf,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC;QAAE,cAAc,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;IAS/C,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAM3D,eAAe,CACb,SAAS,EAAE,MAAM,EACjB,KAAK,SAAM,EACX,MAAM,SAAI,GACT,OAAO,CAAC,oBAAoB,CAAC;IAOhC,mEAAmE;IACnE,gBAAgB,CACd,iBAAiB,EAAE,MAAM,EACzB,aAAa,EAAE,aAAa,EAC5B,aAAa,SAAQ,EACrB,KAAK,SAAM,EACX,MAAM,SAAI,GACT,OAAO,CAAC,gBAAgB,CAAC;IAQ5B,kEAAkE;IAClE,iBAAiB,CACf,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,aAAa,EAAE,aAAa,EAC5B,aAAa,SAAQ,EACrB,KAAK,SAAM,EACX,MAAM,SAAI,GACT,OAAO,CAAC,gBAAgB,CAAC;IAW5B,cAAc,CACZ,SAAS,EAAE,MAAM,EACjB,KAAK,SAAK,EACV,MAAM,SAAI,GACT,OAAO,CAAC,mBAAmB,CAAC;CAYhC"}
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/psn/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/psn/api.ts"],"names":[],"mappings":"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"}
@@ -29,11 +29,14 @@ export declare function refreshTokens(refreshToken: string): Promise<TokenSet>;
29
29
  * token itself has expired.
30
30
  */
31
31
  export declare class TokenManager {
32
- private readonly npsso;
33
32
  private tokens;
34
33
  private pending;
35
- constructor(npsso: string);
34
+ private npsso;
35
+ constructor(npsso?: string | null);
36
+ hasNpsso(): boolean;
37
+ setNpsso(npsso: string): void;
36
38
  /** Returns a valid access token, authenticating or refreshing as needed. */
37
39
  getAccessToken(): Promise<string>;
38
40
  private renew;
39
41
  }
42
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/psn/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAwED,iEAAiE;AACjE,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAU5E;AAED,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAS3E;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,KAAK,CAAgB;gBAEjB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAIjC,QAAQ,IAAI,OAAO;IAInB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAS7B,4EAA4E;IACtE,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;YAezB,KAAK;CAkBpB"}
package/dist/psn/auth.js CHANGED
@@ -92,16 +92,22 @@ export async function refreshTokens(refreshToken) {
92
92
  * token itself has expired.
93
93
  */
94
94
  export class TokenManager {
95
- npsso;
96
95
  tokens = null;
97
96
  pending = null;
97
+ npsso;
98
98
  constructor(npsso) {
99
- this.npsso = npsso;
99
+ this.npsso = npsso || null;
100
+ }
101
+ hasNpsso() {
102
+ return Boolean(this.npsso);
103
+ }
104
+ setNpsso(npsso) {
100
105
  if (!npsso) {
101
- throw new PsnAuthError("No NPSSO token configured. Set the PSN_NPSSO environment variable. " +
102
- "Sign in at https://www.playstation.com, then visit " +
103
- "https://ca.account.sony.com/api/v1/ssocookie to copy your token.");
106
+ throw new PsnAuthError("Cannot set an empty NPSSO token.");
104
107
  }
108
+ this.npsso = npsso;
109
+ this.tokens = null;
110
+ this.pending = null;
105
111
  }
106
112
  /** Returns a valid access token, authenticating or refreshing as needed. */
107
113
  async getAccessToken() {
@@ -119,6 +125,10 @@ export class TokenManager {
119
125
  return this.tokens.accessToken;
120
126
  }
121
127
  async renew() {
128
+ if (!this.npsso) {
129
+ throw new PsnAuthError("No NPSSO token configured. Run psn_begin_login and psn_complete_login, " +
130
+ "or set the PSN_NPSSO environment variable.");
131
+ }
122
132
  const margin = 60_000;
123
133
  if (this.tokens && this.tokens.refreshExpiresAt - margin > Date.now()) {
124
134
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/psn/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/psn/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export interface BeginBrowserLoginResult {
2
+ loginUrl: string;
3
+ message: string;
4
+ }
5
+ export interface CompleteBrowserLoginResult {
6
+ npsso: string;
7
+ }
8
+ export declare function hasActiveBrowserLogin(): boolean;
9
+ export declare function beginBrowserLogin(): Promise<BeginBrowserLoginResult>;
10
+ export declare function completeBrowserLogin(): Promise<CompleteBrowserLoginResult>;
11
+ export declare function cancelBrowserLogin(): Promise<void>;
12
+ //# sourceMappingURL=browser-login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-login.d.ts","sourceRoot":"","sources":["../../src/psn/browser-login.ts"],"names":[],"mappings":"AAqCA,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAkD1E;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,0BAA0B,CAAC,CAiBhF;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAExD"}
@@ -0,0 +1,201 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { mkdtemp, rm } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { createServer } from "node:net";
7
+ const LOGIN_URL = "https://www.playstation.com/";
8
+ let activeSession = null;
9
+ export function hasActiveBrowserLogin() {
10
+ return activeSession !== null;
11
+ }
12
+ export async function beginBrowserLogin() {
13
+ if (activeSession) {
14
+ return {
15
+ loginUrl: LOGIN_URL,
16
+ message: "A PSN login browser is already open. Sign in there, then call psn_complete_login.",
17
+ };
18
+ }
19
+ const browserPath = findBrowserPath();
20
+ if (!browserPath) {
21
+ throw new Error("Could not find a supported browser. Install Chrome, Edge, Brave, or Chromium, " +
22
+ "or set PSN_BROWSER_PATH to the browser executable.");
23
+ }
24
+ const port = await getAvailablePort();
25
+ const userDataDir = await mkdtemp(join(tmpdir(), "psn-mcp-login-"));
26
+ const browser = spawn(browserPath, [
27
+ `--remote-debugging-port=${port}`,
28
+ "--remote-debugging-address=127.0.0.1",
29
+ `--user-data-dir=${userDataDir}`,
30
+ "--no-first-run",
31
+ "--no-default-browser-check",
32
+ LOGIN_URL,
33
+ ], {
34
+ detached: true,
35
+ stdio: "ignore",
36
+ });
37
+ browser.unref();
38
+ activeSession = { browser, port, userDataDir };
39
+ try {
40
+ await waitForDebugger(port);
41
+ }
42
+ catch (error) {
43
+ await cleanupActiveSession();
44
+ throw error;
45
+ }
46
+ return {
47
+ loginUrl: LOGIN_URL,
48
+ message: "A browser window was opened with an isolated profile. Sign in to PlayStation, " +
49
+ "then call psn_complete_login to capture the session automatically.",
50
+ };
51
+ }
52
+ export async function completeBrowserLogin() {
53
+ if (!activeSession) {
54
+ throw new Error("No PSN browser login is active. Call psn_begin_login first.");
55
+ }
56
+ const npsso = await readNpssoCookie(activeSession.port);
57
+ if (!npsso) {
58
+ throw new Error("Could not find an NPSSO cookie yet. Finish signing in to PlayStation in " +
59
+ "the opened browser window, then call psn_complete_login again.");
60
+ }
61
+ await cleanupActiveSession();
62
+ return { npsso };
63
+ }
64
+ export async function cancelBrowserLogin() {
65
+ await cleanupActiveSession();
66
+ }
67
+ function findBrowserPath() {
68
+ if (process.env.PSN_BROWSER_PATH)
69
+ return process.env.PSN_BROWSER_PATH;
70
+ const candidates = browserCandidates();
71
+ return candidates.find((candidate) => existsSync(candidate)) ?? null;
72
+ }
73
+ function browserCandidates() {
74
+ if (process.platform === "darwin") {
75
+ return [
76
+ "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
77
+ "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
78
+ "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
79
+ "/Applications/Chromium.app/Contents/MacOS/Chromium",
80
+ ];
81
+ }
82
+ if (process.platform === "win32") {
83
+ const roots = [
84
+ process.env.PROGRAMFILES,
85
+ process.env["PROGRAMFILES(X86)"],
86
+ process.env.LOCALAPPDATA,
87
+ ].filter(Boolean);
88
+ return roots.flatMap((root) => [
89
+ join(root, "Google", "Chrome", "Application", "chrome.exe"),
90
+ join(root, "Microsoft", "Edge", "Application", "msedge.exe"),
91
+ join(root, "BraveSoftware", "Brave-Browser", "Application", "brave.exe"),
92
+ ]);
93
+ }
94
+ return [
95
+ "/usr/bin/google-chrome",
96
+ "/usr/bin/google-chrome-stable",
97
+ "/usr/bin/chromium",
98
+ "/usr/bin/chromium-browser",
99
+ "/usr/bin/microsoft-edge",
100
+ "/usr/bin/brave-browser",
101
+ ];
102
+ }
103
+ async function getAvailablePort() {
104
+ return new Promise((resolve, reject) => {
105
+ const server = createServer();
106
+ server.once("error", reject);
107
+ server.listen(0, "127.0.0.1", () => {
108
+ const address = server.address();
109
+ server.close(() => {
110
+ if (typeof address === "object" && address) {
111
+ resolve(address.port);
112
+ }
113
+ else {
114
+ reject(new Error("Could not allocate a local debugger port."));
115
+ }
116
+ });
117
+ });
118
+ });
119
+ }
120
+ async function waitForDebugger(port) {
121
+ const deadline = Date.now() + 10_000;
122
+ while (Date.now() < deadline) {
123
+ try {
124
+ const res = await fetch(`http://127.0.0.1:${port}/json/version`);
125
+ if (res.ok)
126
+ return;
127
+ }
128
+ catch {
129
+ // Browser is still starting.
130
+ }
131
+ await delay(250);
132
+ }
133
+ throw new Error("Timed out waiting for the browser debugging endpoint.");
134
+ }
135
+ async function readNpssoCookie(port) {
136
+ const targets = (await fetchJson(`http://127.0.0.1:${port}/json/list`));
137
+ const page = targets.find((target) => target.type === "page" && target.webSocketDebuggerUrl);
138
+ if (!page?.webSocketDebuggerUrl) {
139
+ throw new Error("Could not find the browser page debugging target.");
140
+ }
141
+ const socket = await openCdpSocket(page.webSocketDebuggerUrl);
142
+ try {
143
+ const response = await sendCdp(socket, "Network.getAllCookies");
144
+ const cookie = response.cookies.find((candidate) => candidate.name.toLowerCase() === "npsso" && candidate.value);
145
+ return cookie?.value ?? null;
146
+ }
147
+ finally {
148
+ socket.close();
149
+ }
150
+ }
151
+ async function openCdpSocket(url) {
152
+ const WebSocketCtor = globalThis.WebSocket;
153
+ if (!WebSocketCtor) {
154
+ throw new Error("This Node.js runtime does not expose WebSocket. Use Node.js 22+ for browser login.");
155
+ }
156
+ const socket = new WebSocketCtor(url);
157
+ await new Promise((resolve, reject) => {
158
+ socket.addEventListener("open", () => resolve(), { once: true });
159
+ socket.addEventListener("error", (event) => reject(event.error ?? new Error("WebSocket connection failed.")), { once: true });
160
+ });
161
+ return socket;
162
+ }
163
+ async function sendCdp(socket, method) {
164
+ const id = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
165
+ const result = await new Promise((resolve, reject) => {
166
+ const timeout = setTimeout(() => reject(new Error(`Timed out calling Chrome DevTools ${method}.`)), 5_000);
167
+ socket.addEventListener("message", (event) => {
168
+ const data = JSON.parse(String(event.data));
169
+ if (data.id !== id)
170
+ return;
171
+ clearTimeout(timeout);
172
+ if (data.error) {
173
+ reject(new Error(data.error.message ?? `${method} failed.`));
174
+ }
175
+ else {
176
+ resolve(data.result);
177
+ }
178
+ });
179
+ socket.send(JSON.stringify({ id, method }));
180
+ });
181
+ return result;
182
+ }
183
+ async function fetchJson(url) {
184
+ const res = await fetch(url);
185
+ if (!res.ok) {
186
+ throw new Error(`Browser debugging endpoint failed with HTTP ${res.status}.`);
187
+ }
188
+ return res.json();
189
+ }
190
+ async function cleanupActiveSession() {
191
+ const session = activeSession;
192
+ activeSession = null;
193
+ if (!session)
194
+ return;
195
+ session.browser.kill();
196
+ await rm(session.userDataDir, { recursive: true, force: true });
197
+ }
198
+ function delay(ms) {
199
+ return new Promise((resolve) => setTimeout(resolve, ms));
200
+ }
201
+ //# sourceMappingURL=browser-login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-login.js","sourceRoot":"","sources":["../../src/psn/browser-login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function credentialsPath(): string;
2
+ export declare function loadStoredNpsso(): Promise<string | null>;
3
+ export declare function saveStoredNpsso(npsso: string): Promise<string>;
4
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/psn/credentials.ts"],"names":[],"mappings":"AAQA,wBAAgB,eAAe,IAAI,MAAM,CAKxC;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAU9D;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASpE"}
@@ -0,0 +1,29 @@
1
+ import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+ export function credentialsPath() {
5
+ return (process.env.PSN_NPSSO_FILE ??
6
+ join(homedir(), ".config", "psn-mcp", "credentials.json"));
7
+ }
8
+ export async function loadStoredNpsso() {
9
+ try {
10
+ const data = JSON.parse(await readFile(credentialsPath(), "utf8"));
11
+ return data.npsso || null;
12
+ }
13
+ catch (error) {
14
+ if (error.code === "ENOENT")
15
+ return null;
16
+ throw error;
17
+ }
18
+ }
19
+ export async function saveStoredNpsso(npsso) {
20
+ const path = credentialsPath();
21
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
22
+ await writeFile(path, `${JSON.stringify({ npsso }, null, 2)}\n`, {
23
+ encoding: "utf8",
24
+ mode: 0o600,
25
+ });
26
+ await chmod(path, 0o600);
27
+ return path;
28
+ }
29
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/psn/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAM1C,MAAM,UAAU,eAAe;IAC7B,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,cAAc;QAC1B,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAC1D,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CACrB,MAAM,QAAQ,CAAC,eAAe,EAAE,EAAE,MAAM,CAAC,CACvB,CAAC;QACrB,OAAO,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACpE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAa;IACjD,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QAC/D,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;IACH,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -19,3 +19,4 @@ export declare class PsnHttpClient {
19
19
  constructor(tokens: TokenManager);
20
20
  request<T>(path: string, options?: RequestOptions): Promise<T>;
21
21
  }
22
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/psn/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAI9C,qBAAa,WAAY,SAAQ,KAAK;aAGlB,MAAM,EAAE,MAAM;aACd,IAAI,CAAC,EAAE,OAAO;gBAF9B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,OAAO,YAAA;CAKjC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IAC9D,mCAAmC;IACnC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,kEAAkE;AAClE,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,YAAY;IAE3C,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;CA2CzE"}
package/dist/psn/http.js CHANGED
@@ -27,7 +27,9 @@ export class PsnHttpClient {
27
27
  headers: {
28
28
  Authorization: `Bearer ${accessToken}`,
29
29
  "Accept-Language": "en-US",
30
- ...(options.body !== undefined ? { "Content-Type": "application/json" } : {}),
30
+ ...(options.body !== undefined
31
+ ? { "Content-Type": "application/json" }
32
+ : {}),
31
33
  ...options.headers,
32
34
  },
33
35
  body: options.body !== undefined ? JSON.stringify(options.body) : undefined,