npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@raytio/mcp-server

v1.17.0

Published

MCP server for secure AI agent access to Raytio user data

Readme

Raytio MCP Server

An MCP (Model Context Protocol) server that enables AI agents to securely request and retrieve user data from the Raytio platform using end-to-end encryption.

Overview

This server exposes Raytio platform capabilities to AI agents via MCP. Tools are organised into domains, and the full catalogue (names, descriptions, parameters) is generated from source at docs/tools.md.

Current domains:

| Domain | Purpose | |---|---| | DSM — Data Sharing & Requests | Request and retrieve end-to-end encrypted user data via Raytio forms and access applications. | | PPM — Project & Program Management | Read and update Raytio work items and activities with semantic status transitions. | | PRM — Party Relationship Management | Manage parties (organisations, groups, and people) that the business entity interacts with. | | WRM — Worker Relationship Management | Manage AI worker identities, model stacks, MCP tool registrations, roles, role memories, and agent run steps/artifacts. |

All user data flowing through DSM is encrypted end-to-end using Raytio's Maxcryptor system (AES-256-GCM + WADEK key wrapping).

Adding MCP server to AI tool

Two install paths:

  • npx (recommended for end users) — no clone, no build; npx downloads the published package from npm and runs it. Credentials come from env vars passed inline, or from a file pointed at by RAYTIO_CONFIG_FILE (see below).
  • Local clone (recommended for contributors) — clone this repo, run npm install && npm run build, and point the MCP client at dist/index.js. Credentials come from config.env colocated with the build.

Recommended setup for npx installs

Keep all the credential env vars in a single file outside your project tree, and have the MCP client only pass RAYTIO_CONFIG_FILE pointing at it. This is shorter than inline -e blocks, keeps creds out of the MCP client's config file, and means rotating a password is a one-file edit instead of re-running claude mcp add.

# 1. Create the file (chmod 600 so only you can read it)
mkdir -p ~/.config/raytio
install -m 600 /dev/null ~/.config/raytio/mcp.env

# 2. Populate it — same keys as config.env.example
cat > ~/.config/raytio/mcp.env <<'EOF'
RAYTIO_API_BASE_URL=https://api.rayt.io
RAYTIO_COGNITO_USER_POOL_ID=us-east-1_xxxxxxxxx
RAYTIO_COGNITO_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
RAYTIO_COGNITO_REGION=us-east-1
[email protected]
RAYTIO_AGENT_PASSWORD=...
RAYTIO_AGENT_ENCRYPTION_PASSWORD=...
RAYTIO_AGENT_CUSTOMER_ID=00000000-0000-0000-0000-000000000000
[email protected]
# Optional: static override for tool domains (see "Tool domain selection" below).
# If unset, domains are resolved dynamically from the user's backend roles.
# RAYTIO_TOOL_DOMAINS=ppm-readonly
EOF

Then register the MCP server, passing only the pointer:

# Claude Code
claude mcp add raytio -s user \
  -e RAYTIO_CONFIG_FILE=$HOME/.config/raytio/mcp.env \
  -- npx -y @raytio/mcp-server
# Codex CLI (~/.codex/config.toml)
[mcp_servers.raytio]
command = "npx"
args = ["-y", "@raytio/mcp-server"]

[mcp_servers.raytio.env]
RAYTIO_CONFIG_FILE = "/home/you/.config/raytio/mcp.env"

For multiple registrations with different credentials (see "Splitting tools" below), use one file per registration: ~/.config/raytio/dsm.env, ~/.config/raytio/ppm.env, etc., each with its own RAYTIO_CONFIG_FILE pointer.

Claude Code

Install via npx

claude mcp add raytio -s user \
  -e RAYTIO_API_BASE_URL=https://api.rayt.io \
  -e RAYTIO_COGNITO_USER_POOL_ID=... \
  -e RAYTIO_COGNITO_CLIENT_ID=... \
  -e RAYTIO_COGNITO_REGION=us-east-1 \
  -e [email protected] \
  -e RAYTIO_AGENT_PASSWORD=... \
  -e RAYTIO_AGENT_ENCRYPTION_PASSWORD=... \
  -e RAYTIO_AGENT_CUSTOMER_ID=00000000-0000-0000-0000-000000000000 \
  -- npx -y @raytio/mcp-server

Install from a local clone

Build first (npm install && npm run build), then register. The server resolves config.env relative to its own install location, so one registration works from every project on your machine:

