Skip to main content
Glama

Nexxupp MCP Server

NOTE

We've introduced hosted mode: run one Nexxupp MCP server for your whole team with per-user login — no API tokens in chat configs anymore:

  • Easy installation via standard OAuth. Users click Connect, log in with Nexxupp, approve scopes. No need to fiddle with JSON or API tokens.

  • Powerful tools tailored to AI agents across three products: Cortex memory, NWS workspace, and Calendar. Descriptions carry the conventions models need (datetime format, per-user scoping), keeping token consumption low.

We are prioritizing, and actively supporting, hosted mode. Local stdio keeps working for personal use.

This project implements an MCP server for Nexxupp: private memory (Cortex), programmable workspace (NWS), and scheduling (Calendar).


Tools (22)

Prefix

Tools

cortex_*

memory_store, memory_search, turn

nws_*

search, summarize_station, create_task, open_page_for_event, search_blocks, read_database, upsert_rows, create_chart, apply_template_blocks, summarize_database, station_assist, list_stations

calendar_*

list_calendars, list_events, create_event, update_event, delete_event, ai_assist

billing_*

usage (read-only wallet: balance, tier, storage vs quota, turns — check before expensive runs; no purchase tool on purpose)

Conventions the models must follow are in each tool description: datetimes are YYYY-MM-DD HH:MM:SS, memory calls are scoped per end-user id.


Installation

1. Get your credentials

  • Cortex tools need a per-tenant key (cortex_...).

  • NWS + Calendar tools need your Nexxupp login (email + password). The server logs in once and refreshes behind the scenes. Prefer this over a static access token (15-minute life, no refresh).

WARNING

Credentials in an MCP config act as you. Keep them on personal machines — never on shared servers. On shared servers, use hosted mode below.

2. Adding MCP config to your client

Using npm
Cursor & Claude

Add the following to your .cursor/mcp.json or claude_desktop_config.json (MacOS: ~/Library/Application\ Support/Claude/claude_desktop_config.json)

{
  "mcpServers": {
    "nexxupp": {
      "command": "npx",
      "args": ["-y", "@nexxupp/mcp"],
      "env": {
        "NEXXUPP_API_URL": "https://api.nexxupp.com",
        "CORTEX_API_URL": "https://api.cortex.nexxupp.com",
        "CORTEX_API_KEY": "cortex_...",
        "NEXXUPP_EMAIL": "you@example.com",
        "NEXXUPP_PASSWORD": "..."
      }
    }
  }
}

For local development against your own stack, point at localhost:

{
  "mcpServers": {
    "nexxupp-local": {
      "command": "node",
      "args": ["/absolute/path/to/nexxupp/mcp/dist/index.js"],
      "env": {
        "NEXXUPP_API_URL": "http://localhost:8080",
        "CORTEX_API_URL": "http://localhost:8081",
        "CORTEX_API_KEY": "cortex_...",
        "NEXXUPP_EMAIL": "you@example.com",
        "NEXXUPP_PASSWORD": "..."
      }
    }
  }
}
Zed

Add the following to your settings.json

{
  "context_servers": {
    "nexxupp": {
      "command": {
        "path": "npx",
        "args": ["-y", "@nexxupp/mcp"],
        "env": {
          "NEXXUPP_API_URL": "https://api.nexxupp.com",
          "CORTEX_API_URL": "https://api.cortex.nexxupp.com",
          "CORTEX_API_KEY": "cortex_...",
          "NEXXUPP_EMAIL": "you@example.com",
          "NEXXUPP_PASSWORD": "..."
        }
      },
      "settings": {}
    }
  }
}
GitHub Copilot CLI

Use the Copilot CLI to interactively add the MCP server:

/mcp add

Alternatively, create or edit ~/.copilot/mcp-config.json and add:

{
  "mcpServers": {
    "nexxupp": {
      "command": "npx",
      "args": ["-y", "@nexxupp/mcp"],
      "env": {
        "NEXXUPP_API_URL": "https://api.nexxupp.com",
        "CORTEX_API_URL": "https://api.cortex.nexxupp.com",
        "CORTEX_API_KEY": "cortex_...",
        "NEXXUPP_EMAIL": "you@example.com",
        "NEXXUPP_PASSWORD": "..."
      }
    }
  }
}
Using Docker

Build the image locally (no public registry yet):

docker build -t nexxupp-mcp:0.1.0 .

Then add the following to your .cursor/mcp.json or claude_desktop_config.json

