{"slug": "show-hn-hinge-mcp", "title": "Show HN: Hinge MCP", "summary": "An unofficial TypeScript Model Context Protocol server for Hinge accounts, hinge-mcp 0.2.0, exposes 23 tools, three resources, one resource template, three prompts and prompt-argument completion, with an optional raw tool bringing the total to 24. Built on the official MCP TypeScript SDK 2.1.0, the compiled CLI is tested with the 2026-07-28 protocol and legacy clients over local stdio or Streamable HTTP with an optional static bearer token or OAuth resource-server authentication, and requires Node.js 22 or 24. The project states it is unaffiliated with Hinge, Match Group, Sendbird, OpenAI or Anthropic, that the Hinge API is reverse engineered and can change independently, and that users should only use an account they control and review Hinge's terms before use.", "body_md": "A TypeScript [Model Context Protocol](https://modelcontextprotocol.io/) server for your own Hinge account.\n\nIt exposes **23 tools, three resources, one resource template, three prompts, and prompt-argument completion**. It runs locally over **stdio**, or over **Streamable HTTP** with an optional static bearer token or OAuth resource-server authentication. The optional raw tool brings the total to 24.\n\nUses the official MCP TypeScript SDK **2.1.0**. The compiled CLI is tested with the **2026-07-28 protocol and legacy clients**, over both transports. The SDK handles protocol framing, discovery/initialization, negotiation, schemas, and errors.\n\nThis project is unofficial and unaffiliated with Hinge, Match Group, Sendbird, OpenAI, or Anthropic. The Hinge API is reverse engineered and can change independently of this server. Use only an account you control. Review Hinge's terms before use.\n\nRequirements: **Node.js 22 or 24**, npm, and a Hinge account for live use. Windows, macOS, and Linux are covered by CI.\n\n```\ngit clone https://github.com/Kuberwastaken/hinge-mcp.git\ncd hinge-mcp\nnpm ci\nnpm run build\nnode mcp/dist/cli.js --help\n```\n\nConfigure your MCP host to launch `node` with the **absolute path** to `mcp/dist/cli.js`. The host owns stdin/stdout; starting the CLI in a terminal without an MCP client will simply wait for protocol messages. Do not use `npm start` as the host's stdio command because npm can print non-protocol banners.\n\nStart with `HINGE_MCP_READ_ONLY=1` if you only want account reads. Login and logout remain available in that mode. No login or network request occurs just from discovering tools.\n\nNo npm release is implied by this repository. Do not assume `npx hinge-mcp` installs this fork. To install the exact code you built:\n\n```\nnpm pack --workspace mcp --pack-destination .\nnpm install -g ./hinge-mcp-0.2.0.tgz\nhinge-mcp --version\n```\n\nThe tarball contains the compiled server, bundled local SDK, TypeScript declarations, README and its hero image, the complete agent guide, and MIT license. It does not need this checkout or a `file:` dependency at runtime. Rebuild before packing after source changes.\n\nThese configurations follow the linked vendors' official documentation. Automated tests exercise the wire protocols with official SDK clients; they do **not** claim that every vendor application's UI has been manually tested. Hosts differ in whether they display resources, prompts, or completion. The tools work independently of those optional host interfaces.\n\nUse this stdio entry in Claude Desktop's developer configuration or Cursor's `.cursor/mcp.json` / `~/.cursor/mcp.json`. Replace the path; forward slashes also work on Windows (` C:/path/to/hinge-mcp/mcp/dist/cli.js`).\n\n```\n{\n  \"mcpServers\": {\n    \"hinge\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/hinge-mcp/mcp/dist/cli.js\"],\n      \"env\": {\n        \"HINGE_PHONE_NUMBER\": \"+15555550123\",\n        \"HINGE_MCP_READ_ONLY\": \"1\"\n      }\n    }\n  }\n}\n```\n\nRestart/reload the host and run `hinge_session_status`. Cursor also supports HTTP with an `Authorization` header; see [Cursor MCP documentation](https://cursor.com/docs/mcp).\n\n```\nclaude mcp add --env HINGE_PHONE_NUMBER=+15555550123 HINGE_MCP_READ_ONLY=1 --transport stdio hinge -- node /absolute/path/to/hinge-mcp/mcp/dist/cli.js\n```\n\nSee [Claude Code MCP setup](https://code.claude.com/docs/en/mcp). Keep host options before `--`.\n\nAdd this to `~/.codex/config.toml`:\n\n```\n[mcp_servers.hinge]\ncommand = \"node\"\nargs = [\"/absolute/path/to/hinge-mcp/mcp/dist/cli.js\"]\nstartup_timeout_sec = 20\ntool_timeout_sec = 45\n\n[mcp_servers.hinge.env]\nHINGE_PHONE_NUMBER = \"+15555550123\"\nHINGE_MCP_READ_ONLY = \"1\"\n```\n\nAlternatively, for a running HTTP instance:\n\n```\n[mcp_servers.hinge]\nurl = \"http://127.0.0.1:3939/mcp\"\nbearer_token_env_var = \"HINGE_MCP_TOKEN\"\ntool_timeout_sec = 45\n```\n\nSet that variable in the environment of both processes. See [official Codex MCP documentation](https://developers.openai.com/codex/mcp/).\n\nCreate `.vscode/mcp.json`:\n\n```\n{\n  \"servers\": {\n    \"hinge\": {\n      \"type\": \"stdio\",\n      \"command\": \"node\",\n      \"args\": [\"${workspaceFolder}/mcp/dist/cli.js\"],\n      \"env\": { \"HINGE_MCP_READ_ONLY\": \"1\" }\n    }\n  }\n}\n```\n\nThis example assumes the opened folder is this repository. For remote use, set `type` to `http`, provide `url`, and configure headers or OAuth. See [VS Code's configuration reference](https://code.visualstudio.com/docs/agents/reference/mcp-configuration).\n\nUse an **HTTPS Streamable HTTP endpoint** and the OAuth mode below for hosts that perform OAuth discovery. Register `https://your-host.example/mcp` in the host's developer MCP/plugin settings and select OAuth. Your authorization provider must support the host's callback URI and client-registration method. Account/organization settings may control access to developer integrations.\n\nFor API callers or hosts that accept an explicit bearer header, static-token mode is also available. This is a private deployment option, **not an OAuth authorization server**. A client that requires an interactive OAuth flow must use OAuth mode.\n\n`search` and `fetch` return JSON text and matching structured content. Hinge does not provide verified browser-openable URLs for these private records, so this server deliberately omits citation URLs. They work as ordinary tools; they do not manufacture web citations. See [OpenAI's MCP integration and citation contract](https://developers.openai.com/api/docs/mcp) and [authentication guidance](https://developers.openai.com/plugins/build/auth).\n\nAsk your assistant: **\"Set up my Hinge connection, help me sign in if needed, verify a profile read, then continue my task.\"** Hosts that expose MCP prompts can select `setup_account`; assistants can read `hinge://setup` for the full guide. Tool-only hosts receive the essential workflow in server instructions, tool descriptions, and authentication results.\n\n[AGENTS.md](https://github.com/Kuberwastaken/hinge-mcp/blob/main/AGENTS.md) contains instructions for every tool, resource, prompt, and completion workflow, plus setup, permissions, troubleshooting, and repository maintenance. It is included in the installed package and served through MCP, so an assistant does not need access to this checkout.\n\nThe assistant checks the current session first, asks only for missing details, and reuses an existing session **by path** when possible. Otherwise it guides SMS login and any email challenge, then calls `hinge_me` to verify a live read. There is no API key for the user to find and no need to paste token JSON. A local session path must exist on the machine running the server.\n\nIf an assistant has a connected SMS/email tool, the guide permits retrieving the matching code only with specific user authorization for that account and login. The Hinge MCP server itself cannot read SMS/email. Manual entry remains available; codes passed through chat/tool arguments may be retained by the chosen host. The guide does not grant inbox access or authorize unrelated account writes.\n\nFetching setup instructions has no side effects. A new login sends SMS and clears prior local login state, so the guide tells assistants to establish login intent and avoid repeated sends. It also distinguishes the endpoint's bearer token/OAuth from the saved Hinge session, covers unsupported Google/Apple login, and prevents fixture tests being presented as live verification.\n\n1. Call `hinge_session_status` .`loggedIn` is a**local expiry check** , not proof that Hinge still accepts the token. Use`hinge_me` to verify an existing session remotely.\n2. Call `hinge_login_start` with`phoneNumber` in E.164 format, or set`HINGE_PHONE_NUMBER` . This sends an SMS. Starting a new login clears the previous local session state.\n3. Call `hinge_login_verify_otp` with the numeric SMS code.\n4. If the result has `status: \"email_verification_required\"` , pass its`caseId` and the emailed code to`hinge_login_verify_email` .\n5. Call `hinge_me` . After restart, the saved session loads automatically.\n\nOTP tools are available across clients and do not require elicitation support. Codes entered into tools are visible to your chosen host; don't place them in source files or issue reports. Session tokens are never intentionally returned by authentication tools.\n\n`hinge_logout` removes the configured session file and clears tokens, device state, in-memory recommendations, and the prompt cache. It does not revoke the session at Hinge. Log out before changing to another phone number. A configured phone that conflicts with a saved session stops startup.\n\nThe default session file is `~/.hinge-mcp/session.json`. Writes use an exclusive temporary file and atomic rename, with POSIX mode `0600` and newly created directories `0700`. Windows permissions follow filesystem ACLs: use a private user directory. Files are **not encrypted at rest**. Tokens travel to the upstream Hinge/Sendbird services to authenticate requests; requested account data travels back to your MCP host.\n\nUse **one process per account/session file**. To share a process across clients, use HTTP. The operation queue coordinates requests within that process, not across independent processes. This is a single-account server, not a multi-tenant hosting service.\n\nPowerShell:\n\n``` js\n$env:HINGE_MCP_TOKEN = node -e \"console.log(require('node:crypto').randomBytes(32).toString('hex'))\"\n$env:HINGE_MCP_READ_ONLY = '1'\nnode mcp/dist/cli.js --http 3939\n```\n\nPOSIX shell:\n\n``` js\nexport HINGE_MCP_TOKEN=\"$(node -e \"console.log(require('node:crypto').randomBytes(32).toString('hex'))\")\"\nexport HINGE_MCP_READ_ONLY=1\nnode mcp/dist/cli.js --http 3939\n```\n\nSend `Authorization: Bearer <value of HINGE_MCP_TOKEN>` to `/mcp`. Credentials in the URL path or query are not accepted. `/healthz` exposes only liveness, not account state.\n\nUnauthenticated loopback use is allowed for a trusted local machine. Non-loopback binding or a configured public URL requires authentication. Anyone authorized to this endpoint controls the same account, subject to read-only configuration.\n\nTerminate TLS at a reverse proxy or private tunnel you control. Keep the Node process on loopback where possible and forward `/mcp` and `/.well-known/oauth-protected-resource*`. Set `HINGE_MCP_PUBLIC_URL` to the exact external MCP URL. The server accepts its configured public Host and loopback hosts; it does not trust forwarded headers to discover its identity.\n\nOAuth uses an **external authorization server**, with this application acting as the protected resource. Configure these variables instead of `HINGE_MCP_TOKEN`:\n\n```\nHINGE_MCP_PUBLIC_URL=https://hinge.example.com/mcp\nHINGE_MCP_OAUTH_ISSUER=https://auth.example.com/\nHINGE_MCP_OAUTH_JWKS_URL=https://auth.example.com/.well-known/jwks.json\nHINGE_MCP_OAUTH_SUBJECT=the-exact-subject-of-the-account-owner\n```\n\nConfigure your authorization provider to:\n\n- Publish OAuth/OIDC discovery metadata and its public JWKS over HTTPS.\n- Support authorization-code flow with PKCE S256 and the MCP client's callback. Supply a pre-registered client, CIMD, or dynamic registration as appropriate for that host.\n- Honor the requested `resource` and issue an access token with audience exactly`HINGE_MCP_PUBLIC_URL` and scope`hinge:access` .\n- Issue signed JWT access tokens using RS256 or ES256, with `iss` ,`aud` ,`sub` ,`iat` , and`exp` . Copy the issuer exactly, including its trailing slash if present. Opaque tokens are not supported.\n\nThe server checks signature, issuer, audience, expiry, the configured owner subject, and scope on every request. Restricting `sub` prevents another user at the same issuer from accessing this single account. JWKS are cached by `jose`; rotation follows its remote-key cache behavior. No Hinge token is used as an MCP access token, and no MCP access token is forwarded upstream.\n\nDiscovery is exposed at both `/.well-known/oauth-protected-resource/mcp` and `/.well-known/oauth-protected-resource`. A 401 includes the metadata URL in `WWW-Authenticate`; insufficient scope returns 403. Tokens must be short lived because this server validates JWTs locally and does not perform revocation introspection. Authorization-provider hosting and browser consent are deployment responsibilities, not services bundled here.\n\nBrowser Origins must match an explicitly allowed origin, the configured public origin, or the exact local endpoint origin. For Inspector's browser UI, add its displayed origin to `HINGE_MCP_ALLOWED_ORIGINS`. Wildcards are rejected. Non-browser clients may omit Origin.\n\n- `/mcp` supports POST with the SDK's JSON or request-scoped SSE response behavior.\n- Current clients use discovery and per-request protocol metadata. Legacy clients use initialize; both reach the same feature factory.\n- No MCP session ID is allocated. GET/DELETE return 405; there is no standalone SSE stream or session to terminate.\n- The obsolete HTTP+SSE `/sse` transport is not implemented. Use stdio or Streamable HTTP.\n- Header/body version mismatches, malformed JSON, unsupported methods, and oversized bodies are rejected. CORS preflights return 204 for permitted Origins.\n- Request bodies and stdio frames are bounded at 1 MiB. Subscriptions are disabled because the server advertises no live feed/subscription feature.\n\nAll tool inputs are object schemas. Unknown top-level arguments are rejected. Successful results include JSON text and structured content; stable server-owned results declare output schemas. Dynamic upstream objects stay extensible. Business/API failures use `isError: true`; protocol failures are handled by the SDK. Tool annotations describe reads, writes, destructive actions, and idempotency; they are metadata, not a substitute for authorization.\n\n| Tool | Arguments | Result / effect | \n|---|---|---|\n| `hinge_session_status` | none | Local token presence, expiry, account identity, mode, next step | \n| `hinge_login_start` | optional `phoneNumber` | Send SMS and start a fresh local login | \n| `hinge_login_verify_otp` | `otp` | Login or email challenge; persist successful state | \n| `hinge_login_verify_email` | `caseId` ,`code` | Complete email verification | \n| `hinge_logout` | none | Delete local session and clear memory | \n\n| Tool | Arguments and bounds | Result | \n|---|---|---|\n| `hinge_me` | none | Own profile and content | \n| `hinge_profiles` | `userIds` (1–75), optional`includeRaw` | Compact profiles; missing ids | \n| `hinge_preferences` | none | Current dating preferences | \n| `hinge_recommendations` | optional `newHere` ,`activeToday` ,`includeProfiles` ,`limit` (default 25, max 100) | Feed subjects, origins, rating tokens, summaries | \n| `hinge_standouts` | none | Upstream Standouts object | \n| `hinge_like_limit` | none | Upstream allowance information | \n| `hinge_likes_received` | `limit` (25/100),`offset` (default 0),`includeProfiles` | Likes, total, `nextOffset` | \n| `hinge_matches` | `limit` (50/200),`offset` (default 0),`includeProfiles` | Matches, total, `nextOffset` | \n| `hinge_match_detail` | `subjectId` | Connection, match note, profile | \n| `hinge_chats` | `limit` (30/200) | Existing channels, partner and last-message fields when supplied upstream | \n| `hinge_chat_messages` | Exactly one of `channelUrl` /`partnerUserId` ; optional`limit` (50/200),`beforeTimestamp` | Messages ordered oldest first; lookup never creates a channel | \n| `hinge_prompts_search` | optional `query` ,`category` ,`limit` (30/200) | Hinge profile-prompt catalog; distinct from MCP prompts | \n\n`includeProfiles` defaults to true. Set it false to avoid profile/content lookups. Offset pagination slices a newly fetched likes/matches list, so a changing upstream list can move between pages. For older messages, pass the earliest returned timestamp as Unix milliseconds in `beforeTimestamp`. Channels use the SDK's bounded first page; this server does not promise an exhaustive chat search.\n\nThese tools are absent when `HINGE_MCP_READ_ONLY=1`. Verify the selected person, content, and intended action with the user. A timeout does not prove that a write failed; inspect the resulting account state before retrying.\n\n| Tool | Arguments | Effect | \n|---|---|---|\n| `hinge_like` | `subjectId` ,`ratingToken` ; optional`origin` ,`comment` ,`contentId` ,`questionText` ,`answerText` ,`photoUrl` ,`useRose` | Upstream like request; roses consume an account allowance | \n| `hinge_skip` | `subjectId` ,`ratingToken` , optional`origin` | Pass on a profile | \n| `hinge_send_message` | `subjectId` ,`message` (1–4000 characters), optional`isFirstMessage` | Send a text to a match; inspect history when first-message state is omitted | \n| `hinge_update_preferences` | `preferences` | Merge supported top-level fields into current preferences, then save | \n| `hinge_raw_request` | `service` (`hinge` /`sendbird` ),`method` , relative`path` , optional`body` | Advanced SDK escape hatch; also requires `HINGE_MCP_ALLOW_RAW=1` | \n\nUse fresh rating tokens and the origin returned by Hinge. Commented likes use the SDK's text-review endpoint before the rating call. Message sending preserves the SDK's deduplication identifier and Sendbird fallback for Hinge HTTP 400/404; it does not retry ambiguous network failures.\n\nPreference fields are `genderedAgeRanges`, `genderedHeightRanges`, `maxDistance`, `dealbreakers`, `religions`, `drinking`, `marijuana`, `relationshipTypes`, `drugs`, `children`, `ethnicities`, `smoking`, `educationAttained`, `familyPlans`, `datingIntentions`, `politics`, and `genderPreferences`. Read preferences before editing; a supplied nested map replaces that entire field. Unknown fields are rejected rather than silently ignored. Enum fields use the SDK's string labels; see the preserved SDK enum definitions.\n\nRaw requests reject absolute URLs, network-path references, and backslashes. The transport independently checks the destination origin and disables redirects. Raw responses still redact recognized credential fields. Raw mode is deliberately broad and should only be enabled when the ordinary tools cannot express the requested operation.\n\n`search({\"query\":\"matches Sam\"})` returns up to 50 `{id,title}` items. Source words select matches (default), likes, recommendations/discover, or chats/messages. Remaining words filter names, locations, prompt text, or chat summaries. Search inspects at most 200 candidate profiles or 100 channels and is not exhaustive full-text indexing.\n\n`fetch({\"id\":\"match:1002\"})` returns `{id,title,text,metadata}`. Supported prefixes are `match:`, `like:`, `rec:`, `profile:`, and `chat:`. A chat fetch reads the latest 100 messages and reports `window` / `possiblyMore`; use `hinge_chat_messages` for older history. API failures remain errors, not successful empty search results.\n\n| Surface | Name / URI | Behavior | \n|---|---|---|\n| Resource | `hinge://setup` | Full agent guide: onboarding, all tools, workflows, and credential handling; no network | \n| Resource | `hinge://usage` | Plain-text usage and trust guidance; no network | \n| Resource | `hinge://session` | Local token presence and expiry; no secrets or network | \n| Resource template | `hinge://profiles/{userId}` | Read a known public-profile id through the authenticated SDK | \n| Prompt | `setup_account` | No arguments; guides session reuse or login and verification without executing it | \n| Prompt | `review_profile` | Optional `focus` ; drafts a profile-review workflow | \n| Prompt | `draft_reply` | Required `channelUrl` , optional`tone` ; drafts replies without sending | \n| Completion | Prompt `focus` /`tone` | Suggested values such as `prompts` and`friendly` | \n\nResources represent context; prompts produce user-invoked workflows; tools perform bounded operations. Private profile resources are not exhaustively enumerated. Profile/message text is treated as untrusted data. Prompts never independently execute account writes. Sampling, elicitation, roots, tasks, live subscriptions, and a graphical MCP App are not required or advertised.\n\nEnvironment variables are read at process startup. `.env` is **not** loaded automatically; optionally use `node --env-file=.env mcp/dist/cli.js` and the checked-in `.env.example`. Keep real values outside Git. Boolean values accept `1/0`, `true/false`, `yes/no`, and `on/off`.\n\n| Variable | Default | Meaning | \n|---|---|---|\n| `HINGE_PHONE_NUMBER` | unset | E.164 number; can also be supplied to login | \n| `HINGE_SESSION_FILE` | `~/.hinge-mcp/session.json` | Absolute or working-directory-relative private session path | \n| `HINGE_MCP_READ_ONLY` | `0` | Hide account-write tools; login/logout still available | \n| `HINGE_MCP_ALLOW_RAW` | `0` | Enable raw tool unless read-only | \n| `HINGE_MCP_HTTP` | `0` | Select HTTP; `--http [port]` also selects it | \n| `HINGE_MCP_HOST` | `127.0.0.1` | HTTP bind address | \n| `HINGE_MCP_PORT` | `3939` | Port 0–65535; 0 allocates an ephemeral port; CLI port wins | \n| `HINGE_MCP_TOKEN` | unset | Static MCP bearer token; mutually exclusive with OAuth | \n| `HINGE_MCP_PUBLIC_URL` | unset | Exact public HTTPS URL ending in `/mcp` | \n| `HINGE_MCP_ALLOWED_ORIGINS` | empty | Additional exact browser Origins, comma separated | \n| `HINGE_MCP_OAUTH_ISSUER` | unset | Exact external token issuer | \n| `HINGE_MCP_OAUTH_JWKS_URL` | unset | HTTPS public signing-key endpoint | \n| `HINGE_MCP_OAUTH_SUBJECT` | unset | Only this token subject may access the account | \n| `HINGE_MCP_TIMEOUT_MS` | `30000` | Operation deadline, including queue time; 100–120000 ms | \n| `HINGE_MCP_DEBUG` | `0` | Request service/method/status/timing to stderr; no bodies, tokens, OTPs or URLs | \n\nOAuth requires all three OAuth variables plus the public URL. Malformed ports, booleans, phone numbers, URLs, and unknown CLI arguments fail startup. `--help` and `--version` print to stdout and exit; normal stdio operation reserves stdout for MCP.\n\n``` php\nflowchart LR\n  Host[MCP host] -->|stdio or Streamable HTTP| MCP[Official MCP SDK]\n  MCP --> Features[Tools, resources, prompts]\n  Features --> Queue[Single-account operation queue]\n  Queue --> SDK[Local hinge-ts SDK]\n  SDK --> HTTP[Bounded Node HTTP transport]\n  HTTP --> Hinge[Hinge / Sendbird]\n  Queue --> Session[Private atomic session file]\n```\n\nThe feature factory is shared between transports. HTTP creates protocol instances per exchange; the account context persists for the process lifetime. OAuth validation happens before requests reach account features.\n\n- Profile ids are deduplicated and batched by the SDK, 75 per request. Profile and content requests run concurrently within an operation.\n- Recommendation calls fetch once, replacing the upstream SDK's three-fetch default. Automatic recommendation retries are disabled.\n- Prompt descriptions are loaded only when profile answers need them, then cached in memory for 15 minutes. Logout clears the cache. Personal profiles/messages are not persisted as caches.\n- An account queue permits at most 32 active/waiting operations, preventing login/logout/preference-update races. Queued work checks cancellation before contacting upstream; fetch receives the operation's abort signal.\n- Upstream responses are bounded at 4 MiB before parsing. Tool JSON is bounded at 128 KiB; oversized results request narrower arguments instead of returning invalid truncated JSON.\n- The SDK is bundled into the package. No browser, proxy service, realtime WebSocket, or external database is needed for these REST tools.\n\nThis is not a full exposure of every upstream helper. File exports, credential retrieval, realtime typing/read receipts, and loosely specified account-editing endpoints stay in the preserved SDK. Prefer extending a typed tool with a documented use case over exposing unrestricted arbitrary SDK execution.\n\n```\nnpm ci\nnpm run typecheck\nnpm test\nnpm run test:package\nnpm run pack:dry\nnpm audit --omit=dev\n```\n\nThe suite currently has **52 tests**, including four subprocess workflows (current/legacy × stdio/HTTP). The package check installs the tarball in an isolated directory with production dependencies, imports its public API, checks the binary, and reruns all four workflows against that installed binary.\n\nEnd-to-end tests run the **real compiled CLI → official MCP client/server → real SDK → Node fetch → local HTTP Hinge/Sendbird fixture**. They cover SMS and email challenge handling, all 23 default tools, discovery, resource/template reads, prompts, completion, token persistence, and logout. They verify request counts and secret-free output. Additional tests cover protocol revisions 2024-11-05 through 2026-07-28, auth/origin/Host rejection, schema validation, cancellation, queue saturation, read-only enforcement, pagination foundations, output bounds, OAuth signature/claims/scope validation, and package independence.\n\nCI runs on Ubuntu, Windows, and macOS with Node 22 and 24. The tests require no Hinge credentials and send no real likes or messages. Package installation needs the npm registry; normal tests only use local fixtures.\n\nMCP Inspector 2.8.0 was also checked against the modern protocol: tool/resource/template/prompt discovery, a session-status tool call, a usage-resource read, and prompt retrieval passed. Inspector reported zero schema errors. Its portability warnings concern extensible upstream result objects and nullable JSON Schema types; those are valid MCP schemas, but individual model-provider schema dialects can differ.\n\n**Verification boundary:** fixtures prove the server's protocol and SDK integration, not the continuing availability of Hinge's private API. Vendor UI sessions and an external OAuth provider's browser-consent flow require testing in that deployment. No live-account verification is claimed without a separately recorded smoke run.\n\nFor a live, read-only check after logging in, set `HINGE_SESSION_FILE` to an existing session and run:\n\n```\nnpm run smoke:live\n```\n\nThis checks local status and fetches your own profile/content, prints only pass/fail, and performs no login, ratings, preference updates, or messages. Do not paste session tokens into issues.\n\nMCP Inspector (currently requiring Node 22.19+ or Node 24) can also connect to the built CLI:\n\n```\nnpx @modelcontextprotocol/inspector node /absolute/path/to/hinge-mcp/mcp/dist/cli.js\n```\n\nUse Inspector's UI to discover tools/resources/prompts and inspect schemas. For HTTP, select Streamable HTTP and set your bearer header. The Inspector browser origin must be allowed. See [official Inspector documentation](https://modelcontextprotocol.io/docs/tools/inspector).\n\n| Path | Responsibility | \n|---|---|\n| `mcp/src/server.ts` | Shared feature factory and server instructions | \n| `mcp/src/tools/` | Account auth, reads, writes, search/fetch | \n| `mcp/src/surfaces.ts` | Resources, prompts, completion | \n| `mcp/src/output-schemas.ts` | Stable result shapes | \n| `mcp/src/client.ts` | Account context, queue, cache, session lifecycle | \n| `mcp/src/transport.ts` | Upstream allowlist, cancellation, size limits | \n| `mcp/src/http.ts` ,`oauth.ts` | HTTP front door, CORS, bearer/JWT verification | \n| `mcp/src/storage.ts` | Confined atomic session storage | \n| `mcp/test/` | MCP and subprocess integration/security tests | \n| `sdk/` | Preserved MIT upstream SDK, docs and tests | \n| `scripts/` | Isolated package test and optional live smoke test | \n\n| Symptom | Check | \n|---|---|\n| Host cannot launch | Use Node 22+, an absolute built CLI path, and a reachable Node executable | \n| Invalid JSON on stdio | Launch `node .../cli.js` directly; route wrapper/log output to stderr | \n| Session rejected by Hinge | Local expiry is only a hint; log in again after confirming the account | \n| Email verification cannot finish | Use `caseId` from the most recent OTP result and the matching emailed code | \n| Corrupt/unreadable session | Fix file ownership or move the file aside and log in again; the server fails rather than silently overwriting it | \n| HTTP 401 | Supply bearer header, or check JWT issuer/audience/subject/expiry and OAuth metadata | \n| HTTP 403 | Check Host, Origin, configured public URL, and OAuth scope | \n| HTTP 405 on GET | Expected for stateless Streamable HTTP; configure `/mcp` , not an old`/sse` client | \n| No browser citation for search | Private Hinge records have no verified public URL; the output remains usable as tool data | \n| Empty chat lookup | There may be no existing DM; the read tool intentionally does not create one | \n| Timeout / HTTP 429 | Wait, narrow the request, and verify account state before retrying writes | \n| SDK schema drift | Reproduce a read failure locally, redact private data, and update the SDK adapter and fixtures together | \n\nGit history is preserved through upstream commit [`7f1b425`](https://github.com/wrsrsh/hinge-ts/commit/7f1b425). The SDK was moved into `sdk/`; its original MIT license is retained. This fork's packaging and protocol work are separate subsequent commits. Upstream publishing workflows were removed so this repository cannot publish under the upstream owner's package identity.\n\nImplementation references:\n\n- [MCP specification, 2026-07-28](https://modelcontextprotocol.io/specification/2026-07-28)\n- [MCP tools](https://modelcontextprotocol.io/specification/2026-07-28/server/tools) ,[Streamable HTTP](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http) , and[authorization](https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization)\n- [Official TypeScript SDK v2](https://ts.sdk.modelcontextprotocol.io/v2/) ,[HTTP serving](https://ts.sdk.modelcontextprotocol.io/v2/serving/http.html) , and[legacy compatibility](https://ts.sdk.modelcontextprotocol.io/v2/serving/legacy-clients.html)\n- [Upstream Hinge SDK](https://github.com/wrsrsh/hinge-ts)\n\nBuilt on [wrsrsh/hinge-ts](https://github.com/wrsrsh/hinge-ts). Credit and thanks to the upstream author for the Hinge SDK; its history and MIT attribution are preserved.\n\nLicense: **MIT**, including upstream attribution. There is no npm publishing workflow or hosted service configured by this repository.", "url": "https://wpnews.pro/news/show-hn-hinge-mcp", "canonical_source": "https://github.com/Kuberwastaken/hinge-mcp", "published_at": "2026-09-28 18:41:42+00:00", "updated_at": "2026-09-28 18:49:51.347458+00:00", "lang": "en", "topics": ["agent-protocols", "ai-agents", "developer-tools", "ai-tools"], "entities": ["Hinge", "Model Context Protocol", "hinge-mcp", "Match Group", "Sendbird", "OpenAI", "Anthropic", "Claude Desktop"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-hinge-mcp", "markdown": "https://wpnews.pro/news/show-hn-hinge-mcp.md", "text": "https://wpnews.pro/news/show-hn-hinge-mcp.txt", "jsonld": "https://wpnews.pro/news/show-hn-hinge-mcp.jsonld"}}