claude mcp add raytio -s user -- node /absolute/path/to/mcp-server/dist/index.js

Credentials are picked up from config.env in the repo root (copy config.env.example and fill it in).

Shared settings

Verify: claude mcp list. Inside a session: /mcp. Remove: claude mcp remove raytio.

Scopes:

  • -s user — available in every project for the current OS user (recommended for personal use).
  • -s project — writes to .mcp.json in the current repo, committed for teammates. Prefer the npx form at project scope, since absolute paths aren't portable.
  • (default, local) — private to your user, scoped to the current project.

Codex CLI

Codex CLI registers MCP servers via ~/.codex/config.toml.

Install via npx

[mcp_servers.raytio]
command = "npx"
args = ["-y", "@raytio/mcp-server"]

[mcp_servers.raytio.env]
RAYTIO_API_BASE_URL = "https://api.rayt.io"
RAYTIO_COGNITO_USER_POOL_ID = "..."
RAYTIO_COGNITO_CLIENT_ID = "..."
RAYTIO_COGNITO_REGION = "us-east-1"
RAYTIO_AGENT_USERNAME = "[email protected]"
RAYTIO_AGENT_PASSWORD = "..."
RAYTIO_AGENT_ENCRYPTION_PASSWORD = "..."
RAYTIO_AGENT_CUSTOMER_ID = "00000000-0000-0000-0000-000000000000"

Install from a local clone

Build first (npm install && npm run build), then:

[mcp_servers.raytio]
command = "node"
args = ["/absolute/path/to/mcp-server/dist/index.js"]

Credentials are picked up from config.env next to the server install. To override inline, add a [mcp_servers.raytio.env] block as in the npx example.

Restart Codex CLI after editing the config. Inside a session, /mcp lists loaded servers. Remove by deleting the block and restarting.

Tool domain selection

The server decides which tools to expose using the following precedence:

  1. RAYTIO_TOOL_DOMAINS env var (static override) — if set and non-empty, this value is used directly. No backend query is made.
  2. Dynamic role resolution — if RAYTIO_TOOL_DOMAINS is not set, the server queries the authenticated user's roles via fnd_authz_user_groups() at startup and maps them to tool domains automatically.
  3. All domains (fallback) — if the role query fails or returns no recognised roles, every domain is exposed (matching pre-v1.4.0 behaviour).

The server logs which path was taken at startup (to stderr).

How dynamic resolution works

On startup the server calls the backend RPC endpoint fnd_authz_user_groups() with the agent's Cognito credentials. This returns all roles the user holds (direct assignments + inherited via the role hierarchy). The roles are mapped to tool domains:

| Role | Domain | |---|---| | PROJECT_USER | ppm (full read + write) | | PROJECT_ADMINISTRATOR | ppm + wrm (full read + write) | | PROJECT_VIEWER | ppm-readonly + wrm-readonly (read-only subset) | | DATA_SHARING_USER, DATA_SHARING_ADMINISTRATOR | dsm | | WORKER_ADMINISTRATOR | wrm (full read + write) | | WORKER_VIEWER | wrm-readonly (read-only subset) |

If a user has both PROJECT_VIEWER and PROJECT_USER (or PROJECT_ADMINISTRATOR), ppm wins — it is a superset of ppm-readonly.

The backend's row-level security (RLS) remains the authoritative access control layer. Dynamic filtering is a UX optimisation: it keeps the LLM's tool list relevant and prevents wasted calls to endpoints the agent can't access.

Static override with RAYTIO_TOOL_DOMAINS

Set RAYTIO_TOOL_DOMAINS (comma-separated) to bypass dynamic resolution entirely. This is useful when you want to:

  • Give each domain its own credentials (e.g. a DSM agent and a PPM agent), since each registration is a separate process with its own env.
  • Restrict an agent below its actual role (e.g. force ppm-readonly even though the account has PROJECT_USER).
  • Lock in a known domain set regardless of backend role changes.

Available domains (source: src/tools/domains.ts, also listed at the top of docs/tools.md):

| Domain ID | Notes | |---|---| | dsm | Data Sharing & Requests | | ppm | Project & Program Management (full read + write) | | prm | Party Relationship Management | | ppm-readonly | Read-only subset of PPM — no create/update/status transitions | | wrm | Worker Relationship Management (full read + write) | | wrm-readonly | Read-only subset of WRM — no create/update operations |

