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

@kamilio/skylight-calendar-agent

v0.1.4

Published

Unofficial Toolcraft CLI and MCP server for Skylight Calendar

Readme

skylight-calendar-agent

Unofficial Toolcraft CLI and MCP server for Skylight Calendar.

It exposes calendar, task, reward, list, meal, recipe, photo, and profile operations. The most common list workflows have typed commands for creating lists and adding one or many to-do items.

Requirements

  • Node.js 20 or newer
  • A Skylight account or an existing API token

Install

npm install -g @kamilio/skylight-calendar-agent

To install the current checkout globally before publishing it:

npm install
npm run install:global
skylight --version

This builds the project first, then installs the checkout into npm's global prefix. Remove it later with npm uninstall -g @kamilio/skylight-calendar-agent.

For local development:

npm install
npm run build

Configure

The recommended setup uses Skylight's HTTPS OAuth page. The CLI prints the complete URL without opening a local browser, which works well when Hermes is running on another machine:

skylight auth login

Open the printed URL on your phone and sign in directly on app.ourskylight.com. After Skylight redirects to https://ourskylight.com/welcome, copy that complete final URL back to Hermes and have it run:

skylight auth complete --callback-url 'https://ourskylight.com/welcome?code=...&state=...'
skylight auth status
skylight auth logout

Your password stays between your browser and Skylight; it is never sent through Telegram or entered into the remote shell. On macOS, the OAuth credential is encrypted with a random key held in Keychain. On Linux, including typical Hermes hosts, it is stored in ~/.config/skylight-calendar-agent/credentials with directory mode 0700 and file mode 0600. CLI processes automatically refresh the credential before expiry and after an authorization rejection. Remove it with skylight auth logout.

For direct terminal-only setup, the older password flow remains available:

printf '%s\n' "$SKYLIGHT_PASSWORD" | skylight auth login-password --email [email protected] --password-stdin

Environment variables and .env remain available as portable fallbacks:

[email protected]
SKYLIGHT_PASSWORD=your-password
SKYLIGHT_FRAME_ID=1234567

Quote dotenv values that contain # or intentional leading/trailing spaces, for example SKYLIGHT_PASSWORD=" secret#value ".

Instead of email and password, you may set one of:

  • SKYLIGHT_AUTH_HEADER — complete Authorization header value
  • SKYLIGHT_BASIC_TOKEN — base64-encoded Skylight user-id/token pair
  • SKYLIGHT_BEARER_TOKEN — web-app access token

If multiple methods are set, precedence is full auth header, Basic token, Bearer token, the stored OAuth credential, then email/password OAuth login. Environment credentials therefore remain useful for temporary overrides.

An explicitly exported credential method takes precedence over credential methods in .env. When shell credentials are present, SKYLIGHT_API_BASE is also not loaded from .env; export it explicitly if you intentionally use a custom API host. This prevents a stale or untrusted working-directory file from redirecting exported credentials.

profiles update-email uses SKYLIGHT_PASSWORD by default, so the current password does not need to appear in shell history. Pass --password only to override it.

See .env.example for optional API, calendar URL, and timezone settings. Credentials and captured traffic files are ignored by Git and excluded from the npm package.

Lists and to-dos

Create a to-do list:

skylight lists create --label "Weekend"

Create a shopping list:

skylight lists create --label "Hardware Store" --kind shopping --color B6E085

Find the new list ID, then add one or many items:

skylight lists list
skylight lists item-create --list-id LIST_ID --label "Replace air filter"
skylight lists items-create --list-id LIST_ID --labels "Buy filter" "Install filter"

Skylight list items currently expose label, status, section, position, and creation time, but no due-date field. For a dated task, create a chore instead:

skylight tasks chore-create-simple --summary "Replace air filter" --start 2026-07-12

Raw list and item commands remain available as lists create-raw and lists item-create-raw for API fields not yet modeled by this package. Their *Json options accept JSON text in the CLI and native JSON values over MCP/SDK.

MCP

Run the stdio MCP server:

skylight-calendar-mcp

Example MCP client configuration:

{
  "mcpServers": {
    "skylight": {
      "command": "npx",
      "args": ["-y", "--package", "@kamilio/skylight-calendar-agent", "skylight-calendar-mcp"],
      "env": {}
    }
  }
}

If the package is globally installed, set command directly to skylight-calendar-mcp and omit args.

For local stdio MCP servers, the MCP authorization specification uses process-local credentials rather than an MCP HTTP authorization exchange. Complete skylight auth login once before starting Claude; the MCP server then reads and refreshes the same stored Skylight OAuth credential without secrets in .mcp.json.

Streamable HTTP

Run the same Toolcraft MCP tools over Streamable HTTP:

skylight-calendar-mcp-http
# http://127.0.0.1:8787/mcp

Connect the client directly. OAuth discovery opens the Skylight login page automatically, so .mcp.json contains no headers or secrets:

{
  "mcpServers": {
    "skylight-http": {
      "type": "http",
      "url": "http://127.0.0.1:8787/mcp"
    }
  }
}