{
  "mcpServers": {
    "nexxupp": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "-e", "NEXXUPP_API_URL",
        "-e", "CORTEX_API_URL",
        "-e", "CORTEX_API_KEY",
        "-e", "NEXXUPP_EMAIL",
        "-e", "NEXXUPP_PASSWORD",
        "nexxupp-mcp:0.1.0"
      ],
      "env": {
        "NEXXUPP_API_URL": "https://api.nexxupp.com",
        "CORTEX_API_URL": "https://api.cortex.nexxupp.com",
        "CORTEX_API_KEY": "cortex_...",
        "NEXXUPP_EMAIL": "you@example.com",
        "NEXXUPP_PASSWORD": "..."
      }
    }
  }
}

Transport options

STDIO transport (default)

The default transport uses standard input/output. This is what desktop clients like Claude Desktop and Cursor expect.

# Run with default stdio transport
npx -y @nexxupp/mcp

# Or explicitly specify stdio
npx -y @nexxupp/mcp --transport stdio

Streamable HTTP transport

For web-based applications or bridged setups, run Streamable HTTP:

# Run on port 3100 (default), localhost only
npx -y @nexxupp/mcp --transport http

# Run on a custom port
npx -y @nexxupp/mcp --transport http --port 8080

# Bind to a different host. The default is 127.0.0.1.
npx -y @nexxupp/mcp --transport http --host 0.0.0.0

The server answers at http://127.0.0.1:<port>/mcp. Health at /health, dependency status at /ready, counters at /metrics.

Authentication

Local HTTP mode has no gateway auth and binds localhost by default — keep it that way. For anything shared, use hosted mode:

MCP_MODE=hosted MCP_TRANSPORT=http MCP_PORT=3100 \
MCP_PUBLIC_URL=https://mcp.nexxupp.com npm start