Example — separate DSM and PPM registrations with different credentials:

claude mcp add raytio-dsm -s user \
  -e RAYTIO_TOOL_DOMAINS=dsm \
  -e [email protected] \
  -e RAYTIO_AGENT_PASSWORD=... \
  -e RAYTIO_AGENT_ENCRYPTION_PASSWORD=... \
  -e RAYTIO_AGENT_CUSTOMER_ID=... \
  -- npx -y @raytio/mcp-server

claude mcp add raytio-ppm -s user \
  -e RAYTIO_TOOL_DOMAINS=ppm \
  -e [email protected] \
  -e RAYTIO_AGENT_PASSWORD=... \
  -e RAYTIO_AGENT_ENCRYPTION_PASSWORD=... \
  -e RAYTIO_AGENT_CUSTOMER_ID=... \
  -- npx -y @raytio/mcp-server

Example — read-only PPM for a separate audit agent:

claude mcp add raytio-ppm-ro -s user \
  -e RAYTIO_TOOL_DOMAINS=ppm-readonly \
  -e [email protected] \
  ...
  -- npx -y @raytio/mcp-server

The same pattern works in Codex CLI by varying RAYTIO_TOOL_DOMAINS and the credential env vars per [mcp_servers.<name>] block.

Prerequisites

All installs need a Raytio account with agent credentials, a customer ID, and Cognito access. Installing from a local clone additionally requires:

  • Node.js 20 or higher (use nvm use.nvmrc pins the version)
  • npm or yarn

Installation (local clone)

Skip this if you registered the server via npx above.

npm install

Configuration

Environment Variables

Copy config.env.example to config.env in the server's root directory and fill in the values below. The server resolves config.env relative to its own install location, so it works regardless of which directory Claude Code (or any other MCP client) launches it from. To point at a different file, set RAYTIO_CONFIG_FILE=/absolute/path/to/creds.env. Real process.env variables always take precedence over anything in the file.

# Raytio API Configuration
RAYTIO_API_BASE_URL=https://api.rayt.io
RAYTIO_COGNITO_USER_POOL_ID=us-east-1_xxxxxxxxx
RAYTIO_COGNITO_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
RAYTIO_COGNITO_REGION=us-east-1

# Agent User Credentials
[email protected]
RAYTIO_AGENT_PASSWORD=your-agent-password
RAYTIO_AGENT_ENCRYPTION_PASSWORD=your-encryption-password
RAYTIO_AGENT_CUSTOMER_ID=00000000-0000-0000-0000-000000000000

# Target User
[email protected]

# Optional: Request Settings
RAYTIO_REQUEST_TIMEOUT_SECONDS=600
RAYTIO_POLL_INTERVAL_SECONDS=5
RAYTIO_REQUEST_EXPIRY_MINUTES=10

See config.env.example for the full template.

Building

npm run build

This compiles TypeScript to JavaScript in the dist/ directory.

Running

Development Mode

npm run dev

Production Mode

npm start

The server runs in stdio mode for MCP communication.

Tools

The full catalogue of exposed tools — names, descriptions, and parameters — is generated from source at docs/tools.md. Regenerate it after adding or changing tools:

npm run docs:tools

Error codes

Tools return structured responses; error codes common across domains:

  • PPM_NOT_FOUND — ID doesn't exist or RLS hides it (PPM only)
  • PPM_VALIDATION — Input failed validation (PPM only)
  • API_ERROR — Network or server error (all tools)

Usage example (DSM)

End-to-end flow: list schemas → create application → create form → send request → poll for the encrypted submission.

const schemas = await list_schemas();

const aa = await create_access_application({
  name: 'Tax Filing Assistant',
  description: 'Collecting tax information',
});

const form = await create_form({
  access_application_id: aa.data.access_application_id,
  system_schemas: ['ss_Right_To_Work', 'ss_Phone_Number'],
  recipient_email: '[email protected]',
});

const request = await send_request({
  access_application_id: aa.data.access_application_id,
  short_link_key: form.data.short_link_key,
  recipient_email: '[email protected]',
  message: 'Please share your information',
  expiry_minutes: 10,
});

let data = null;
while (!data) {
  const result = await poll_and_retrieve({
    request_short_code: request.data.request_short_code,
  });
  if (result.data) data = result.data;
  else await sleep(5000);
}

Architecture

