# Tools Reference

> Reference for every MCP tool the Grovs server exposes: projects, links, campaigns, analytics, and configuration.

Source: https://docs.grovs.io/docs/ai/mcp/tools-reference

Your AI assistant picks these up automatically once connected. This page lists every tool the MCP server exposes, what it takes, and what it returns.

## Account

### get_status

Returns the authenticated user's account info and all their Grovs projects with domains. Call this first to discover available project IDs before using other tools.

**No parameters required.**

**Returns:** User name, email, and a table of projects with instance IDs and domains (production + test). Also surfaces a usage warning when any instance has exceeded its MAU quota without a paid subscription.

---

### get_usage

Get the MAU (monthly active users) usage for a specific instance: current count, limit, quota status, and whether the instance has a paid subscription.

- `instance_id` (string, required): Instance ID from `get_status`.

**Returns:** Current MAU, MAU limit, whether quota is exceeded, and whether the instance has an active paid subscription. When quota is exceeded without a subscription, a warning is appended explaining that deep links are no longer working.

---

## Projects

### create_project

Create a new Grovs project. This provisions a production and test environment with their own domains for deep links.

- `name` (string, required): Project name (e.g. "My App").

**Returns:** Instance ID, URI scheme, and the production and test project IDs.

---

## Links

### create_link

Create a deep link in a project. Only `name` is required; the URL path is auto-generated from the name if you don't supply one. You can also set a title and subtitle for previews, tags for organization, and a data payload that gets passed to the app when the link is opened.

**Required**

- `project_id` (string, required): Project ID from `get_status`.
- `name` (string, required): Link name (also used to generate the URL slug).

**Optional**

- `path` (string, optional): Custom URL slug. Auto-generated from name if omitted.
- `title` (string, optional): Preview title shown when the link is shared.
- `subtitle` (string, optional): Preview subtitle shown when the link is shared.
- `image_url` (string, optional): Preview image URL shown when the link is shared.
- `tags` (string\[], optional): Tags for organizing links.
- `data` (object, optional): JSON payload passed to the app when the link is opened.
- `custom_redirects` (object, optional): Per-platform redirect overrides keyed by `ios`, `android`, and `desktop`. Each platform accepts three forms:
  - **Omit the platform** → open the app if installed, otherwise fall back to the App Store / Play Store (default behavior).
  - **String** (e.g. `{ "ios": "https://example.com" }`) → open the app if installed, otherwise redirect to the given URL.
  - **Object** (e.g. `{ "ios": { "url": "https://example.com", "open_app_if_installed": false } }`) → use the URL directly. Set `open_app_if_installed: false` to skip the app entirely and always redirect to the URL.
- `campaign_id` (number, optional): Campaign ID to add this link to (from `list_campaigns` or `create_campaign`).

**Returns:** Full link details including the generated URL, metadata, and custom redirects.

---

### get_link

Look up a deep link by its URL path slug or full URL. Returns full link details including preview metadata, tags, data payload, and custom redirects.

- `project_id` (string, required): Project ID from `get_status`.
- `path` (string, required): Link path slug (e.g. `summer-sale`) or full URL (e.g. `https://myapp.grovs.link/summer-sale`).

**Returns:** Full link details including name, path, preview metadata, tags, data payload, and custom redirects.

---

### update_link

Update an existing deep link. Only include the fields you want to change.

**Required**

- `project_id` (string, required): Project ID from `get_status`.
- `link_id` (number, required): Numeric link ID from `search_links` or `get_link`.

**Optional**

- `name` (string, optional): New link name.
- `path` (string, optional): New URL path slug.
- `title` (string, optional): Preview title.
- `subtitle` (string, optional): Preview subtitle.
- `image_url` (string, optional): Preview image URL.
- `tags` (string\[], optional): Tags.
- `data` (object, optional): JSON payload for the app.
- `custom_redirects` (object, optional): Per-platform redirect overrides keyed by `ios`, `android`, and `desktop`. Same three forms as `create_link`:
  - **Omit the platform** → app + App Store fallback (default).
  - **String** → app if installed, otherwise the given URL.
  - **Object** with `open_app_if_installed: false` → skip the app, always use the URL.
- `campaign_id` (number, optional): Campaign ID to assign this link to.

**Returns:** Updated link details.

---

### archive_link

Archive (deactivate) a deep link. The link will stop redirecting users. This action cannot be undone.

- `project_id` (string, required): Project ID from `get_status`.
- `link_id` (number, required): Numeric link ID from `search_links` or `get_link`.

**Returns:** The archived link details with `active: false`.

> **Warning:** Archiving a link deactivates it permanently. The link URL will stop redirecting users. This cannot be undone.

---

### search_links

Search or list all deep links in a project. Returns links with their view/open/install metrics. Supports pagination, search by name, and sorting.

**Required**

- `project_id` (string, required): Project ID from `get_status`.

**Optional**

- `page` (number, optional): Page number (default: 1).
- `limit` (number, optional): Results per page (default: 20).
- `search` (string, optional): Search by link name, title, path, or tags.
- `sort_by` (string, optional): Sort by: `name`, `created_at`, `views`, `opens`, `installs`.
- `sort_order` (string, optional): Sort direction: `asc` or `desc`.

**Returns:** A table of links with name, path, views, opens, installs, and active status. Includes pagination metadata.

---

## Campaigns

### create_campaign

Create a campaign to group related deep links. After creating, use `create_link` with `campaign_id` to add links to this campaign.

- `project_id` (string, required): Project ID from `get_status`.
- `name` (string, required): Campaign name.

**Returns:** Campaign ID, name, archived status, and creation date.

