Skip to content

Commit 8c8479f

Browse files
authored
feat: publish Claude and NPX AI agent marketplace plugins (#1334)
Signed-off-by: Guillaume Belanger <guillaume.belanger27@gmail.com>
1 parent 8b09dca commit 8c8479f

10 files changed

Lines changed: 411 additions & 111 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "ellanetworks-core",
3+
"owner": {
4+
"name": "Ella Networks",
5+
"email": "contact@ellanetworks.com"
6+
},
7+
"metadata": {
8+
"description": "Official Ella Networks plugins for Claude Code",
9+
"version": "0.2.0"
10+
},
11+
"plugins": [
12+
{
13+
"name": "ella-core",
14+
"description": "Manage and inspect a running Ella Core 5G private mobile network via its REST API. Triggers: subscribers, profiles, slices, policies, data networks, radios, BGP, NAT, routes, PDU sessions, IMSI, S-NSSAI, DNN, 5QI, AMBR, ARP, audit logs, flow reports, data usage on an Ella Core instance.",
15+
"version": "0.2.0",
16+
"source": "./",
17+
"author": {
18+
"name": "Ella Networks",
19+
"email": "contact@ellanetworks.com"
20+
},
21+
"homepage": "https://docs.ellanetworks.com",
22+
"repository": "https://github.com/ellanetworks/core",
23+
"license": "Apache-2.0",
24+
"keywords": ["5g", "mobile-network", "private-5g", "ella-core", "ellanetworks"]
25+
}
26+
]
27+
}

.claude-plugin/plugin.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "ella-core",
3+
"version": "0.2.0",
4+
"description": "Manage and inspect a running Ella Core 5G private mobile network via its REST API.",
5+
"author": {
6+
"name": "Ella Networks",
7+
"email": "contact@ellanetworks.com"
8+
},
9+
"homepage": "https://docs.ellanetworks.com",
10+
"repository": "https://github.com/ellanetworks/core",
11+
"license": "Apache-2.0",
12+
"keywords": ["5g", "mobile-network", "private-5g", "ella-core", "ellanetworks"]
13+
}

.github/skills/ella-core-api/SKILL.md

Lines changed: 0 additions & 110 deletions
This file was deleted.

docs/how_to/ai_agents.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,26 @@ Before using the skill, you need:
1515

1616
## 1. Install the skill
1717

