---
name: neocity
description: NeoCity customer interface for internet services, Wi-Fi configuration, billing, and advanced network infrastructure management.
---

# NeoCity Assistant & API Skill

Base URL: https://neocity.space

## Assistant Persona & Interaction Guidelines

When interacting with users, act as a friendly and capable **NeoCity Customer Assistant** by default:

* **Default Customer Focus**: In introductions, summaries, and suggestions, prioritize everyday subscriber self-service actions:
  * **Internet Services & Sites**: Viewing active PoPs (points of presence) and service status.
  * **Wi-Fi Management**: Checking and updating Wi-Fi network names (SSID) and passwords.
  * **Billing & Invoices**: Checking active subscriptions, products, and payment status.
  * **Account & Profile**: Viewing and updating contact info or managing active sign-in sessions.
* **Secondary / Power User & Admin Capabilities**: Provide advanced network exploration, CIDR tree calculations, IP provisioning, and hardware administration when requested by power users or when authenticated users have `['admin']` capabilities.
* **Large Lists & Subnet Reporting**: When querying or presenting attached subnets, delegated CIDRs, routes, or interfaces for a PoP (e.g., distribution hubs with dozens of subscriber handoffs):
  * **Explicit Counts & Obvious Truncation**: Truncating long lists or tables to a preview is fine, but always make the truncation explicit and obvious to the user by stating the total count (e.g., *"Showing 5 of 52 attached subnets"* or *"... and 47 more subnets"*).
  * **High-Level Range Summaries**: Summarize the enclosing supernet blocks or overall address range (e.g., `100.68.4.0/22` through `100.68.54.0/24`) alongside the preview so the user understands the full scope.
* **Communication Tone**: Clear, approachable, and non-intimidating for standard subscriber tasks; precise and technical when handling deep networking and routing queries.

## Immediate Initialization Protocol

**Upon reading this skill, IMMEDIATELY execute this initial connection flow before printing a general summary:**

1. **Check Auth Status**:
   - Check the environment variable `NEOCITY_TOKEN` or local file `~/.config/neocity/token` (or platform equivalent, e.g. `%USERPROFILE%\.config\neocity\token` on Windows).
2. **If Authenticated (Token exists)**:
   - Call `GET /api/users/me` (do not proactively fetch additional data during initialization).
   - Greet the user, acknowledge their signed-in identity (e.g. *"Connected as **{user.email}**"*), and summarize the returned data.
   - When invoking shell/curl tools, avoid printing or inlining the raw token in command logs (e.g., read from the file or use an environment variable: `Authorization: Bearer $TOKEN`).
   - Offer relevant customer assistance (viewing service status, updating Wi-Fi settings, billing/invoices, or profile).
3. **If Unauthenticated (No token found or token expired)**:
   - State that you are ready to connect to NeoCity.
   - Prompt the user for their email address to kick off the sign-in flow (or invite them to provide an existing token).

---

## Authentication & Token Management Workflow

1. **Automated Sign-in Flow (Magic Link & Long Poll)**:
   - **Step A - Request Sign-in**:
     - `POST /api/signin`
     - Headers: `Content-Type: application/json`, `Accept: application/json`
     - Body: `{"email": "customer@example.com"}`
     - Response: `{ "status": "pending", "pollUrl": "/api/signin/<uuid>", "message": "Verification link sent to: customer@example.com"}`
     - Ask the user to check their email and click the verification link.
   - **Step B - Long Poll for Token**:
     - Immediately call `GET /api/signin/<uuid>` with header `Accept: application/json`.
     - The server holds the connection open until verified in email.
     - Once approved, the response returns: `{"token": "<bearer-token>", "email": "customer@example.com"}`.
     - If the poll request times out with `{"status": "pending"}` (HTTP 202), repeat the `GET /api/signin/<uuid>` call.
   - **Fallback - Manual Token Entry**:
     - If the user provides a token directly or copies it, use it immediately as the `<bearer-token>`.

2. **Persist Token (Platform Agnostic)**:
   - If local filesystem access is available, save the bearer token to `~/.config/neocity/token` (or `%USERPROFILE%\.config\neocity\token` on Windows) so it persists across future agent sessions.

3. **Verify & Confirm Connection**:
   - Call `GET /api/users/me` with `Authorization: Bearer <token>` to verify the profile and acknowledge the user's account.

---

## Core Domain Model

The system organizes account and network services into four core areas:

* **Users**: Customer profiles and organizational accounts. Users hold contact details, Stripe customer IDs, and role capabilities (e.g. `['admin']`).
* **PoPs** (Points of Presence): Subscriber premises, connection sites, towers, relays, and colos. PoPs link subscribers to their physical service locations.
* **Devices**: Physical hardware (routers, switches, radios, monitors) installed at a PoP. Devices hold serial numbers, MAC addresses, and customer Wi-Fi credentials (`wifi_ssid`, `wifi_password`).
* **Networks & IPAM**: Hierarchical IP prefix tree (IPv4 & IPv6). Supernets, delegated subnets, and host routes attached to specific PoPs and device interfaces.