The HTTP MCP is generated by toolcraft/http and uses tiny-http-mcp-server for Streamable HTTP protocol handling. Browser-based OAuth login is the default: connect a client to http://127.0.0.1:8787/mcp, and the client opens a Skylight email/password page automatically. Security defaults include loopback-only binding, OAuth 2.1 with PKCE, strict Host and Origin validation, bounded request and JSON-RPC batch sizes, bounded sessions and streams, concurrent tool-call limits, idle expiration, and short HTTP timeouts. The unauthenticated /healthz endpoint returns only name, version, and health status.

For a TLS-terminated deployment, bind a non-loopback interface only with an HTTPS canonical URL:

SKYLIGHT_MCP_HTTP_ALLOWED_HOSTS=mcp.example.com \
skylight-calendar-mcp-http \
  --hostname 0.0.0.0 \
  --port 8787 \
  --public-url https://mcp.example.com/mcp

Run this as a foreground process under the deployment platform's process manager. Terminate TLS in a trusted reverse proxy. Plain non-loopback HTTP is rejected. --insecure-no-auth is available only on loopback for isolated debugging and should not be used normally.

The built-in OAuth login page requires no authentication flags. The client discovers the authorization server, opens a browser, and asks for the same email and password used by Skylight:

SKYLIGHT_MCP_HTTP_ALLOWED_HOSTS=mcp.example.com \
skylight-calendar-mcp-http \
  --hostname 0.0.0.0 \
  --port 8787 \
  --public-url https://mcp.example.com/mcp

The password is sent directly to Skylight and is not stored. The resulting Skylight OAuth credential and this server's OAuth grants are kept only in process memory, so clients sign in again after a restart. One running server supports one Skylight account; restart it to switch accounts. The generated signing key is also process-local, which keeps setup automatic but invalidates issued MCP tokens on restart.

Pre-shared token mode remains available by explicitly setting SKYLIGHT_MCP_HTTP_TOKEN; doing so disables the built-in OAuth server. For deployments that already have an authorization service, configure Toolcraft's external JWT verification instead:

The legacy skylight-calendar-mcp-http-headers helper is installed for existing pre-shared-token configurations, but new OAuth setups should connect directly without it.

SKYLIGHT_MCP_HTTP_PUBLIC_URL=https://mcp.example.com/mcp \
SKYLIGHT_MCP_HTTP_ALLOWED_HOSTS=mcp.example.com \
SKYLIGHT_MCP_OAUTH_AUTHORIZATION_SERVERS=https://auth.example.com \
SKYLIGHT_MCP_OAUTH_JWKS_URL=https://auth.example.com/.well-known/jwks.json \
SKYLIGHT_MCP_OAUTH_SCOPES=mcp \
skylight-calendar-mcp-http --hostname 0.0.0.0

OAuth mode publishes RFC 9728 protected-resource metadata, requires JWT access tokens with typ=at+jwt, and validates signature, issuer, audience, expiry, and required scopes. Set SKYLIGHT_MCP_HTTP_TRUST_PROXY=1 only when every request reaches the process through a trusted reverse proxy.

SDK

The package exports a pre-bound SDK factory with typed command names and parameters:

npm install @kamilio/skylight-calendar-agent
import { createSkylightSDK } from "@kamilio/skylight-calendar-agent";

const skylight = createSkylightSDK();
const lists = await skylight.lists.list({});
const created = await skylight.lists.create({ label: "Weekend" });
await skylight.auth.logout({});

The SDK reads the same SKYLIGHT_* variables from process.env and accepts native JSON values for *Json parameters. It does not load .env automatically; load that file in your application before creating the SDK if needed. Response types are unknown because the upstream API is undocumented and may change.

Request failures preserve their structured SkylightRequestError type, which is exported with status, method, and path fields for SDK error handling. SDK error messages are stripped of terminal control characters.

MCP safety

Commands that reveal or mint credentials, OAuth authorization URLs, device activation codes, and signed upload URLs; trigger account emails, exports, migrations, hardware reset/deletion, or hidden-frame state; accept account passwords or share tokens; delete the user account; or transfer frame ownership are intentionally limited to the CLI and SDK. They are not advertised as MCP tools.

The destructive CLI commands profiles user-delete, profiles frame-hide, profiles frame-transfer, profiles device-delete, profiles device-reset, and meals migrate also require --confirm.

Dynamic IDs are encoded as individual URL path segments, and typed commands reject blank names, impossible dates, reversed date ranges, invalid page numbers, empty bulk operations, and non-object payloads where a JSON object is required.

To keep malformed requests bounded, command strings are limited to 8,192 characters and command arrays to 500 items. Native/raw JSON inputs additionally allow at most 500 properties or array items per container, 500-character property names, and 100 nesting levels.

For terminal safety, the human-readable CLI flattens response line breaks/tabs and marks exceptionally large response fields or collections as truncated (500 properties/items, 500-character property names, or 10,000-character strings). These CLI-only layout and size limits do not apply to SDK or MCP responses.

Development

npm run dev:cli -- lists --help
npm run --silent dev:mcp
npm run check

npm run check performs a clean TypeScript build, CLI/MCP/transport smoke tests, and an npm package dry run.

Disclaimer

This project is not affiliated with or endorsed by Skylight. It uses undocumented API endpoints that may change without notice.