New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

@three-ws/notifications-mcp

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@three-ws/notifications-mcp

Read and manage your three.ws notification inbox from any AI agent — list inbound events (pump/market alerts, sales, purchases, social, IRL, account), mark read, tune the per-category delivery matrix, and register Web Push devices. Account-scoped over the

latest
Source
npmnpm
Version
0.1.4
Version published
Maintainers
1
Created
Source

three.ws

@three-ws/notifications-mcp

Your three.ws notification inbox, delivery preferences, and Web Push devices — from any AI agent.

npm downloads license node MCP Registry three.ws

Install · Quick start · Tools · Authentication · Errors · three.ws

A Model Context Protocol server that gives an AI assistant its own three.ws notification inbox + delivery control over stdio. Read inbound events (pump/market alerts, sales & earnings, purchase receipts, social mentions, IRL interactions, account/security notices), mark them read, tune the per-category → per-channel delivery matrix, and register Web Push devices — all live, all account-scoped.

Why

An agent that trades, sells skills, or stands in the real world generates inbound events around the clock — a coin it launched pumps, a skill it published sells, someone taps its IRL pin. Without an inbox surface, the agent polls a dozen endpoints or misses everything. This server turns the platform's own notification feed into seven MCP tools: the agent reads what happened since it last looked, triages it, and controls exactly which channels (in_app, push, email, telegram) each category of event uses to reach its owner.

Every read and write hits the real three.ws API. The server is authenticated: it carries a three.ws API key (or OAuth access token) as a Bearer credential and resolves the owning account on every call. It signs nothing locally and holds no other secret.

Install

npm install @three-ws/notifications-mcp

Or run with npx (no install):

THREE_WS_API_KEY=sk_live_… npx @three-ws/notifications-mcp

Node 20+. Two runtime dependencies (@modelcontextprotocol/sdk, zod).

Quick start

Claude Code, one line:

claude mcp add notifications -e THREE_WS_API_KEY=sk_live_… -- npx -y @three-ws/notifications-mcp

Claude Desktop / Cursor / any MCP client — add to your MCP config (claude_desktop_config.json, .cursor/mcp.json, .mcp.json):

{
	"mcpServers": {
		"notifications": {
			"command": "npx",
			"args": ["-y", "@three-ws/notifications-mcp"],
			"env": { "THREE_WS_API_KEY": "sk_live_…" }
		}
	}
}

Restart the client and the seven tools appear. Inspect the surface in a GUI:

npx -y @modelcontextprotocol/inspector npx -y @three-ws/notifications-mcp

Then ask in plain language:

Anything new in my inbox? Mark the pump alerts read, and turn off email for social mentions.

Runs list_notificationsmark_readset_preferences.

Tools

ToolKindWhat it does
list_notificationsreadThe inbox, newest first, filterable by type, with an unread_count.
mark_readwriteMark one notification — or every unread one — read. Idempotent.
delete_notificationwrite ⚠️Permanently remove one notification (irreversible).
get_preferencesreadThe per-category → per-channel delivery matrix.
set_preferenceswritePatch which channels deliver each category. Idempotent.
register_push_devicewriteRegister a Web Push device from a browser PushSubscription. Idempotent.
unregister_push_devicewrite ⚠️Remove a Web Push device (tears down delivery to it). Idempotent.

Every tool ships MCP tool annotations: the two reads advertise readOnlyHint: true, and the two ⚠️ tools are flagged destructiveHint: true, so annotation-aware clients prompt before running them.

list_notifications

Read the account's inbox — the inbound-event feed the platform delivers: market/pump alerts, sales & earnings, purchase receipts, social mentions, IRL interactions, and account/security notices. Wraps GET /api/notifications.

ArgTypeRequiredNotes
typestringnoReturn only one notification type (e.g. "pump_alert", "skill_purchased", "referral_earned", "security_alert"). Lower_snake_case, ≤ 40 chars. Omit for all types.
limitnumbernoHow many to return, newest first. 1–50, default 20.

Example call and response (shape illustration — your inbox contents will differ):

// call
{ "type": "pump_alert", "limit": 2 }