Components

  • Config Management: Zod-validated environment variable loading
  • Authentication: AWS Cognito JWT token management with caching
  • API Client: Axios-based REST client with automatic token refresh
  • Schema Loader: File system-based schema loading and caching
  • Encryption:
    • Maxcryptor: AES-256-GCM with PBKDF2 key derivation
    • WADEK: Wrapped Asymmetric DEK for key sharing
  • Tool Registry: Unified Tool interface with Zod schema validation and zod-to-json-schema conversion
  • DSM Tools: Data request workflow (in src/tools/dsm/)
  • PPM Tools: Work item and activity management (in src/tools/ppm/)
  • PRM Tools: Party relationship management (in src/tools/prm/)
  • WRM Tools: Worker, model, MCP server/tool, role, guardrail, eval scorer, and agent run management (in src/tools/wrm/)
  • MCP Server: Stdio-based server implementing MCP protocol

Security

  • End-to-End Encryption: All data is encrypted with user's password
  • WADEK Key Wrapping: DEKs are wrapped with recipient's password
  • JWT Authentication: Cognito-based authentication with automatic refresh
  • No Plaintext Storage: Encryption passwords never leave the client

Testing

# Run all tests
npm test

# Run tests with UI
npm run test:ui

# Run specific test file
npm test src/tools/list-schemas.test.ts

Development

Project Structure

src/
├── index.ts                          # MCP server entry point (dispatches via registry)
├── config.ts                         # Configuration management
├── raytio/
│   ├── auth.ts                       # Cognito authentication + getCurrentUserId()
│   ├── api-client.ts                 # REST API client (get/post/put/patch/delete + RequestOptions)
│   └── types.ts                      # Auth type definitions
├── crypto/
│   ├── maxcryptor.ts                 # AES-256-GCM encryption
│   └── wadek.ts                      # WADEK key wrapping
├── schemas/
│   └── loader.ts                     # Schema file loader
├── ppm/                              # PPM domain helpers
│   ├── types.ts                      # WorkItem, Activity interfaces
│   ├── projection.ts                 # WORK_ITEM_SELECT, ACTIVITY_SELECT constants
│   └── filters.ts                    # buildPostgrestQuery()
├── prm/                              # PRM domain helpers
│   ├── types.ts                      # Party interfaces
│   └── projection.ts                 # PRM SELECT constants
├── wrm/                              # WRM domain helpers
│   ├── types.ts                      # WRM entity interfaces
│   └── projection.ts                 # WRM SELECT constants
└── tools/
    ├── types.ts                      # ToolResponse + error codes
    ├── registry.ts                   # Tool + ToolContext interfaces
    ├── domains.ts                    # Domain definitions + resolveDomains()
    ├── role-mapping.ts               # Role → domain resolution
    ├── dsm/                          # DSM tools
    │   ├── index.ts
    │   └── ...
    ├── ppm/                          # PPM tools
    │   ├── index.ts
    │   └── ...
    ├── prm/                          # PRM tools
    │   ├── index.ts
    │   └── ...
    └── wrm/                          # WRM tools
        ├── index.ts
        └── ...

Adding New Tools

  1. Create a tool file implementing the Tool interface from src/tools/registry.ts
  2. Add tests in a co-located *.test.ts file
  3. Export from the relevant index.ts (dsm, ppm, or wrm)

Troubleshooting

Authentication Errors

  • Verify Cognito credentials are correct
  • Check user has access to the Raytio API
  • Ensure Cognito user pool ID and client ID match

Decryption Errors

  • Verify encryption password matches user's password
  • Check WADEK was created with correct password
  • Ensure data format matches expected schema

API Errors

  • Check API base URL is correct
  • Verify network connectivity
  • Review error messages in tool responses

Versioning and updates

This server follows semver. The current version is published in package.json and logged at startup.

Keeping your install up to date (local clone):

cd /path/to/mcp-server
git pull
npm install     # if package.json changed
npm run build

Restart any running Claude Code sessions (exit/relaunch, or /mcp → reconnect) to pick up the new dist/. New sessions load the latest build automatically.

The server is published to npm on every merge to main (see .gitlab-ci.yml), so end users can run the latest release with:

npx -y @raytio/mcp-server

or register it in Claude Code / Codex CLI with npx instead of a local path.

Contributing

See AGENTS.md for contributor conventions — especially the requirement to bump package.json version on every branch / MR.

License

MIT

Support

For issues or questions, please open an issue in the repository.