Skip to main content

qURL™ CLI

Securely publish
your local apps and APIs.

One command turns a local app or API into a securely shareable resource. Keep it hidden from public scans. Give a teammate or AI agent a private way in — without a staging server, public DNS, or an inbound port.

Make it available to the people and agents you choose without exposing it to the public internet.

Install, publish, share.

Three steps from a running local app to a private link. No account needed.

  1. Install the CLI

    brew install layervai/tap/qurl

    Did a coding agent already install it? The agent puts qurl in ~/.local/bin. If your shell says qurl: command not found, run export PATH="$HOME/.local/bin:$PATH", and add that line to ~/.zshrc or ~/.bashrc to keep it.

  2. Publish your app

    Start your HTTP app on 127.0.0.1 first. Keep it running, then use a second terminal. Replace 3000 with your app’s port.

    qurl publish http://127.0.0.1:3000

    The command prints your full CRID when the route is ready. Sharing continues in the background while your app and host are running.

    This command publishes a private resource: it opens only for you and the people you allow, and the output says so in its Access: line. This needs qurl 3.4.1 or later (check with qurl --version); an earlier release publishes a public resource unless you add --private. To publish something that anyone who has the CRID can open, add --public.

  3. Send someone a link

    qurl share <CRID>

    Replace <CRID> with the full value printed in step 2, without the brackets. Send the returned link to one person. The CRID names the resource; the link grants access.

    Send it in a direct message, not a public channel: whoever opens it first uses it. Avoid email and apps that preview links, because a scanner that runs the page could use its one opening. Don’t open it yourself to check it, for the same reason.

    Legacy: let people ask you for access with a code (qurl 3.4.1 or later). New shares from a coding agent use email invitations instead. Run qurl requests <CRID> --on, which turns access requests on for the resource you already published, or publish a new one with --allow-requests, and send them https://qurl.link/<CRID>. Each person gets a six-digit code there and gives it to you, and you approve them with qurl approve <CRID> <code>. Approve a code only when it came from the person you mean to let in, over a channel where you know it is them: in person, on a call, or in a conversation you already have with them. The address and the CRID of a private resource are safe to send to anyone.

    What your recipient sees

    A one-time link (when qurl share confirms one-time use)
    They open it in a browser and land on your app, with no install and no LayerV account. It works once and expires on its own. Your app’s own sign-in still applies.
    An email invitation (what a coding agent sends)
    They open the invitation in a browser, see who published the app (marked Not verified), verify their email there, and save a passkey. The email verification code stays in that flow; they never send it to you. Where the page offers Email me an access link, they can use that instead of a passkey.
    Legacy: an access request at https://qurl.link/<CRID>
    Only for resources published with --allow-requests. They press Request access, type a name, save a passkey, and get a six-digit code to give you. Once you approve that code, they press Open anyway.

How it protects

Nothing to find. Nothing to leave open.

Links that expire on their own

You run qurl share to mint a short-lived access link, then send it. Expiry prevents new redemption; an open session has its own lifetime.

No inbound ports

Traffic is outbound only — HTTPS to api.layerv.ai and NHP over UDP 443. No inbound port forwarding is needed. Your network must allow the required outbound traffic.

No staging server to provision

Keep your app running; the CLI serves it in the background. Use qurl stop <CRID> to pause access, qurl start <CRID> to resume, or qurl delete <CRID> to retire the resource.

The demo, without the exposure.

Show work in progress

Let a team member or client click through the branch running on your laptop — without a staging deploy and without a public address for it.

Give an agent a local target

Publish the service on your machine, then hand an AI agent a qURL scoped to that one resource and nothing else.

Hand a contractor one thing

Publish the single API they need and send them a link. They reach that resource under the link and session limits you set, without joining your network.

Protect something already remote

qurl publish also accepts a remote HTTPS URL. It adds an access path through LayerV; the original URL stays reachable unless you restrict it.

Running a production service

Use the CLI daemon beside your service.

The connector runs inside the qURL CLI. Production deployments need:

  • A service manager or container runtime that keeps the daemon running
  • Persistent, restricted device state across restarts
  • Deployment configuration and secure enrollment credentials
CLI deployment reference ↗

For AI agents

Teach your agent qURL with one file.

SKILL.md teaches an agent to publish privately, check access-policy support, send authorized invitations, and open a CRID. Email verification codes stay in the recipient browser. It covers both sides: the publisher and the agent that receives a CRID or link. It also covers exit codes, JSON output, and when to stop and ask you.

  1. Claude Code. Save it to your personal skills folder so every project can use it:
    mkdir -p ~/.claude/skills/qurl && curl -fsSL https://layerv.ai/skills/qurl/SKILL.md -o ~/.claude/skills/qurl/SKILL.md
    For a single repository, save it as .claude/skills/qurl/SKILL.md in that repository instead. Claude loads the skill on its own when a task mentions qURL, a CRID, or a qurl.link link.
  2. Claude apps (claude.ai, Desktop). Put SKILL.md in a folder named qurl, zip the folder, and upload the zip under Settings → Capabilities → Skills.
  3. Other agents. If your agent supports SKILL.md skills, save the file in its skills folder. Otherwise, paste this prompt:
    Read https://layerv.ai/skills/qurl/SKILL.md and follow it whenever we work with qURL, CRIDs, or LayerV links.

