Your team's knowledge, always available.
Skynest brings Context Nest to the cloud — a hosted MCP server your whole team can connect to from any AI tool, anywhere, without running anything locally.
Context Nest (by PromptOwl) is a structured knowledge vault for AI tools. Rather than dumping raw files at an AI, it organizes information as interconnected documents — nodes with graph relationships, pack bundles, semantic indexing, and full version history — purpose-built for AI consumption. Teams use it to share meeting notes, project decisions, architectural context, and reference documentation directly with Claude, Cursor, and other AI tools through the Model Context Protocol (MCP).
The original Context Nest runs as a local stdio MCP server with vault files on your filesystem. That means it only works when your machine is on and the server process is running. Sharing the vault via OneDrive or Dropbox can extend access to teammates, but requires every person to have the right drive mapped and synced — and there's no built-in multi-user story. Writes from different people can conflict silently, and nothing links a document change to the person who made it.
Skynest adapts Context Nest for serverless cloud deployment on Vercel. It replaces the local filesystem with Vercel Blob — durable, globally accessible object storage — so vault documents are always available without any local process running. Authentication is handled by GitHub OAuth 2.1: every team member signs in with their own GitHub account, and every write is committed to a private GitHub repository under that user's identity. You get a complete, accurate audit trail of who wrote what and when, using real git commits — not a synthetic log.
All 19 Context Nest MCP tools — read_document, search, create_document, update_document, read_version, integrity checks, and more — are exposed over HTTPS. Connect once from Claude Code, Cursor, or any MCP-compatible AI tool, and your team's entire knowledge vault is immediately accessible from any machine, any time.
Skynest is built on the open-source Context Nest engine by PromptOwl (AGPL-3.0). The vault storage layer has been adapted to run on Vercel's serverless infrastructure, with GitHub OAuth and Vercel Blob replacing the local filesystem.
| Always on | Deployed to the Cloud — your vault is reachable over HTTPS 24/7, not just when your computer is open. |
| Multi-user | Every team member signs in with their own GitHub account. Writes are committed with native git attribution. |
| Git-versioned | Every document change is a real commit in a private GitHub repository — full history, diffs, and rollback. |
| read.ai integration | Meeting transcripts are automatically ingested into the vault when a meeting ends — no manual action needed. |
- Sign in with your GitHub account when prompted by your AI tool.
- Skynest authenticates you via OAuth and issues a secure session token.
- Your AI tool can now read, search, create, and update vault documents over MCP.
- Every write is committed to the vault repo under your GitHub identity.
┌──────────────────────────────────────────────────────────────────────┐
│ Skynest — Hosted Context Nest MCP server (Vercel / Next.js) │
│ • Next.js App Router, mcp-handler, /api/mcp route │
│ • GitHub OAuth 2.1 (PKCE + dynamic client registration + RS256 JWT) │
│ • Context Nest engine (vendored fork) used as a library │
│ — StorageProvider interface; BlobStorageProvider on Vercel │
│ • Vault files: Vercel Blob (read/write) + GitHub API (commit/history)│
│ • WRITE tools → Vercel Blob put → GitHub API PUT /contents │
│ (commit attributed to session user's GitHub token) │
│ • /api/webhooks/[apikey]/[vaultId]/readai (read.ai ingest) │
└───────▲──────────────────────────────────────────────┬────────────────┘
│ MCP over HTTPS (GitHub OAuth) │ GitHub API
│ ▼
Claude Code / Cursor / Private git repo
any MCP-compatible tool <owner>/contextnest-vault
(each user's own GitHub (source of truth +
account → attributed commits) full version history)
▲
│ webhook POST (HMAC signed)
read.ai (meeting_end event)
Tech stack: Next.js 15 App Router · TypeScript · pnpm · mcp-handler · @vercel/blob · NextAuth v5 (GitHub provider) · jose (RS256 JWTs) · zod
- A Vercel account
- A GitHub account (for OAuth App registration and vault repo)
pnpm>= 9, Node.js >= 20- An existing Context Nest vault (or a new one initialized with the
ctxCLI)
Push your existing vault to a new private GitHub repository, or create an empty one and initialize it later. This repo (<owner>/contextnest-vault) becomes the source of truth for version history.
# From your local vault directory
bash scripts/init-vault.sh <local-vault-path>Add each team member as a collaborator on the vault repository.
Go to GitHub → Settings → Developer settings → OAuth Apps → New OAuth App and fill in:
| Field | Value |
|---|---|
| Application name | Skynest |
| Homepage URL | https://<your-vercel-app>.vercel.app |
| Authorization callback URL | https://<your-vercel-app>.vercel.app/api/auth/callback/github |
Note the Client ID and Client Secret — you'll need them in the next step.
pnpm oauth:gen-keypairThis outputs OAUTH_PRIVATE_KEY and OAUTH_PUBLIC_KEY values for your environment.
Or deploy via the CLI:
pnpm dlx vercelIn the Vercel project dashboard (Settings → Environment Variables), add the following:
# GitHub OAuth App (for user sign-in)
GITHUB_CLIENT_ID=<your-github-oauth-client-id>
GITHUB_CLIENT_SECRET=<your-github-oauth-client-secret>
# NextAuth
AUTH_SECRET=<random-32-char-string> # openssl rand -base64 32
NEXTAUTH_URL=https://<your-vercel-app>.vercel.app
# OAuth JWT signing (from step 3)
OAUTH_PRIVATE_KEY=<generated-private-key>
OAUTH_PUBLIC_KEY=<generated-public-key>
# Storage backend
CONTEXTNEST_STORAGE=blob
CONTEXTNEST_BLOB_PREFIX=vault # namespace prefix for Blob objects
# Vercel Blob (auto-populated when you connect a Blob store in step 6)
BLOB_READ_WRITE_TOKEN=<vercel-blob-token>
# Vault GitHub sync — single "owner/repo" string
VAULT_REPO=<github-username-or-org>/contextnest-vault
VAULT_BRANCH=main # optional, defaults to main
VAULT_SYNC_PROVIDER=github # 'github' (default) or 'none' to disable
# Authorization — which identity mode gates mcp:read / mcp:write scope
AUTH_PROVIDER=github # 'github' (default) or 'entra'
# Required when AUTH_PROVIDER=github (usually the same repo as VAULT_REPO)
AUTHZ_GITHUB_REPO=<github-username-or-org>/contextnest-vault
# Required when AUTH_PROVIDER=entra — sign-in via Microsoft Entra ID
ENTRA_TENANT_ID=<entra-tenant-id>
ENTRA_CLIENT_ID=<entra-app-client-id>
ENTRA_CLIENT_SECRET=<entra-app-client-secret>
AUTHZ_ENTRA_WRITE_GROUP_ID=<group-id>[,<group-id>...] # members get mcp:read + mcp:write (comma-separated for multiple groups)
AUTHZ_ENTRA_READ_GROUP_ID=<group-id>[,<group-id>...] # members get mcp:read only (comma-separated for multiple groups)
# Optional — also accept tokens issued directly by a trusted Entra tenant
# (e.g. from an MCP client's own on-behalf-of flow), alongside Skynest's own
# self-issued OAuth tokens. Leave both unset to keep today's self-issued-only
# behavior exactly as-is.
MCP_TRUSTED_ISSUER=https://login.microsoftonline.com/<tenant-guid>/v2.0
MCP_TRUSTED_AUDIENCE=api://<skynest-entra-app-id> # from that app registration's "Expose an API" Identifier URI
# read.ai webhook (optional — only needed if using the webhook integration)
WEBHOOK_API_KEY=<secret-key> # included in the webhook URL path
READ_AI_SIGNING_KEY=<hmac-key> # from the read.ai dashboard
BOT_GITHUB_TOKEN=<github-pat> # PAT with repo scope, for bot vault writesIn the Vercel project dashboard, go to Storage → Connect Store and create or attach a Blob store. The BLOB_READ_WRITE_TOKEN will be added automatically.
Trigger a fresh deployment. Visit your Vercel URL — you should see the Skynest home page. The MCP endpoint is live at https://<your-vercel-app>.vercel.app/api/mcp.
- A GitHub account — Skynest uses GitHub OAuth for authentication. You'll be prompted to authorize on first connection.
- Vault access — ask your Skynest admin to add your GitHub username as a collaborator on the vault repository.
Replace YOUR_SKYNEST_URL below with your actual deployment URL.
claude mcp add --transport http skynest https://YOUR_SKYNEST_URL/api/mcpRestart Claude Code. On first use you'll be prompted to sign in with GitHub.
Manual config alternative
Add to ~/.claude/mcp.json:
{
"mcpServers": {
"skynest": {
"type": "http",
"url": "https://YOUR_SKYNEST_URL/api/mcp"
}
}
}- Open Claude Code and go to Settings.
- Navigate to MCP Servers and click Add Server.
- Enter:
Name: skynest Transport: HTTP URL: https://YOUR_SKYNEST_URL/api/mcp - Save and restart. You'll be prompted to sign in with GitHub on first use.
Add to your project's .cursor/mcp.json (or the global Cursor MCP config):
{
"mcpServers": {
"skynest": {
"url": "https://YOUR_SKYNEST_URL/api/mcp",
"transport": "http"
}
}
}Reload Cursor. On first use, a browser window will open for GitHub OAuth sign-in.
Skynest exposes a standard MCP HTTP endpoint with OAuth 2.1. Any tool that supports MCP over HTTP with OAuth 2.1 should work — use https://YOUR_SKYNEST_URL/api/mcp as the endpoint.
Read tools
| Tool | Description |
|---|---|
vault_info |
Get vault identity and configuration summary |
resolve |
Execute a selector query with graph traversal |
read_document |
Read a document by URI or path |
list_documents |
List documents with optional type/status/tag filters |
get_skill |
Render a type: skill node as a skill file for an agent harness |
get_skill_install_manifest |
Files for installing a vault skill locally (the calling agent writes them) |
document_format |
Get the document format spec (call before creating docs) |
read_index |
Return the context.yaml index |
read_pack |
Resolve and return a context pack with documents |
search |
Full-text search with graph traversal |
verify_integrity |
Verify all hash chains |
list_checkpoints |
List recent checkpoints |
read_version |
Read a specific version of a document |
Write tools (each write is committed to the vault repo under your GitHub identity)
| Tool | Description |
|---|---|
create_document |
Create a new document with frontmatter and optional body |
update_document |
Update a document's title, tags, status, or body |
delete_document |
Delete a document and its version history |
publish_document |
Publish a document (bump version, create checkpoint) |
Governance tools
| Tool | Description |
|---|---|
stage_drift_suggestion |
Capture an out-of-band edit as a staged suggestion for review |
list_suggestions |
List all staged suggestions for a document |
approve_suggestion |
Approve a suggestion: apply patch, bump version, archive |
reject_suggestion |
Reject a suggestion: archive without modifying the document |
A vault can carry its own instructions for use. Save a type: skill node — create_document
accepts trigger, tools_required and output_format — and any connected agent can fetch it
and install a local loader in one step.
Designate an entry point in .context/config.yaml so an agent with no prior knowledge can
ask "how do I use this vault?" and get the right node. vault_info reports it.
skills:
bootstrap: nodes/skills/vault-bootstrapInstall it. get_skill_install_manifest returns file contents and intended paths; the
calling agent writes them, because this server is remote and has no filesystem access.
get_skill_install_manifest({ path: "nodes/skills/vault-bootstrap", server_alias: "skynest" })
Two things are worth knowing:
modedefaults toloader. The installed file carries the node'sskill.trigger(as the harnessdescription, which is what decides whether the skill fires) plus an instruction to fetch the procedure at run time — not the procedure itself. A local copy of a procedure drifts the moment the node is updated, and the drift is invisible: the agent keeps working, confidently, from superseded rules.mode: "full"inlines a snapshot for offline use and is a deliberate choice.- Pass
server_alias. The tool prefix is client-side configuration, not a server fact — the same vault ismcp__skynest__*on one machine andmcp__bigearnie-ctx__*on another. It defaults to the vault id. Node bodies should write{{server_alias}},{{vault_id}}and{{node_path}}rather than hardcoding a prefix; those are resolved per caller at render time.
get_skill returns the same node rendered for a harness (claude-code, cursor, codex, or
raw) without the install wrapper.
Skynest can automatically ingest meeting transcripts from read.ai when a meeting ends. Configure the webhook in your read.ai workspace settings:
Webhook URL:
https://YOUR_SKYNEST_URL/api/webhooks/YOUR_WEBHOOK_API_KEY/default/readai
Replace YOUR_WEBHOOK_API_KEY with the value you set in the WEBHOOK_API_KEY environment variable. Replace default with your vault ID if you're using a named vault.
Set the signing key in read.ai to the value you set in READ_AI_SIGNING_KEY.
When a meeting ends, read.ai POSTs the transcript to Skynest, which:
- Verifies the HMAC signature
- Deduplicates by
request_id - Uses Claude Haiku to classify the meeting (client, tags, summary, action items)
- Writes a structured node to
nodes/meetings/YYYY-MM-DD-<slug>.md - Commits the file to the vault repo via the bot GitHub token
# Install dependencies
pnpm install
# Build the vendored engine
pnpm --filter @promptowl/contextnest-engine build
# Copy .env.example and fill in values
cp .env.example .env.local
# Start the dev server
pnpm devThe app runs at http://localhost:3000. The MCP endpoint is at http://localhost:3000/api/mcp.
For local development, set CONTEXTNEST_STORAGE=fs and CONTEXTNEST_VAULT_PATH=/path/to/your/vault to use a local filesystem vault instead of Vercel Blob. Set VAULT_SYNC_PROVIDER=none to disable git sync.
skynest/
├── src/
│ ├── app/
│ │ ├── api/
│ │ │ ├── mcp/route.ts # MCP endpoint (mcp-handler + OAuth middleware)
│ │ │ └── webhooks/[apikey]/[vaultId]/readai/ # read.ai ingest webhook
│ │ ├── oauth/ # OAuth 2.1 authorize/token/register endpoints
│ │ ├── .well-known/ # OAuth metadata + JWKS endpoints
│ │ ├── docs/page.tsx # Documentation
│ │ ├── faq/page.tsx # Connection guide
│ │ └── page.tsx # Home page
│ ├── components/
│ │ ├── home/ # Home page sections
│ │ └── docs/ # Docs page sections
│ └── lib/
│ ├── oauth/ # JWT signing, PKCE, token helpers
│ ├── mcp/
│ │ ├── tools.ts # Tool registration (21 tools)
│ │ └── auth.ts # MCP token validation
│ ├── vault/
│ │ ├── index.ts # createEngine factory
│ │ ├── storage/ # BlobStorageProvider + factory
│ │ └── sync/ # GitVaultSyncProvider + GitHub impl
│ └── webhooks/readai/ # read.ai payload schema, verify, dedup, analyze, document
├── vendor/ # Vendored Context Nest engine (fork of PromptOwl/ContextNest)
├── scripts/ # init-vault.sh, oauth-gen-keypair.ts
├── vercel.json
└── .env.example
The Context Nest engine vendored in this repository is licensed under AGPL-3.0 by PromptOwl. The Skynest host application (everything outside vendor/) is the work of its contributors. By hosting this project you accept the AGPL-3.0 obligations — the source of your modifications must be made available. Commercial licensing is available from PromptOwl if you need to embed or redistribute without AGPL obligations.