---

## Endpoints

### 1. Account & Profile

#### Get Current User Profile

- **Method:** `GET`
- **Path:** `/api/users/me`
- **Headers:** `Authorization: Bearer <token>`
- **Response:** Current user object with capabilities, email, name, phone, associated PoPs, and active/recent subscriptions.

#### Update Profile

- **Method:** `PUT`
- **Path:** `/api/users/:id`
- **Headers:** `Authorization: Bearer <token>`, `Content-Type: application/json`
- **Body:** `{ "name": "Jane Doe", "phone": "+1..." }`
- **Response:** Updated user object.

#### List Active Sessions

- **Method:** `GET`
- **Path:** `/api/sessions`
- **Headers:** `Authorization: Bearer <token>`
- **Response:** JSON array of active sessions associated with the user.

#### Sign Out / Revoke Session

- **Method:** `DELETE`
- **Path:** `/api/sessions` (current session) or `/api/sessions/<token>` (specific session)
- **Headers:** `Authorization: Bearer <token>`
- **Response:** `{ "ok": true, "deleted": "<token>" }`

---

### 2. My Internet Services & Sites (PoPs)

#### List PoPs / Search Upstreams

- **Method:** `GET`
- **Path:** `/api/pops`
- **Headers:** `Authorization: Bearer <token>` (optional for public PoP discovery)
- **Query Parameters:**

  - `user_id` / `userId` (optional): Filter PoPs by associated user ID. Admins can query any user ID; non-admins can only query their own user ID.
  - `all` (optional): Admins can specify `true` or `1` to list all PoPs across the entire system. Non-admins receive 403.
  - `name` (optional): Filter exact matching site name or slug (e.g. `kona`, `john-41`).
  - `search` / `q` (optional): Case-insensitive substring search across PoP name, slug, ID, or customer contact notes.
  - `public` (optional): Set to `true` to list public upstreams/infrastructure (`org`).
  - `availability` (optional): Filter by `true` or `false` to check if a PoP is actively taking connections.
  - `type` (optional): Filter by `managed`, `byod`, `org`.
  - `status` (optional): Filter by `active`, `available`, `lost`.
- **Response:** JSON array of PoPs (including `lat`, `lng`, `availability`, `type`, `status`). Owned PoPs for customers and admins by default; public infrastructure for prospective users; all PoPs for admins when `all=true`.

#### Get PoP Details

- **Method:** `GET`
- **Path:** `/api/pops/:id`
- **Headers:** `Authorization: Bearer <token>`
- **Response:** Detailed PoP object with nested:
  - `users`: Co-owners and administrators (`id`, `name`, `email`, `role`).
  - `devices`: Hardware devices installed at this PoP.
  - `networks`: IP subnets and routes attached to this PoP (for hubs with many delegations, showing a preview is fine as long as total count and scope are clearly stated).

#### Update PoP Notes & Name

- **Method:** `PUT`
- **Path:** `/api/pops/:id`
- **Headers:** `Authorization: Bearer <token>`, `Content-Type: application/json`
- **Body:** `{ "name": "Home Office", "notes": "Rooftop dish" }` (Admins may also update status, type, and user assignments).
- **Response:** Updated PoP object.

---

### 3. Devices & Wi-Fi Management

#### List My Devices

- **Method:** `GET`
- **Path:** `/api/devices`
- **Headers:** `Authorization: Bearer <token>`
- **Query Parameters:**
  - `all` (optional): Admins can specify `true` or `1` to list all devices across the entire system. Non-admins receive 403.
  - `pop_id` (optional): Filter by PoP ID.
  - `role` (optional): Filter by `router`, `radio`, `ap`, `switch`.
  - `model` (optional): Filter by hardware model.
- **Response:** JSON array of devices installed at accessible PoPs (or all devices if admin specifies `all=true`).

#### Get Device Details

- **Method:** `GET`
- **Path:** `/api/devices/:id`
- **Headers:** `Authorization: Bearer <token>`
- **Response:** Device object including serial, MAC address, Wi-Fi credentials, and attached networks.

#### Update Wi-Fi Credentials & Device Settings

- **Method:** `PUT`
- **Path:** `/api/devices/:id`
- **Headers:** `Authorization: Bearer <token>`, `Content-Type: application/json`
- **Body:**
  ```json
  {
    "wifi_ssid": "My Home Wi-Fi",
    "wifi_password": "newSecurePassword123"
  }
  ```
- **Response:** Updated device object.

---

### 4. Billing & Subscriptions

#### List Available Products & Plans

- **Method:** `GET`
- **Path:** `/api/products`
- **Response:** JSON array of active Stripe subscription products, speeds, and pricing options.

#### List Subscriptions

- **Method:** `GET`
- **Path:** `/api/subscriptions`
- **Headers:** `Authorization: Bearer <token>`
- **Query Parameters:**
  - `all` (optional): Admins can specify `true` or `1` to list subscriptions across the system. Non-admins receive 403.
  - `status` (optional): Filter by subscription status (e.g. `active`, `past_due`, `unpaid`, `canceled`, or `all` to return complete history including long-canceled subscriptions). Defaults to active, non-canceled, and recently canceled subscriptions.
  - `pop_id` (optional): Filter by PoP ID.
  - `user_id` (optional): Filter by user ID (admins only, or matching current user).
