---
name: gentic-subscriptions
description: "Give your AI agent your Shopify subscription data. Sync Loop subscriptions, orders, billing attempts, and cancellation reasons into your Brain with bounded, resumable syncs, then analyze them in natural language or with SQL via query_data — all through the Model Context Protocol. Free to sync."
license: MIT
metadata:
  author: gentic
  version: "1.0.0"
---

# Gentic Subscriptions

Connect any AI agent to your Shopify subscriptions. Sync your Loop subscription data — subscriptions, orders, billing attempts, and cancellation reasons — into your organization's Brain, then ask in natural language: 'what's my active subscriber count?', 'why are people cancelling?', 'how much recurring revenue is at risk from failed payments this week?'. Bounded, resumable syncs keep the picture current without re-reading everything.

## When to apply

- User wants to know their active subscriber count, MRR, or recurring-revenue trends.
- User wants to understand churn — why subscribers are cancelling, or the top cancellation reasons.
- User wants to find revenue at risk from failed payments / dunning (billing attempts).
- User wants to sync their Loop subscription data into their Brain for analysis.
- User wants to count or aggregate over subscriptions, orders, billing attempts, or cancellations.
- User wants to feed subscription metrics into a digest, retention flow, or revenue report.

## Tools

| Tool | Description | Cost |
|------|-------------|------|
| `loop_connection_status` | Check whether the calling organization has connected Loop (the Shopify subscriptions app). Returns `{ connected, shop_domain, updated_at }` when connected, or `{ connected: false }` otherwise. Free. Call before loop_sync to give the user actionable guidance when the integration is missing. Never returns the API token. | Free |
| `loop_sync` | Sync subscription data from Loop (the Shopify subscriptions app) into this organization's data backend — READ-ONLY, verbatim, one BOUNDED chunk per call. Uses the org's connected Loop integration (dashboard → Integrations; no API token is passed here). Warehouses four resources into per-org tables: `loop_subscriptions`, `loop_orders`, `loop_billing_attempts`, `loop_cancellation_reasons` (dedupe-upserted on their natural key, so re-syncs refresh rows in place). BOUNDED + RESUMABLE: each call pages the requested resources only until `max_pages_per_run` pages OR `max_seconds_per_run` seconds are reached, then returns `has_more` + `next_cursor: { resource, page_no }`. The recommended flow: call again passing that `next_cursor` back as `cursor` until `has_more` is false — the walk resumes exactly where it stopped. Returns `{ synced: { <resource>: count }, has_more, next_cursor, persisted }`. FREE. | Free |

## Workflow

### 1. Connect Loop once, then sync without credentials

The Subscriptions server sources the Loop connection (the Admin API token) from the org's connected integration (Gentic dashboard → Integrations → Loop). You never pass credentials to the tools — connect once in the dashboard and the server reads the encrypted connection automatically. Call `loop_connection_status` first (it's free) to confirm the org is connected; if it returns `{ connected: false }`, point the user to Integrations → Loop. It never returns the API token.

### 2. Sync subscription data into the Brain with `loop_sync`

`loop_sync` is **free**. It is READ-ONLY and warehouses four resources into per-org tables — `loop_subscriptions`, `loop_orders`, `loop_billing_attempts`, `loop_cancellation_reasons` — dedupe-upserted on their natural key, so a re-sync refreshes existing rows in place rather than duplicating them. Returns `{ synced: { <resource>: count }, has_more, next_cursor, persisted }`.

### 3. Walk the data with bounded, resumable pagination

Each `loop_sync` call is BOUNDED: it pages the requested resources only until `max_pages_per_run` pages OR `max_seconds_per_run` seconds are reached, then returns `has_more` and a `next_cursor: { resource, page_no }`. To finish a large backfill, call again passing that `next_cursor` back as `cursor` until `has_more` is false — the walk resumes exactly where it stopped. Use `resources` to sync only the tables you need and `page_size` to tune batch size.

### 4. Count and aggregate with `query_data`