No account or API key needed. To update the skill, download it again; the URL always serves the latest version.

FAQs

Does this put my app on the public internet?

No — an app listening on 127.0.0.1 stays off the public internet. The CLI connects outbound to LayerV and opens no inbound port. Close or restrict any separate public route your app already exposes.

What is a CRID?

Your stable handle for the lifetime of a published resource. qurl publish makes a private resource unless you add --public; this needs qurl 3.4.1 or later, and an earlier release makes a public resource unless you add --private. A private resource opens only for your devices and for the people and devices you allow, so its CRID and its address https://qurl.link/<CRID> are safe to send to anyone. A public resource can be opened by anyone who has its CRID at that address, so share that CRID only where you would share the resource itself.

So how does someone actually get in?

From the CLI there are two ways. You run qurl share on the CRID, which mints a short-lived qURL, and you send them that link. They open it in a browser without installing the CLI or creating a LayerV account. The link grants access to its holder; your app’s own sign-in still applies. Or, with the legacy code flow (qurl 3.4.1 or later), you run qurl requests <CRID> --on for the resource you published, or publish a new one with --allow-requests, and send them https://qurl.link/<CRID>. There they press Request access, save a passkey, and get a six-digit code to give you, and you approve them with qurl approve <CRID> <code>. Approve a code only when it came from the person you mean to let in, over a channel where you know it is them (in person, on a call, or in a conversation you already have with them): the name on a request can be typed by anyone, and anyone who has the address can ask. A coding agent with the qURL skill sends named people an email invitation instead: they verify their email in the browser and save a passkey. A public resource needs none of these: anyone who has its CRID opens that address and presses Open anyway. For a download in your own script, run qurl get <CRID> --file <path>. Do not curl the share link: that fetches the browser opening page, not the app content.

Can I open a CRID that someone else published?

Open https://qurl.link/<CRID> in a browser. The page shows who published the resource, and whether LayerV has verified that publisher. The publisher name is a display name. Today LayerV has verified only its own account, so every other publisher is shown as Not verified. If the resource is public, press Open anyway; the button reads Open for a publisher that LayerV has verified. If it is private and takes access requests, press Request access, save a passkey when your device asks, and give the six-digit code on the page to the publisher; when the publisher has approved it, press Open anyway. In a terminal, qurl get <CRID> works on a device that the publisher allowed. And where the deployment offers it, qurl get <CRID> fetches a public resource on any machine with only its CRID: no account and no setup. This needs qurl 3.3.1 or later. When no link is given, the three most common answers are "not found" (exit code 5: the CRID is mistyped, the resource was removed, or it is not open to this machine), "can't give a link right now" (exit code 11: nothing is wrong with the CRID; try again later), and "too many requests" (exit code 9: wait, then try again).

Do I have to open a firewall port?

No. Traffic is outbound only — HTTPS to api.layerv.ai and NHP over UDP 443. No inbound port forwarding is needed; your network must allow the required outbound traffic.

What happens when I stop the command?

qurl publish exits when the route is ready. A background daemon serves the local app while the app and host are running. Use qurl stop <CRID> to stop sharing, or qurl start <CRID> to resume. With --foreground, Ctrl-C stops serving.

Which platforms does it run on?

Local publishing works on macOS, Linux, and Windows. Install the latest release for your operating system and architecture. On Linux, background publishing uses systemd user services; use --foreground when a user service manager is unavailable.

How is this different from a public tunnel?

A public tunnel exposes an endpoint and can protect it with authentication. With LayerV, your local app stays hidden from public scans. You create a private, expiring way in for one resource at a time. A teammate or AI agent can use the app without a public deployment or access to your wider network.

Is the hiding built on a standard?

Yes. qURL builds on OpenNHP, the Network Hiding Protocol specified by the Cloud Security Alliance. The CLI handles the protocol exchange for you. OpenNHP is open source, and its IETF work is an Internet-Draft rather than an adopted IETF standard.

Weighing it against a tunnel? See every way to share localhost, compared, or go head to head with ngrok, Cloudflare quick tunnels, and Tailscale Funnel. Or follow a step-by-step guide.

Publish your first app.

Keep your app on your machine. Give people and agents access on your terms.

Pilot LayerV

Tell us what to protect, and we’ll scope a pilot.

Enterprise starts with a scoped, paid pilot on one application, typically 60 to 90 days, credited in full toward year one if you convert within 60 days. Then an annual package sized to what you protect. Not per seat.