// response (example)
{
  "ok": true,
  "type": "pump_alert",
  "unread_count": 5,
  "count": 2,
  "notifications": [
    {
      "id": "5d1c2f0a-9b1e-4c3d-8e7f-000000000001",
      "type": "pump_alert",
      "payload": { "mint": "FeMbDoX7R1Psc4GEcvJdsbNbZA3bfztcyDCatJVJpump", "symbol": "THREE" },
      "read": false,
      "read_at": null,
      "created_at": "2026-07-11T18:04:12.000Z"
    }
  ]
}

read is derived from read_at (null ⇒ unread). unread_count is the total unread across the whole inbox, not just this page.

mark_read

Mark notifications read. Wraps POST /api/notifications/:id/read (one) and POST /api/notifications/read-all (all). Pass exactly one of the two arguments. Marking read only sets read_at — nothing is deleted, and re-running is a no-op.

ArgTypeRequiredNotes
idstring (UUID)one ofA single notification to mark read (from list_notifications).
allbooleanone oftrue ⇒ mark every unread notification read.
// call
{ "all": true }

// response (example)
{ "ok": true, "scope": "all", "marked_read": 5 }

With id, the response is { "ok": true, "scope": "one", "id": "…", "read_at": "…" }.

delete_notification

Permanently remove one notification. Wraps DELETE /api/notifications/:id. Irreversible — prefer mark_read for normal triage. Only a notification the caller owns can be deleted; a missing or already-deleted id returns a not-found error.

ArgTypeRequiredNotes
idstring (UUID)yesThe notification to delete (from list_notifications).
// call
{ "id": "5d1c2f0a-9b1e-4c3d-8e7f-000000000001" }

// response (example)
{ "ok": true, "id": "5d1c2f0a-9b1e-4c3d-8e7f-000000000001", "deleted": true }

get_preferences

Read the resolved delivery matrix — for each category, which channels deliver it. No arguments. Wraps GET /api/notifications/preferences. Read this before set_preferences so you patch from real current state.

// response (example)
{
  "ok": true,
  "categories": [
    { "key": "sales", "label": "Sales & earnings", "description": "…" },
    { "key": "alerts", "label": "Market & pump alerts", "description": "…" }
    /* purchases, social, irl, account … */
  ],
  "channels": ["in_app", "push", "email", "telegram"],
  "prefs": {
    "categories": { "alerts": { "in_app": true, "push": true, "email": false, "telegram": false } },
    "telegram_chat_id": null
  },
  "push": { "subscribed_devices": 1 }
}

The seven categories are sales, purchases, social, irl, alerts, creations, account; the four channels are in_app, push, email, telegram. prefs.categories is the effective matrix with the user's sparse overrides already merged onto platform defaults. A category may also carry lockedChannels: account locks in_app on, so security and withdrawal notices always reach the bell inbox.

set_preferences

Patch the delivery matrix. Wraps PUT /api/notifications/preferences. Provide at least one of the two arguments. Only the category/channel pairs you pass change; unknown keys are dropped server-side; untouched pairs keep their current value. Re-applying the same values is a no-op.

ArgTypeRequiredNotes
categoriesobjectat least oneOuter keys: sales, purchases, social, irl, alerts, creations, account. Inner keys: in_app, push, email, telegram → boolean. account's in_app is locked on and a false for it is ignored.
telegram_chat_idstringat least oneNumeric Telegram chat id to deliver the telegram channel to, or "" to unlink. ≤ 24 chars.
// call — stop emailing social mentions, push pump alerts
{ "categories": { "social": { "email": false }, "alerts": { "push": true } } }

// response (example) — the full resolved matrix after the update
{ "ok": true, "prefs": { "categories": { "social": { "email": false /* … */ } }, "telegram_chat_id": null } }

register_push_device

Register a Web Push device so the account receives push notifications on it. Wraps POST /api/push/subscribe. The subscription argument is exactly what the browser's pushManager.subscribe().toJSON() returns. Push endpoints are globally unique — re-registering the same device upserts (latest owner wins), so this is idempotent. Whether a category actually delivers over push is still governed by set_preferences.