In hosted mode every /mcp request must carry Authorization: Bearer <user access token>. The server validates it against the backend and scopes all nws_* / calendar_* calls to that caller — no token, or a bad token, gets 401 before any tool runs. cortex_* tools additionally accept a per-call apiKey (the caller's own tenant key); never set a global CORTEX_API_KEY on a shared server.

# Example request
curl -H "Authorization: Bearer <user-access-token>" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json, text/event-stream" \
     -d '{"jsonrpc": "2.0", "method": "tools/list", "params": {}, "id": 1}' \
     http://localhost:3100/mcp
Hosted setup (operator checklist)
  1. Deploy the Docker image beside the API with MCP_MODE=hosted and MCP_PUBLIC_URL set to its public URL.

  2. Set backend OAUTH_API_BASE=https://api.nexxupp.com so discovery advertises reachable URLs.

  3. Register one OAuth client per bot via POST /oauth/clients with the bot's redirect URIs and scopes (openid profile email calendar).

  4. Users connect from the bot, approve scopes in the Nexxupp consent screen, and manage grants at GET /oauth/consents / DELETE /oauth/consents/{client_id} (revoking kills the bot's refresh tokens immediately; access tokens expire within ~15 minutes).

  5. Point NEXXUPP_API_URL at production, keep the default 120/min caller quota (or lower it), and alert on /metrics rate_limited spikes — they mean an agent loop is burning someone's wallet.

Examples

  1. Using the following instruction

Remember that Maya prefers oat-milk lattes

AI will call cortex_memory_store with your user id, and the memory comes back versioned as a brick.

  1. Similarly, the following instruction summarizes a whole workspace

Summarize my station, including open tasks and recent pages

AI will call nws_summarize_station (listing stations first if it doesn't know the id), and may follow up with nws_search_blocks for detail.

  1. You may also schedule in plain language

Find us 30 minutes next week for a design review

AI will call calendar_ai_assist, which reads the calendar and returns executable scheduling actions.

Development

Build & test

npm install
npm run build
npm test

npm test runs 14 tests (unit + live transport/auth-matrix tests, tool-surface snapshot, rate-limit checks; no external services required).

Execute

npm start

Testing changes locally in Cursor:

  1. Run npm link from the repository root.

  2. Merge the snippet below into Cursor's mcp.json.

  3. (Cleanup) run npm unlink from the repository root.

{
  "mcpServers": {
    "nexxupp-local-package": {
      "command": "nexxupp-mcp",
      "env": {
        "NEXXUPP_API_URL": "http://localhost:8080",
        "CORTEX_API_URL": "http://localhost:8081",
        "CORTEX_API_KEY": "cortex_...",
        "NEXXUPP_EMAIL": "you@example.com",
        "NEXXUPP_PASSWORD": "..."
      }
    }
  }
}

Publish

npm login
npm publish --access public

Observability

  • Logs: stderr, one line per request (LOG_LEVEL=debug|info|warn|error).

  • GET /ready returns 503 while the backend is unreachable — wire alerts there, not to the container healthcheck (GET /health).

  • Tune with MCP_REQUEST_TIMEOUT_MS (default 60000), MCP_MAX_BODY_BYTES (default 1048576), MCP_UPSTREAM_TIMEOUT_MS (default 20000), MCP_RATE_LIMIT_MAX (default 120) and MCP_RATE_LIMIT_WINDOW_MS (default 60000) — the per-caller tool-call quota (429 + Retry-After when hit, counted as rate_limited in /metrics).

Related MCP server: Taskade MCP Server

License

MIT — see LICENSE.

Available Tools

22 tools
billing_usageA

Check the caller's wallet before expensive runs: credit balance, tier, storage used vs quota, turns used, spend by product. Read-only; it never spends.

Inputs: no named parameters.

calendar_ai_assistB

Ask the calendar AI in plain language: schedule, reschedule, find free time, summarize. It reads the calendar and returns executable actions.

Inputs: message (required), calendarId (required), timezone.

calendar_create_eventC

Create an event on a calendar.

Inputs: endAt (required), title (required), startAt (required), calendarId (required), +5 more.

calendar_delete_eventC

Delete an event by id.

Inputs: eventId (required).

calendar_list_calendarsB

List the calendars the user can access.

Inputs: no named parameters.

calendar_list_eventsB

List events on a calendar in a time range. Optional text search.

Inputs: end (required), start (required), calendarId (required), search.

calendar_update_eventC

Update an event. Only set the fields to change.

Inputs: eventId (required), endAt, title, startAt, +4 more.

cortex_memory_storeA

Store one user memory in Cortex. Returns the versioned brick. Scope every call to the end user's id.

Inputs: userId (required), message (required), apiKey, domain, +1 more.

cortex_turnC

Stateful Cortex turn over a session. Use for multi-step flows that must stay coherent.

Inputs: userId (required), message (required), apiKey, sessionId, +1 more.

nws_apply_template_blocksC

Append template blocks to an NWS page.

Inputs: blocks (required), pageId (required).

nws_create_chartC

Create a chart block on an NWS page from a data source payload.

Inputs: pageId (required), chartType (required), axis, source, +2 more.

nws_create_taskC

Create a task in an NWS station.

Inputs: title (required), stationId (required), dueAt, pageId, +1 more.

nws_list_stationsB

List the NWS stations the user can access.

Inputs: no named parameters.

nws_open_page_for_eventC

Open (or create) the NWS page linked to a calendar event.

Inputs: eventId (required), stationId (required), title, templateSlug.

nws_read_databaseC

Read an NWS database schema plus rows, optionally through a view.

Inputs: databaseId (required), viewId.

nws_search_blocksC

Search page blocks inside NWS stations.

Inputs: query (required), limit, stationId.

nws_station_assistB

Ask the NWS station AI to act: create/update pages, tasks, reminders, invites. Describe the goal in plain language.

Inputs: message (required), stationId (required).

nws_summarize_databaseC

Summarize an NWS database's contents, optionally through a view.

Inputs: databaseId (required), viewId.

nws_summarize_stationC

Summarize everything in an NWS station: pages, tasks, databases.

Inputs: stationId (required).

nws_upsert_rowsA

Create or update NWS database rows. Omit row_id to insert; set it to update. Read the database first for property ids.

Inputs: rows (required), databaseId (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3/5.0

    Scored across 22 tools

    Disambiguation3/5

    Most tools are distinct by prefix and purpose, but nws_station_assist and nws_create_task/calendar_ai_assist vs calendar_create_event overlap—the AI-assist tools can perform the same actions as the explicit CRUD tools, creating ambiguity about which to use for a given operation.

    Naming Consistency4/5

    Names consistently follow prefix_verb_noun (nws_, cortex_, calendar_, billing_) with snake_case throughout, which is predictable and readable. Minor deviation: billing_usage lacks a verb, but overall the convention is well-maintained.

    Tool Count4/5

    22 tools for a multi-domain server (NWS, Cortex, Calendar, billing) is slightly heavy but reasonable given it spans three distinct product areas. Nothing feels gratuitous, though the set could be trimmed by removing redundant AI-assist/CRUD overlaps.

    Completeness4/5

    Coverage is broad and mostly complete: NWS has create/search/summarize/read/upsert plus AI assist; Calendar has full CRUD plus list and AI assist; Cortex has store/search/turn; billing has usage. Minor gaps like calendar delete exists but no explicit NWS delete tool, and Cortex lacks a delete/forget operation.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers