Documentation

Sharnix Reference

Sharnix tunnels your local dev server to a public HTTPS URL so anyone can view it — without deploying, port forwarding, or exposing your IP. You control who can access each link, for how long, and whether they can interact with it.

First setup usually takes 10 seconds to 1 minute while the agent installs/authenticates skills. After your agent is set up, future shares are usually ready in seconds.

Overview

The core flow is three objects working together:

  • Agent — the @sharnix/agent process running on your machine. It keeps the tunnel connection alive.
  • Tunnel — the persistent channel between your local port and the relay. Has a stable ID and optional permanent subdomain.
  • Share link — a scoped URL you hand to a viewer. Each link has its own permission level, expiry, and access rules.
localhost:3000  →  @sharnix/agent  →  relay.sharnix.com  →  https://relay.sharnix.com/p/abc123?t=TOKEN

Quick start

The normal foreground CLI flow is:

  1. Start your local app.
  2. Run the Sharnix agent.
  3. Copy the public URL or scan the compact QR code.
  4. Share it with a client, tester, teammate, or phone.
# 1. Start your app
npm run dev

# 2. Share a single-port app
npx @sharnix/agent --port 3000 --share

# 3. Multi-port apps
# Add .sharnix.yaml, then run the agent from that project.

Use --port for single-port apps. Multi-port apps require a .sharnix.yaml manifest so the agent knows which local services belong to the preview.

Platform support

macOSForeground CLI ready. Background service mode is not fully shipped yet.
WindowsForeground CLI ready. Windows service/background mode is currently beta.
LinuxForeground CLI ready. Background service mode is not fully shipped yet.

Share links depend on your local app and the Sharnix agent being online. If either stops, visitors see a paused/offline page and can notify the owner from that page.

Tunnels

A tunnel is a stable WebSocket connection between your local machine and the Sharnix relay. The tunnel ID is derived from a SHA-256 hash of your working directory, so restarting the agent in the same project can produce the same ID and URL.

Once connected, the relay forwards all HTTP requests that arrive at your tunnel URL through the WebSocket to your local server and proxies the response back. Viewers never see your IP address.

Permanent subdomains

By default a tunnel is accessed via its ID (relay.sharnix.com/p/abc123). You can claim a permanent subdomain — my-app.preview.sharnix.com — that stays stable forever, even if the tunnel disconnects and reconnects.

# Via CLI
npx @sharnix/agent --port 3000 --subdomain my-app

# Via MCP
claim_subdomain(tunnel_id, "my-app")

Each subdomain is globally unique across all of Sharnix. Once claimed it belongs to your org permanently.

A share link is a scoped URL that grants a specific level of access to one tunnel. You can create as many links as you want per tunnel — each with different permissions, expiry, and restrictions. Links are independent: revoking one doesn't affect others.

# URL format
https://relay.sharnix.com/p/<tunnelId>?t=<JWT>

# The JWT encodes: tunnelId, linkId, permission, label, expiry

Permissions

Every share link has one of three permission levels:

read-onlyDefault. The relay rewrites response HTML to disable all forms, buttons, and JavaScript write operations. Visitors can browse and read but cannot interact, submit data, or trigger API calls.
fullFully interactive. Visitors can submit forms, click buttons, and make API calls exactly as if they were on your local machine. Use with care — anyone with the link can write to your app.
blockedReturns HTTP 403 immediately. Useful for temporarily suspending a link without revoking it. The link can be un-blocked later by updating its permission.

Expiry & one-time view

Links can be set to expire at a specific date and time. After expiry, the relay returns a 410 Gone response. Links can also be created as one-time view — the link burns after the first successful page load and cannot be visited again.

create_share_link(tunnel_id, "read-only",
  expires_in_hours=48,   // expires in 48 hours from now
  one_time_view=true     // burns after first visit
)

Email restrictions

You can restrict a share link to specific email addresses or entire domains without requiring viewers to log in. When a visitor tries to access a restricted link, they are prompted to enter their email address. If it matches the allowlist, they get a one-time access code via email.

allowed_emails: ["alice@acme.com"]Only alice@acme.com can access the link.
allowed_emails: ["@acme.com"]Anyone with an @acme.com email address can access.
allowed_emails: ["alice@acme.com", "@partner.io"]Alice specifically, plus anyone from partner.io.

This feature is available on all plans. Viewers do not need a Sharnix account.

Require viewer login Pro

When require_auth is enabled, visitors must log in with their Sharnix account before seeing the preview. Unlike email restrictions, this enforces full authentication — the visitor must have (or create) a Sharnix account.

Use this when you need a strong identity guarantee, not just an email gate. You can combine require_auth with allowed_emails to allow only specific accounts.

create_share_link(tunnel_id, "read-only",
  require_auth=true,
  allowed_emails=["@acme.com"]  // optional — restrict to company accounts
)

IP & geo allowlists Team

IP allowlists restrict access to specific IPv4/IPv6 addresses or CIDR ranges. Geo allowlists restrict access to visitors from specific countries (ISO 3166-1 alpha-2 codes). Visitors outside the allowlist receive a 403 response immediately — no explanation is shown.

ip_allowlist: ["203.0.113.0/24"]Only requests from this subnet are allowed.
geo_allowlist: ["US", "GB", "DE"]Only requests from the US, UK, or Germany are allowed.

Auto-suspension

When the @sharnix/agent process disconnects (Ctrl+C, crash, machine sleeps), all active share links for its tunnels are automatically paused within seconds. Visitors see a branded "Preview paused" or offline page — not a connection error — and can notify the owner from that page.

Timeline after reconnect:

  • Agent reconnects → tunnel re-established immediately
  • After 30 seconds of stability → reactivation email sent to org owner (Pro/Team)
  • Owner or agent calls reactivate_link → link goes live again

Pro and Team plans track visits that occur while the link is paused (downtimeVisits in analytics), so you can see demand even when the preview was offline.

Analytics Pro

The get_link_stats MCP tool and GET /api/v1/orgs/:slug/links/:id/stats endpoint return visit analytics for any share link.

totalVisitsTotal HTTP requests that reached the link (including repeated visits from the same person).
uniqueVisitorsDistinct visitors by IP address.
avgDurationMsAverage time between first and last request in a session, in milliseconds.
visitsOverTimeArray of { ts, count } buckets at hourly resolution for the requested period.
topCountriesTop visitor countries by request count (ISO codes).
topReferrersTop HTTP Referer header values.
downtimeVisitsVisits that arrived while the link was paused (Pro/Team only).

The period parameter accepts "1d", "7d", or "30d".

Custom domains Team

Map your own domain (e.g. previews.acme.com) to a tunnel so visitors see your domain instead of relay.sharnix.com. Add a CNAME record pointing to relay.sharnix.com and register the domain in Settings.

Custom domains work with all share link features — permissions, expiry, auth, and analytics apply normally. TLS is provisioned automatically via Let's Encrypt.

CLI reference

Install via npx — no global install required.

# Start a tunnel
npx @sharnix/agent --port 3000

# Tunnel + immediately print a share link and compact QR code
npx @sharnix/agent --port 3000 --share

# First-time setup (local machine)
npx @sharnix/agent setup

# First-time setup (remote/headless — prints URL and exits)
npx @sharnix/agent setup --print-url
--port, -pLocal port to forward. Default: 3000.
--label, -lHuman label for this tunnel, shown in the dashboard.
--nameAgent name used on first-time provisioning. Default: local-dev.
--shareCreate a read-only share link on connect and print the URL and compact QR code.
--subdomainClaim a permanent subdomain on first connect.
SHARNIX_API_KEYYour API key (shx_...). Required.
SHARNIX_URLOverride relay URL. Default: https://relay.sharnix.com

MCP tools

Install the MCP server by running npx @sharnix/agent setup — it writes the config to Claude Desktop, Cursor, and Windsurf automatically. All tools accept an optional org parameter (org slug). If omitted, the first org is used.

list_tunnels(org?)List all tunnels with their live status, IDs, labels, and subdomains.
get_tunnel(tunnel_id, org?)Get full tunnel details including all active share links.
create_share_link(tunnel_id, permission, ...)Create a shareable URL. Returns the URL immediately. See share link options above for all parameters.
revoke_link(link_id, org?)Permanently revoke a link. Visitors immediately see 410 Gone. Cannot be undone.
reactivate_link(link_id, org?)Re-enable a link paused by agent disconnection.
list_suspended_links(org?)List all links currently paused due to agent disconnect.
claim_subdomain(tunnel_id, subdomain, org?)Give a tunnel a permanent URL at subdomain.preview.sharnix.com.
get_link_stats(link_id, period, org?)Visit analytics. period: "1d" | "7d" | "30d". Pro plan required.
list_orgs()List all workspaces the current API key has access to.
list_api_keys()List all API keys on the account (prefix + label only).
create_api_key(label, org?)Create a new API key. Returns the full key — show it to the user immediately.

REST API

All endpoints require Authorization: Bearer shx_... or a session cookie. Base URL: https://relay.sharnix.com

GET /api/v1/orgsList orgs
GET /api/v1/orgs/:slug/tunnelsList tunnels
GET /api/v1/orgs/:slug/tunnels/:idGet tunnel
DELETE /api/v1/orgs/:slug/tunnels/:idDelete tunnel (cascades links)
GET /api/v1/orgs/:slug/tunnels/:id/linksList links for tunnel (masked tokens + state)
POST /api/v1/orgs/:slug/tunnels/:id/linksCreate share link
POST /api/v1/orgs/:slug/tunnels/:id/links/duplicate-checkPreview duplicate policy matches
GET /api/v1/orgs/:slug/linksList all org links (?state= &tunnelId=)
GET /api/v1/orgs/:slug/links/:idLink detail + recent visits/audit
POST /api/v1/orgs/:slug/links/:id/reveal-urlCopy full preview URL (audited)
DELETE /api/v1/orgs/:slug/links/:idRevoke link
DELETE /api/v1/orgs/:slug/links/:id?permanent=1Remove revoked link permanently
POST /api/v1/orgs/:slug/links/:id/reactivateReactivate paused link
GET /api/v1/orgs/:slug/links/:id/diagnosticsLink health checks
GET /api/v1/orgs/:slug/links/:id/stats?period=7dLink analytics (Pro)
GET /api/v1/orgs/:slug/audit?tunnel=:idAudit events (optional tunnel filter)
POST /api/v1/orgs/:slug/subdomainsClaim subdomain
GET /api/v1/me/keysList API keys
POST /api/v1/me/keysCreate API key
DELETE /api/v1/me/keys/:idRevoke API key