18-
Download [`SKILL.md`](https://raw.githubusercontent.com/ellanetworks/core/main/.github/skills/ella-core-api/SKILL.md) and place it in a skills directory that your AI tool can discover (e.g. `<project>/.agents/skills/ella-core-api/SKILL.md`).
18+
=== "Claude Code"
19+
20+
```
21+
/plugin marketplace add ellanetworks/core
22+
/plugin install ella-core@ellanetworks-core
23+
```
24+
25+
Refresh later with `/plugin marketplace update`.
26+
27+
=== "NPX"
28+
29+
Works with any Skills-aware tool that auto-discovers `.agents/skills/` (Codex, Cursor, Cline, Goose, Amp, OpenCode, …).
30+
31+
```
32+
npx skills add ellanetworks/core
33+
```
34+
35+
=== "Manual"
36+
37+
Copy the [`skills/ella-core/`](https://github.com/ellanetworks/core/tree/main/skills/ella-core) folder into the skills directory your AI tool discovers.
1938

2039
## 2. Prompt the agent
2140

skills/ella-core/SKILL.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
---
2+
name: ella-core
3+
description: >
4+
Manage and inspect a running Ella Core 5G private mobile network via its REST API.
5+
Use when the user asks to provision, update, list, inspect, or delete subscribers,
6+
profiles, slices, policies, data networks, radios, routes, BGP peers, NAT, operators,
7+
or users; or asks about live status, data usage, flow reports, audit logs, AMF/SMF/UPF
8+
state, PDU sessions, gNB connections, IMSIs, S-NSSAIs, DNNs, 5QI, AMBR, ARP, or any
9+
runtime telemetry of an Ella Core instance.
10+
metadata:
11+
version: 0.2.0
12+
author: ellanetworks
13+
---
14+
15+
# Ella Core Skill
16+
17+
Ella Core is a 5G private mobile network packaged as a single Go binary (AMF + SMF + UPF + AUSF). This skill operates a running instance via its REST API.
18+
19+
## Connection
20+
21+
Two values are required:
22+
23+
- **Base URL** — e.g. `http://192.168.1.10:5000`. Read from `ELLA_CORE_URL` if set.
24+
- **API token** — string prefixed with `ellacore_`. Read from `ELLA_CORE_TOKEN` if set.
25+
26+
Ask the user for any value that is not in the environment or earlier in the conversation. Token minting and roles: `references/auth.md`.
27+
28+
Authenticate every request with `Authorization: Bearer $ELLA_CORE_TOKEN`. Exceptions (no auth required): `GET /api/v1/status`, `GET /api/v1/metrics`, `GET /api/v1/openapi.yaml`.
29+
30+
Ella Core typically serves HTTPS with a self-signed certificate. Use `curl -k` (or `--cacert <file>` if the user provides one) for `https://` URLs. Plain HTTP works against `h2c` instances.
31+
32+
## Calling the API
33+
34+
Use `curl -sk` (silent + skip cert verification) and pipe JSON through `jq` (or `python3 -m json.tool`):
35+
36+
```bash
37+
curl -sk -H "Authorization: Bearer $ELLA_CORE_TOKEN" \
38+
"$ELLA_CORE_URL/api/v1/subscribers?per_page=100" | jq
39+
```
40+
41+
**Retrieval-first.** Before calling any endpoint not already used in this session, check `references/examples.md` for a recipe. If the operation isn't covered, fetch the OpenAPI spec — the source of truth, never guess paths or shapes:
42+
43+
```bash
44+
curl -s "$ELLA_CORE_URL/api/v1/openapi.yaml"
45+
```
46+
47+
Fetch once per session and reuse. Don't pre-fetch resource lists unless you need their IDs — aggregate endpoints often return everything in one call.
48+
49+
## Endpoint namespacing
50+
51+
Many resources live under sub-paths — never assume top-level. Common groups:
52+
53+
- `/api/v1/auth/*` — login, logout, refresh, lookup-token
54+
- `/api/v1/networking/*` — data-networks, routes, NAT, BGP, interfaces
55+
- `/api/v1/ran/*` — radios, events
56+
- `/api/v1/logs/audit` — audit logs
57+
- `/api/v1/operator/*` — operator code, ID, home-network-keys, NAS security
58+
- `/api/v1/cluster/*` — HA cluster management
59+
- `/api/v1/subscribers`, `/api/v1/profiles`, `/api/v1/policies`, `/api/v1/slices` — top-level
60+
- `/api/v1/subscriber-usage`, `/api/v1/flow-reports` — top-level
61+
62+
When in doubt, fetch the OpenAPI spec.
63+
64+
## Response envelope
65+
66+
- Success: `{"result": <payload>}`
67+
- Error: `{"error": "message"}`
68+
- Mutation success (201/200): `{"result": {"message": "..."}}`
69+
70+
## Pagination
71+
72+
List endpoints accept `page` (default 1) and `per_page` (default 25, max 100). Responses include `items`, `page`, `per_page`, `total_count`. Use `per_page=100` when iterating to minimize round-trips.
73+
74+
## Mutations and destructive operations
75+
76+
For any `POST`, `PUT`, `PATCH`, or `DELETE`:
77+
78+
1. **Confirm with the user first.** State what will change and ask for explicit approval. Do not chain destructive calls without re-confirming.
79+
2. **List or GET before delete.** Confirm the target exists and show its current state to the user.
80+
3. **Verify prerequisites before create.** Resources follow a strict dependency chain (data network → slice → profile → policy → subscriber). See `references/data-model.md`.
81+
4. **One change at a time.** Don't bundle unrelated mutations. Re-read state after each one to confirm it landed.
82+
83+
## When to load references
84+
85+
| File | Read when |
86+
|------|-----------|
87+
| `references/auth.md` | Setting up tokens, hitting 401/403, reasoning about RBAC |
88+
| `references/data-model.md` | Provisioning new resources or explaining the data model |
89+
| `references/conventions.md` | Questions about IMSI, K/OPc, 5QI, ARP, AMBR, bitrate strings, byte conversion, BGP/NAT specifics |
90+
| `references/examples.md` | Looking for a recipe before fetching the full OpenAPI |
91+
| `references/troubleshooting.md` | A request fails or returns unexpected data |
92+
93+
## External documentation
94+
95+
For non-API guidance, fetch from `https://docs.ellanetworks.com/` — for example `how_to/ai_agents/`, `how_to/backup_and_restore/`, or `reference/`.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Authentication
2+
3+
## Token types
4+
5+
- **JWT session tokens** — issued by `POST /api/v1/auth/login` for browser/UI sessions. Short-lived; refreshed at `POST /api/v1/auth/refresh`. Not appropriate for agents.
6+
- **API tokens** — long-lived, prefixed `ellacore_`. Use these for agents and automation. They inherit the role of the owning user.
7+
8+
Mint API tokens in the UI under **Users → API Tokens**, or via the API:
9+
10+
- `POST /api/v1/users/me/api-tokens` — for the calling user
11+
- `POST /api/v1/users/{email}/api-tokens` — admin-only, for another user (path parameter is the user's **email**, not an ID)
12+
13+
Identify the calling user with `GET /api/v1/users/me`.
14+
15+
## Roles and permissions
16+
17+
Three roles:
18+
19+
| Role | ID | Can |
20+
|------|----|-----|
21+
| Admin | 1 | All endpoints, including user/operator management |
22+
| Read-Only | 2 | Read-only access to all resources |
23+
| Network Manager | 3 | Manage subscribers, profiles, policies, slices, data networks; read all telemetry |
24+
25+
Permissions are strings of the form `<resource>:<action>`, checked per endpoint. A 403 means the token's role lacks the required permission — switch to a higher-privilege token rather than retrying.
26+
27+
Notable privileged permission: `subscriber:read_credentials` (used by `GET /api/v1/subscribers/{imsi}/credentials`) is granted only to Admin and Network Manager.
28+
29+
## Environment variables
30+
31+
The skill expects:
32+
33+
- `ELLA_CORE_URL` — base URL with no trailing slash (e.g. `http://192.168.1.10:5000`)
34+
- `ELLA_CORE_TOKEN` — full API token including the `ellacore_` prefix
35+
36+
If either is unset, ask the user before making any call.
37+
38+
## Unauthenticated endpoints
39+
40+
These do not require a token:
41+
42+
- `GET /api/v1/status` — health and version
43+
- `GET /api/v1/metrics` — Prometheus metrics
44+
- `GET /api/v1/openapi.yaml` — full OpenAPI 3.1 specification
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Field formats and valid values
2+
3+
## Identifiers
4+
5+
- **IMSI** — 15-digit string, e.g. `"999016992280505"`. In `CreateSubscriberParams`, the field is `imsi`. Must start with the operator's MCC+MNC.
6+
- **Permanent key (K)** — 32-character hex string. **Field name in the API is `key`** (not `K`).
7+
- **OPc** — 32-character hex string. **Field name in the API is `opc`** (lowercase). Optional on create — derived from operator code if omitted.
8+
- **Sequence number** — 6-byte hex string. **Field name in the API is `sequenceNumber`** (camelCase, unlike most other fields which are snake_case).
9+
10+
## QoS
11+
12+
- **5QI** — valid values: `5, 6, 7, 8, 9, 69, 70, 79, 80`
13+
- **ARP** — integer, range `1-15`
14+
- **AMBR / session bitrate** — string with unit, e.g. `"50 Mbps"`, `"1 Gbps"`, `"500 Kbps"`
15+
16+
## Dates
17+
18+
- Usage queries — `YYYY-MM-DD`
19+
20+
## Subscriber usage
21+
22+
`GET /api/v1/subscriber-usage` **requires** the `group_by` query parameter (`day` or `subscriber`); omitting it returns 400. Optional: `start`, `end` (defaults: 7 days ago → today), `subscriber` (IMSI filter).
23+
24+
Response is `{"result": [<single-key objects>]}` — each object's key is a date (when `group_by=day`) or an IMSI (when `group_by=subscriber`); the value is a `{uplink_bytes, downlink_bytes, total_bytes}` summary.
25+
26+
## Byte counts and presentation
27+
28+
Usage byte fields are `uplink_bytes`, `downlink_bytes`, `total_bytes` (int64). Convert to binary units before presenting:
29+
30+
- MiB = bytes / 1,048,576
31+
- GiB = bytes / 1,073,741,824
32+
33+
Round to one decimal place with the unit suffix (e.g. `46.2 MiB`, `1.3 GiB`). Verify `uplink_bytes + downlink_bytes == total_bytes` before presenting.
34+
35+
## BGP and NAT
36+
37+
- BGP supports up to **5 peers** (`/api/v1/networking/bgp/peers`).
38+
- BGP global state at `/api/v1/networking/bgp` includes `enabled`, `localAS`, `routerID`, `listenAddress`, and `rejectedPrefixes`.
39+
- NAT status at `/api/v1/networking/nat` returns `{"enabled": bool}`. When NAT is enabled, the BGP speaker runs but does **not** advertise subscriber routes.
40+
41+
## Flow reports
42+
43+
`/api/v1/flow-reports` — filterable by subscriber, protocol, source, and destination. Includes both allowed and dropped flows. `/api/v1/flow-reports/stats` returns top protocols and top destination IPs (no required parameters).

0 commit comments

Comments
 (0)