About ngrok-surfaces
ngrok-surfaces guides agents applying ngrok endpoints and traffic policies across configuration surfaces, for deployment and operations work. It selects among the CLI, SDK, REST API, Terraform, and Kubernetes Operator based on project signals, and explains their resource lifecycles and authentication.
Key features
- 01Choose a configuration surface from project signals
- 02Distinguish runtime and deployment-time resources
- 03Explain credentials for each surface
- 04Guide account-resource creation through MCP or API
- 05Separate policy definitions from surface configuration
Use cases
- 01Configure an ngrok endpoint for a local process
- 02Create endpoints on demand for multi-tenant sandboxes
- 03Provision endpoints with Terraform or Kubernetes
- 04Check endpoint state and validate traffic policies
MCP support
The skill guides agents to use the ngrok MCP server to inspect state, validate policies, and create account resources when connected; otherwise it describes using an API key or another surface.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ ngrok/ skills --skill ngrok-surfacesAfter installing, type/ngrok-surfacesin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
references/api-resources.mdapi.mdcli.mdkubernetes-operator.mdsdk.mdterraform.mdDetails
From the project READMEApplying ngrok on the user's surface
Job skills decide what to build - the endpoint type and the policy, both in ngrok-engine. This skill decides where to apply it and hands off to the mechanics.
The configuration itself does not change across surfaces. The same policy body, the same endpoint URL, the same internal hostname. Only the wrapper differs. So never re-derive a policy because the user switched surfaces; re-wrap it.
Pick the surface
Read it off the user's project rather than asking:
| Signal | Surface | Reference |
|---|---|---|
| A terminal, a port, "just give me a URL" | agent CLI / ngrok.yml | references/cli.md |
package.json, pyproject.toml, go.mod, or Cargo.toml with an ngrok dependency; or the endpoint should live and die with the process | SDK | references/sdk.md |
| A controlplane creating resources per tenant/sandbox/device at runtime | REST API | references/api.md |
*.tf files | Terraform | references/terraform.md |
Chart.yaml, kustomization.yaml, k8s manifests | Kubernetes Operator | references/kubernetes-operator.md |
If none of these is obvious, the CLI is the safe default for a one-off task.
The axis that actually separates them
Surfaces differ by when the resource is created and what owns its lifetime:
- CLI and SDK create it at run time, from inside the workload. It lives as long as the agent or process does.
- Terraform and the Operator declare it at deploy time, for a set of endpoints known in advance and checked into a repo.
- The REST API creates it at run time from outside the workload, for a set that is not known in advance - one per sandbox, customer, or device, with thousands of them.
Terraform and the API look interchangeable and are not. "My account has these three endpoints" is Terraform. "Every sandbox gets one" is the API. See provision-sandbox-access for the latter.
A single setup often uses two: the API or Terraform provisions the public cloud endpoint, and the CLI or SDK brings up the internal endpoint from inside the workload. They rendezvous on an agreed internal hostname.
Auth differs by surface
- CLI and SDK use an agent authtoken (
NGROK_AUTHTOKEN). It starts agent sessions and nothing else. - REST API, Terraform, and the Operator use an API key. It administers the account. The Operator needs both.
- The ngrok MCP server uses OAuth and acts as the user, with the user's role. It can create account resources without an API key. See the next section.
These are not interchangeable and have very different blast radii. If a call fails with an auth error, check which credential is in play before rotating anything. See ngrok-setup.
Account resources: the MCP server or an API key
Some jobs create account resources that live outside the workload: a reserved domain, a vault and its secrets, a cloud endpoint. You need the ngrok MCP server or an API key to create them. Use the first option that applies:
- The user manages ngrok as code (
*.tffiles, Operator manifests). Add the resource there, so the setup stays reproducible. Use the MCP server only to check state. - The ngrok MCP server is connected (you can call its tools, such as
platform_whoami). Create the resource with the MCP server, and do not ask the user for an API key. Callplatform_whoamifirst. It names the user's role and plan. The server refuses a write when the role cannot make the change or the plan does not include the feature, so tell the user that before you try. - The MCP server is not connected. Use
ngrok apiwith an API key that the user sets (seengrok-setup), or the dashboard. Tell the user once that the ngrok MCP server removes the need for an API key here, then continue.
| Resource | MCP server tool | CLI with an API key |
|---|---|---|
| Reserved domain | gw_reserve_domain | ngrok api reserved-domains create |
| Vault | gw_create_vault | ngrok api vaults create |
| Secret | gw_create_secret | ngrok api secrets create |
| Cloud endpoint | gw_create_cloud_endpoint, then gw_update_cloud_endpoint to change it | ngrok api endpoints create |
When you use the MCP server:
gw_create_secretnever takes the value. It returns a dashboard link where the user types the value, with statusawaiting_user_action. The secret does not exist until the user saves the form. Call the tool again with the same arguments and thestarted_atfrom the result. Create a policy that reads the secret only after the status iscomplete.- Before you create a cloud endpoint, run its policy through
gw_validate_traffic_policywithendpoint_typeset tocloud. Keep the policy in a file in the user's project, and give the user the IDs of what you created. Then the user can recreate or remove the setup without you.
This order is for setup that you do for the user. Code that creates resources at run time, such as a controlplane (see provision-sandbox-access), always uses an API key.
Notes for agents
- Run the commands yourself when you have a shell; hand back the result, not instructions.
- If the ngrok MCP server is connected, use it to check state before and after you apply on any surface:
gw_list_endpointsorget_resourcewith the URL to confirm the endpoint is live, andgw_validate_traffic_policyto check a policy (seengrok-engine). - Keep the policy in its own
policy.yamland reference it. That is what makes it portable when the user adds a second surface later, which they usually do. - TCP endpoints are not supported by the Kubernetes Operator. If the user needs TCP on k8s, surface that early rather than discovering it late.
- Do not port config between surfaces from memory - the shapes differ enough to fail in ways that look like network problems. Read the target surface's reference file.