The subscription tools warehouse data; they don't analyze it. For subscriber counts, MRR, churn rate, cancellation-reason breakdowns, or failed-payment totals, use `query_data` (Gentic Data MCP) over the `loop_subscriptions`, `loop_orders`, `loop_billing_attempts`, and `loop_cancellation_reasons` tables — standard SQL GROUP BY / COUNT / SUM over the synced rows. Sync first (or re-sync incrementally) so the numbers are current.

### 5. Join across your other synced data

Because everything lands in the same per-org Brain, you can join subscription data with what you've synced from other Gentic servers — e.g. correlate cancellation reasons with support tickets (`support_tickets`), or subscriber cohorts with order history. Compose the question across tables with `query_data`.

### 6. Present results clearly

Don't dump raw JSON. Summarize the numbers — active subscribers, MRR, top cancellation reasons, revenue at risk — and cite the counts. After a sync, tell the user how many rows were `persisted` per resource and whether `has_more` is true (i.e. there's more to page through). For recurring checks, re-run `loop_sync` to refresh the tables before querying.

## Notes

- Organization-scoped: the Loop connection comes from the org's connected integration (dashboard → Integrations → Loop). No credential is ever passed to the tools.
- Cost: both `loop_connection_status` and `loop_sync` are **free**. You pay only for analytics you run over the synced data (e.g. `query_data`). Pricing is pulled live from the Gentic MCP manifest.
- `loop_sync` is READ-ONLY — it warehouses Loop data into your Brain and never writes back to Loop.
- Rows are deduped on their natural key: re-syncing refreshes the same row (mutable fields and all) rather than duplicating it.
- Syncs are bounded and resumable: each call stops at `max_pages_per_run` / `max_seconds_per_run` and returns `next_cursor`; pass it back as `cursor` to continue. Loop `has_more` to false to finish a backfill.
- The four tables — `loop_subscriptions`, `loop_orders`, `loop_billing_attempts`, `loop_cancellation_reasons` — are queried with `query_data` for all counts and aggregations.

## Tool details

- `loop_connection_status` — Check whether the calling organization has connected Loop (the Shopify subscriptions app). Returns `{ connected, shop_domain, updated_at }` when connected, or `{ connected: false }` otherwise. Free. Call before loop_sync to give the user actionable guidance when the integration is missing. Never returns the API token.
- `loop_sync` — Sync subscription data from Loop (the Shopify subscriptions app) into this organization's data backend — READ-ONLY, verbatim, one BOUNDED chunk per call. Uses the org's connected Loop integration (dashboard → Integrations; no API token is passed here). Warehouses four resources into per-org tables: `loop_subscriptions`, `loop_orders`, `loop_billing_attempts`, `loop_cancellation_reasons` (dedupe-upserted on their natural key, so re-syncs refresh rows in place). BOUNDED + RESUMABLE: each call pages the requested resources only until `max_pages_per_run` pages OR `max_seconds_per_run` seconds are reached, then returns `has_more` + `next_cursor: { resource, page_no }`. The recommended flow: call again passing that `next_cursor` back as `cursor` until `has_more` is false — the walk resumes exactly where it stopped. Returns `{ synced: { <resource>: count }, has_more, next_cursor, persisted }`. FREE.
  - `resources` (array of string) — Subset of resources to sync this run (in order). Any of: subscriptions, orders, billing_attempts, cancellation_reasons. Omit to sync all four.
  - `page_size` (integer) — Rows per Loop page (1–100, default 50). Loop caps this at 100.
  - `max_pages_per_run` (integer) — Cap on pages fetched this call (default 20, hard max 50). Keeps a single call bounded — page more via next_cursor, never a bigger run.
  - `max_seconds_per_run` (integer) — Wall-clock budget in seconds for this call (default 20, hard max 30). The walk stops after the current page once exceeded; resume with next_cursor.
  - `cursor` — Resume point from a prior call's `next_cursor` — { resource, page_no }. Omit/null to start from the first requested resource at page 1.

---

_This SKILL.md is generated from the live Gentic MCP manifest. Tool names, descriptions, and pricing are always current. Connect Gentic Subscriptions at https://gentic.co/subscriptions._