ArgTypeRequiredNotes
subscriptionobjectyes{ endpoint, keys: { p256dh, auth } }endpoint is the push-service URL (≤ 2048 chars); p256dh/auth are the base64url-encoded keys from the browser.
// call
{
  "subscription": {
    "endpoint": "https://fcm.googleapis.com/fcm/send/exampleSubscriptionId",
    "keys": { "p256dh": "BNcRd…", "auth": "tBHI…" }
  }
}

// response (example)
{ "ok": true, "registered": true, "endpoint": "https://fcm.googleapis.com/fcm/send/exampleSubscriptionId" }

unregister_push_device

Remove a Web Push device so it stops receiving pushes. Wraps DELETE /api/push/subscribe. Provide at least one of the two arguments — the endpoint is what locates the device. Idempotent: removing an endpoint that isn't registered still returns ok. Only push delivery to that device changes; in_app, email, and telegram preferences are untouched.

ArgTypeRequiredNotes
endpointstring (URL)one ofThe push endpoint URL of the device to remove (preferred).
subscriptionobjectone ofAlternatively the full subscription object; its endpoint is used.
// call
{ "endpoint": "https://fcm.googleapis.com/fcm/send/exampleSubscriptionId" }

// response (example)
{ "ok": true, "unregistered": true, "endpoint": "https://fcm.googleapis.com/fcm/send/exampleSubscriptionId" }

Authentication

Every endpoint is account-scoped and returns 401 without a valid credential — this server can never read or change another account.

Set THREE_WS_API_KEY to either:

  • a three.ws API key (sk_live_… / sk_test_…) — create one in your three.ws dashboard, or
  • an OAuth access token for the account.

Both are carried as Authorization: Bearer … on every request. Bearer auth is CSRF-exempt server-side, so writes need no extra token. THREE_WS_TOKEN and THREE_WS_BEARER are accepted aliases. Treat the credential like a password — it grants full read/write over the account's inbox and delivery settings.

Configuration

Env varRequiredDefaultDescription
THREE_WS_API_KEYyesthree.ws API key or OAuth access token (see Authentication). Aliases: THREE_WS_TOKEN, THREE_WS_BEARER.
THREE_WS_BASEnohttps://three.wsAPI base URL. Override only when self-hosting or targeting a preview.
THREE_WS_TIMEOUT_MSno20000Per-request timeout in milliseconds. Must be a positive number.

The credential is checked when a tool runs, not at startup — the server boots and advertises its tool surface without one, so tools/list always works.

Errors

A failed tool call returns an MCP error result (isError: true) whose text is a single JSON object:

// error shape (example)
{ "ok": false, "error": "upstream_error", "message": "Not found", "status": 404, "detail": { /* API body */ } }
errorHTTPMeaningRecovery
missing_credential401No THREE_WS_API_KEY (or alias) configured.Set the env var and restart the client.
validation_error400Bad arguments (e.g. neither id nor all on mark_read).Fix the call — the message says exactly what's missing.
upstream_erroras returnedThe three.ws API rejected the request; status + detail carry the real response (401 bad key, 404 unknown id, 429 rate-limited).Act on status — a 429 is safe to retry after a pause.
timeoutNo response within THREE_WS_TIMEOUT_MS.Retry; raise the timeout if it recurs.
network_errorThe request never reached the API (DNS, offline).Check connectivity / THREE_WS_BASE.

Reads are always safe to retry. The writes are idempotent by design (mark_read, set_preferences, register_push_device, unregister_push_device re-run to the same state) — only delete_notification is not, and a repeat simply returns not-found.

  • @three-ws/brain-mcp — the three.ws multi-provider LLM router over MCP.
  • @three-ws/pumpfun-mcp — free, read-only pump.fun + Solana data (the source of many pump_alert events).
  • @three-ws/irl — the real-world presence layer whose interactions land in the irl category.

Part of the three.ws SDK suite — 3D AI agents, on-chain identity, and agent payments.
Website · Changelog · GitHub

Keywords

mcp

FAQs

Package last updated on 11 Sep 2026

Related posts