๐ฎ psn-mcp
A Model Context Protocol server for the PlayStation Network
Let MCP clients like Claude look up PSN profiles, friends, online presence, trophies, purchased games, play history, and store deals โ in plain language.
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 mobile and web APIs.
โจ Highlights
- ๐งโ๐คโ๐ง Profiles & friends โ look up any player, resolve friends lists to full profiles
- ๐ข Live presence โ see who's online, on which platform, and what they're playing
- ๐ Trophies โ levels, tiers, per-game progress, earned state, and global rarity
- โฑ๏ธ Play history โ PS4/PS5 games with play counts and total durations
- ๐ฎ Purchased library โ digital PS4/PS5 games, including unplayed titles, with artwork and license metadata
- ๐ Store โ deals, prices, discounts, and review scores, no PSN account required
- ๐ Zero client deps โ pure TypeScript on Node
fetch, credentials stored owner-only
๐ฆ Requirements
- Node.js 24.18+
- A PlayStation Network account (not needed for the store tools)
๐ Usage with an MCP client
No installation needed โ run it with npx. Add to your client's MCP
configuration (e.g. claude_desktop_config.json):
{
"mcpServers": {
"psn": {
"command": "npx",
"args": ["-y", "psn-mcp"]
}
}
}
Or for Claude Code:
claude mcp add psn -- npx -y psn-mcp
๐ Signing in
The MCP server can automate NPSSO capture through an isolated browser profile:
- Start the MCP server without
PSN_NPSSO. - Call the
psn_begin_logintool. - Sign in to PlayStation in the browser window it opens.
- Call the
psn_complete_logintool.
psn_complete_login reads the PlayStation npsso browser cookie, verifies it,
and stores it in ~/.config/psn-mcp/credentials.json with owner-only file
permissions. Future server starts use the stored token automatically. Set
PSN_NPSSO_FILE to choose a different credential file.
- Sign in at playstation.com.
- In the same browser, open https://ca.account.sony.com/api/v1/ssocookie.
- Copy the 64-character
npssovalue from the JSON response intoPSN_NPSSO.
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, run the login flow again.
[!NOTE] This uses your personal account session. What you can see (other users' friends, presence, play history) is governed by normal PSN privacy settings.
๐งฐ Tools
Every user-scoped tool accepts "me" (the authenticated account), a PSN online
id (username), or a numeric account id โ online ids are resolved automatically.
psn_get_purchased_games accesses only the authenticated account and has no
user parameter. It returns digital library entitlements, including unplayed
games and potentially free or PS Plus titles, rather than a payment history or
physical-disc collection. Metadata includes names, platforms, artwork, product,
title and entitlement ids, and available active/downloadable/pre-order flags
and membership information. It does not report purchase prices or dates.
Purchased games default to active PS4/PS5 licenses, ordered by activation date
(newest first). Use platform: ["ps5"] to filter platforms, isActive: false
for inactive licenses, or membership: "PS_PLUS" for PS Plus entitlements.
membership: "NONE" selects entitlements not from PS Plus, including free titles;
it does not mean paid purchases. Omit membership to include all membership types.
Use sortDirection: "asc" for oldest first.
Pages accept limit (1โ100, default 50) and offset (default 0). Pass the
returned nextOffset as offset until it is absent. The NONE filter may scan
several library pages per call. Its offsets count matching entitlements, and its
totalItemCount and pageInfo are returned only when the scan reaches the end
and the filtered total is known. For other membership selections, pagination and
totals come from Sony; when Sony omits pageInfo, a full final page can be
followed by an empty page.
Play time is included by default: playDuration (an ISO 8601 duration such as
PT12H30M), playCount, firstPlayedDateTime, and lastPlayedDateTime where
PSN provides them. This may require several play-history requests per
purchased-library page; set includePlayTime: false to skip them. Games are
matched by exact title ID, keeping PS4/PS5 versions separate. Missing fields mean no matching
data was available, not zero time played. If the lookup fails, the library
still returns with a playTimeError explaining why play time is unavailable.
For PS5 titles pass npServiceName: "trophy2"; for PS4 and earlier use
"trophy". psn_get_trophy_titles reports the right value per game.
The three store tools browse the public PlayStation Store and need no PSN
account. Set PSN_STORE_LOCALE (e.g. en-gb, de-de, ja-jp) to change the
store region and currency; the default is en-us.
๐ฌ Examples
Once the server is connected, just ask in natural language. Some prompts and the tools they exercise:
๐ข Presence and friends
"Is anyone on my friends list online right now? What are they playing?"
Calls psn_get_friends, then psn_get_presence for each friend, and reports
who is online, on which platform, and in what game.
"Look up the profile for online id
Hakoom."
Calls psn_get_profile with user: "Hakoom" โ any tool that takes a user
accepts "me", an online id, or a numeric account id.
๐ Trophies
"What's my trophy level, and what game did I most recently earn trophies in?"
Calls psn_get_trophy_summary and psn_get_trophy_titles (most recently played
first).
"Which trophies am I still missing in Astro Bot, and how rare are they?"
Finds the game via psn_get_trophy_titles (getting its npCommunicationId and
npServiceName), then combines psn_get_title_trophies (names and
descriptions) with psn_get_earned_trophies (earned state and global rarity) to
list the unearned ones, rarest first.
โฑ๏ธ Play history
"How many hours have I put into my ten most-played PS5 games?"
Calls psn_get_played_games and ranks by total play duration.
๐ฎ Purchased games
"List the PS5 games in my digital library, including games I haven't played."
Calls psn_get_purchased_games with platform: ["ps5"], following nextOffset
to retrieve more pages. Each entry includes its available game and license
metadata. Use its productId with psn_get_store_product for current store
prices and ratings (these are not the original purchase price).
"List my purchased games with the time I've spent playing each one."
Calls psn_get_purchased_games, which includes play time by default.
๐ Store (no PSN account needed)
"Give me the top 10 games currently on sale based on review score."
Calls psn_get_store_deals with includeRatings: true and ranks by
starRating.averageRating.
"Is Elden Ring discounted right now? What do reviewers rate it?"
Calls psn_search_store with query: "Elden Ring", then
psn_get_store_product for the price, discount, and star-rating breakdown.
๐๏ธ Architecture
src/
index.ts Entry point: stdio MCP server wiring
server.ts MCP server factory and protocol-version settings
tools.ts MCP tool definitions (zod schemas -> PSN API calls)
psn/
auth.ts NPSSO -> OAuth code -> access token exchange, auto-refresh
http.ts Authenticated JSON client for Sony's mobile and web APIs
api.ts Typed endpoint wrappers (profiles, trophies, game libraries, search)
store.ts Public store catalog: deals, search, prices, star ratings
types.ts PSN API response types
The store module works differently from the account API: the store's GraphQL
endpoint only accepts Sony's whitelisted persisted queries, so it instead reads
the Apollo state and star-rating payloads that the store server-renders into
every page's __NEXT_DATA__ blob. This needs no authentication but is
inherently coupled to the store's page structure.
The purchased library uses the authenticated web GraphQL API's persisted
getPurchasedGameList query. Like the other undocumented endpoints, its query
hash and response shape may change; GraphQL failures are returned as tool errors.
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.
โ ๏ธ Disclaimer
This project uses undocumented PSN endpoints and is not affiliated with or endorsed by Sony Interactive Entertainment. Use at your own risk.