---

### list_campaigns

List campaigns with aggregated metrics (views, opens, installs, revenue). Supports pagination, search by name, date range filtering, and sorting.

**Required**

- `project_id` (string, required): Project ID from `get_status`.

**Optional**

- `page` (number, optional): Page number (default: 1).
- `per_page` (number, optional): Results per page (default: 20).
- `term` (string, optional): Search by campaign name.
- `sort_by` (string, optional): Sort by: `name`, `created_at`, `views`, `opens`, `installs`, `revenue`.
- `ascendent` (boolean, optional): Sort ascending (default: false = descending).
- `start_date` (string, optional): Metrics start date (YYYY-MM-DD, default: 30 days ago).
- `end_date` (string, optional): Metrics end date (YYYY-MM-DD, default: today).
- `platform` (string, optional): Filter metrics by platform: `ios`, `android`, `desktop`, `web`.
- `archived` (boolean, optional): Filter by archived status.

**Returns:** A table of campaigns with name, ID, views, opens, installs, revenue, and archived status. Includes pagination metadata.

---

### archive_campaign

Archive a campaign and deactivate all its links. This action cannot be undone.

- `project_id` (string, required): Project ID from `get_status`.
- `campaign_id` (number, required): Campaign ID from `list_campaigns`.

**Returns:** Archived campaign details.

> **Warning:** Archiving a campaign deactivates all links in it. The links will no longer redirect users. This cannot be undone.

---

## Analytics

### get_analytics_overview

Get aggregated analytics for a project: views, opens, installs, new/returning users, revenue. Compares current period vs previous period. Defaults to last 30 days.

**Required**

- `project_id` (string, required): Project ID from `get_status`.

**Optional**

- `start_date` (string, optional): Start date (YYYY-MM-DD), defaults to 30 days ago.
- `end_date` (string, optional): End date (YYYY-MM-DD), defaults to today.
- `platform` (string, optional): Filter by platform: `ios`, `android`, `desktop`, `web`.

**Returns:** Current and previous period metrics including views, opens, installs, app opens, new users, returning users, returning rate, reinstalls, referred users, revenue, units sold, cancellations, ARPU, and ARPPU.

---

### get_link_analytics

Get analytics for a specific link by its path slug or full URL: views, opens, installs, engagement time, referrals. Defaults to last 30 days.

**Required**

- `project_id` (string, required): Project ID from `get_status`.
- `path` (string, required): Link path slug (e.g. `summer-sale`) or full URL (e.g. `https://myapp.grovs.link/summer-sale`).

**Optional**

- `start_date` (string, optional): Start date (YYYY-MM-DD).
- `end_date` (string, optional): End date (YYYY-MM-DD).

**Returns:** Per-link metrics: views, opens, installs, reinstalls, reactivations, app opens, referred users, and average engagement time.

---

### get_top_links

Get the top performing links ranked by views. Returns each link with its view, open, and install counts. Defaults to top 10 over last 30 days.

**Required**

- `project_id` (string, required): Project ID from `get_status`.

**Optional**

- `start_date` (string, optional): Start date (YYYY-MM-DD).
- `end_date` (string, optional): End date (YYYY-MM-DD).
- `platform` (string, optional): Filter by platform: `ios`, `android`, `desktop`, `web`.
- `limit` (number, optional): Number of links to return (default: 10).

**Returns:** A ranked table of links with name, path, views, opens, and installs.

---

## Configuration

### configure_redirects

Set where users land when they open a deep link. You can configure per-platform fallbacks (iOS App Store, Google Play, desktop website) and a global fallback URL for anything not matched.

**Required**

- `project_id` (string, required): Project ID from `get_status`.

**Optional**

- `ios_redirect` (string, optional): iOS redirect URL (e.g. App Store link).
- `android_redirect` (string, optional): Android redirect URL (e.g. Play Store link).
- `desktop_redirect` (string, optional): Desktop fallback URL.
- `web_redirect` (string, optional): Web fallback URL.
- `fallback_url` (string, optional): Global fallback URL for all platforms.

**Returns:** Updated redirect configuration for all platforms.

---

### configure_sdk

Configure platform-specific SDK settings for an instance: iOS bundle ID, Android package name, desktop app URLs. Required if you want links to open the actual app instead of falling back to a URL.

**Required**

- `instance_id` (string, required): Instance ID from `get_status`.

**Optional**

- `ios_bundle_id` (string, optional): iOS bundle identifier (e.g. `com.myapp.ios`).
- `ios_team_id` (string, optional): Apple Developer Team ID.
- `ios_app_store_id` (string, optional): iOS App Store ID.
- `android_package_name` (string, optional): Android package name (e.g. `com.myapp.android`).
- `android_sha256_fingerprints` (string\[], optional): Android SHA256 certificate fingerprints for App Links.
- `desktop_url` (string, optional): Desktop app download URL.

**Returns:** Updated SDK configuration for all platforms.

---

## Security

> **Note:** The MCP server uses **OAuth 2.1 with PKCE (S256)** for all authorization. Tokens are automatically refreshed and can be revoked from **Account Settings → Connected Apps** in the dashboard.

- All tools require authentication. There is no anonymous access
- PKCE is mandatory on every OAuth flow
- Access tokens expire after 1 hour and are auto-refreshed
- Refresh tokens expire after 90 days of inactivity
- Connections can be revoked anytime from the dashboard

For self-hosters: dynamic client registration is open by design (per RFC 7591). A registered `client_id` alone grants no access; users must still authenticate and consent. Registration is rate-limited to 5 per minute per IP. To restrict it further, add IP allowlisting at the reverse proxy level.