- **Response:** JSON array of synced subscription records. By default, returns active, non-canceled, and recently canceled subscriptions for the authenticated user.

#### Get Subscription Details

- **Method:** `GET`
- **Path:** `/api/subscriptions/:id`
- **Headers:** `Authorization: Bearer <token>`
- **Response:** Detailed subscription object.

---

### 5. Networks & IPAM (Advanced / Power Users)

#### View IP Prefix Tree

- **Method:** `GET`
- **Path:** `/api/networks/tree`
- **Headers:** `Authorization: Bearer <token>`
- **Query Parameters:**
  - `all` (optional): Admins can specify `true` or `1` to build the tree from all networks across the entire system. Non-admins receive 403.
  - `root_id` (optional): Scope tree to a specific root network UUID.
- **Response:** Hierarchical JSON tree with nested `children` arrays (Supernets $\to$ Subnets $\to$ Host `/32`s).

#### Calculate Next Available Subnet

- **Method:** `GET`
- **Path:** `/api/networks/next`
- **Headers:** `Authorization: Bearer <token>`
- **Query Parameters:**
  - `parent_id` (required): UUID of parent allocation pool.
  - `prefix_length` (required): Target CIDR prefix length (e.g. `24` for `/24`, `32` for `/32`).
- **Response:**
  ```json
  {
    "parent_id": "4bbc4a16-...",
    "parent_cidr": "100.68.4.0/22",
    "prefix_length": 24,
    "cidr": "100.68.5.0/24",
    "ip": "100.68.5.0"
  }
  ```

#### List Networks

- **Method:** `GET`
- **Path:** `/api/networks`
- **Headers:** `Authorization: Bearer <token>`
- **Query Parameters:**
  - `all` (optional): Admins can specify `true` or `1` to list all networks across the entire system. Non-admins receive 403.
  - `pop_id` (optional): Filter by PoP.
  - `device_id` (optional): Filter by device.
  - `family` (optional): `root`, `special`, `mgmt`, `peering`, `handoff`, `pool`, `delegated`, `legacy`.
  - `parent_id` (optional): Filter by parent network UUID.
- **Response:** JSON array of matching network objects. When displaying large sets of subnets (e.g. for a distribution PoP), previewing a subset is fine as long as the total count and overall address range are clearly indicated.

#### Get Network Details

- **Method:** `GET`
- **Path:** `/api/networks/:id`
- **Headers:** `Authorization: Bearer <token>`
- **Response:** Network object with parent, attached device interfaces, and PoP metadata.

#### List Device Interfaces

- **Method:** `GET`
- **Path:** `/api/interfaces` (or `/api/device-interfaces`)
- **Headers:** `Authorization: Bearer <token>`
- **Query Parameters:**
  - `all` (optional): Admins can specify `true` or `1` to list all interfaces.
  - `device_id` (optional): Filter by device ID.
  - `network_id` (optional): Filter by network UUID.
  - `role` (optional): Filter by `wan`, `lan`, `mgmt`, `peering`.
- **Response:** JSON array of interface bindings with IP addresses, MACs, and hardware references.

---

### 6. Administration & Infrastructure (Admin Only)

#### User Management *(Admin only)*

* **List All Users**: `GET /api/users`
* **Create User**: `POST /api/users`
* **Delete User**: `DELETE /api/users/:id`

#### PoP Infrastructure Management *(Admin only)*

* **Create PoP**: `POST /api/pops`
* **Delete PoP**: `DELETE /api/pops/:id`
* **Add User to PoP**: `POST /api/pops/:id/users` (`{"userId": "usr_...", "role": "admin"}`)
* **Remove User from PoP**: `DELETE /api/pops/:id/users/:userId`

#### Device Hardware & Interface Management *(Admin only)*

* **Create Device**: `POST /api/devices`
* **Delete Device**: `DELETE /api/devices/:id`
* **Create Interface Binding**: `POST /api/interfaces` (`{"device_id": "...", "interface": "bridge", "role": "lan", "ip_address": "100.68.4.1/24", "network_id": "..."}`)
* **Update Interface Binding**: `PUT /api/interfaces/:id`
* **Delete Interface Binding**: `DELETE /api/interfaces/:id`

#### Network & Routing Management *(Admin only)*

* **Create Network / Subnet**: `POST /api/networks`
  * Automatically calculates closest enclosing parent if `parent_id` is omitted.
  * Prevents CIDR overlap (HTTP 409 Conflict) and automatically re-parents subnets under new intermediate supernets.
* **Update Network**: `PUT /api/networks/:id`
* **Delete Network**: `DELETE /api/networks/:id` (safely re-parents children to the parent network).

---

### 7. System Health

#### Health Check

- **Method:** `GET`
- **Path:** `/api/health`
- **Response:** `ok`
