@proars/ghost-mcp-server 0.0.0-stage → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example ADDED
@@ -0,0 +1,2 @@
1
+ GHOST_API_URL=https://your-blog.com
2
+ GHOST_ADMIN_API_KEY=your_ghost_admin_api_key_here
package/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are listed here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/).
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [2.1.1] - 2026-11-01
8
+
9
+ ### Changed
10
+
11
+ - README: Claude Code install uses `--scope user`, with steps to check and remove the server, a note on updating, and a warning about running `npx` inside a clone of this repository.
12
+
13
+ ## [2.1.0] - 2026-11-01
14
+
15
+ First release on npm as `@proars/ghost-mcp-server`.
16
+
17
+ ### Added
18
+
19
+ - `delete_member` tool (`DELETE /members/{id}/`). The server now has 59 tools.
20
+ - `ghost-mcp-server` command (`bin` with a shebang), so the package runs with `npx -y @proars/ghost-mcp-server`.
21
+ - GitHub Actions workflow that runs typecheck, build and tests on Node 20 and 22.
22
+ - README warning that destructive tools are available, and an install section for `npx`.
23
+
24
+ ### Changed
25
+
26
+ - `npm start` runs the compiled `dist/index.js` instead of `tsx`.
27
+ - Published files are limited to `dist`, `README.md`, `LICENSE` and `.env.example`.
28
+ - `prepublishOnly` builds the project and runs the tests before every publish.
29
+ - Minimum `@modelcontextprotocol/sdk` raised from `^1.0.0` to `^1.32.0`.
30
+ - README rewritten with a quick start, FAQ and access notes.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 proars
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,196 @@
1
- # Temporary Holding Version
1
+ # Ghost MCP Server: manage Ghost CMS from Claude, Cursor and other AI clients
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![CI](https://github.com/proars/ghost-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/proars/ghost-mcp-server/actions/workflows/ci.yml)
4
+ ![Node.js 20+](https://img.shields.io/badge/node-%3E%3D20-339933?logo=node.js&logoColor=white)
5
+ ![Tools](https://img.shields.io/badge/tools-59-blue)
6
+ ![Routes](https://img.shields.io/badge/Admin%20API%20routes-253-orange)
7
+ ![License: MIT](https://img.shields.io/badge/license-MIT-green)
8
+
9
+ Ghost MCP Server is an open-source [Model Context Protocol](https://modelcontextprotocol.io) server for Ghost CMS, written in TypeScript. It connects an MCP client such as Claude Desktop, Claude Code or Cursor to the Ghost Admin API over stdio. With it, an AI assistant can create and edit posts and pages, set SEO metadata, manage tags, members and newsletters, upload images and themes, and export content.
10
+
11
+ It exposes **59 tools**: 55 dedicated API tools, two shortcuts for SEO and tags, a route search and a generic request tool. The built-in catalog covers **253 Admin API routes** taken from a pinned Ghost source snapshot. What works on your site depends on your credentials, your Ghost version and its feature flags. Routes and sources are listed in [GHOST_API.list](GHOST_API.list).
12
+
13
+ ## Quick start
14
+
15
+ You need Node.js 20 or newer and a Ghost site with Admin API access.
16
+
17
+ 1. In Ghost Admin, open **Settings → Integrations → Add custom integration** and copy the **Admin API Key** (`id:secret`). Do not use the Content API key.
18
+ 2. Add the server to your client configuration. For Claude Desktop or Cursor:
19
+
20
+ ```json
21
+ {
22
+ "mcpServers": {
23
+ "ghost": {
24
+ "command": "npx",
25
+ "args": ["-y", "@proars/ghost-mcp-server"],
26
+ "env": {
27
+ "GHOST_API_URL": "https://your-blog.com",
28
+ "GHOST_ADMIN_API_KEY": "64f1a2b3c4d5e6f7a8b9c0d1:3e5f7a9b1c2d4e6f8a0b2c4d6e8f0a1b3c5d7e9f1a2b4c6d8e0f2a3b5c7d9e1f"
29
+ }
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ The key above is a made-up example in the real format: 24 hex characters, a colon, then 64 hex characters. Replace both values with your own.
36
+
37
+ When you run the server with `npx`, pass the settings through `env` as shown. A `.env` file is read only from a source checkout (see below), or from the path in `GHOST_MCP_ENV_FILE`.
38
+
39
+ 3. Restart the client and ask something like "List my latest posts with their SEO titles."
40
+
41
+ `GHOST_API_URL` is the canonical Admin domain, including any site subdirectory, without `/ghost/api/admin`. For a local site, use an address such as `http://localhost:2368`.
42
+
43
+ Config file locations: Claude Desktop on macOS uses `~/Library/Application Support/Claude/claude_desktop_config.json`. Cursor uses `~/.cursor/mcp.json` or `.cursor/mcp.json` in your project.
44
+
45
+ **Claude Code:**
46
+
47
+ ```bash
48
+ claude mcp add ghost --scope user \
49
+ -e GHOST_API_URL=https://your-blog.com \
50
+ -e GHOST_ADMIN_API_KEY=64f1a2b3c4d5e6f7a8b9c0d1:3e5f7a9b1c2d4e6f8a0b2c4d6e8f0a1b3c5d7e9f1a2b4c6d8e0f2a3b5c7d9e1f \
51
+ -- npx -y @proars/ghost-mcp-server
52
+ ```
53
+
54
+ `--scope user` makes the server available in every folder. Without it, the server is registered only for the folder where you ran the command. Claude Code starts and stops the server itself, so you don't need to keep a terminal open.
55
+
56
+ Check the connection with `claude mcp get ghost`, which should report `Connected`, or type `/mcp` inside a `claude` session. To remove the server, run `claude mcp remove ghost -s user`.
57
+
58
+ **Updating:** `npx` keeps a cached copy and may not fetch a new release right away. To update, run `rm -rf ~/.npm/_npx` and restart your client, or use `@proars/ghost-mcp-server@latest` in the command so npx checks the registry on every start. To stay on one version, pin it, for example `@proars/ghost-mcp-server@2.1.0`. See the [changelog](CHANGELOG.md) for what changed in each release.
59
+
60
+ Don't run `npx` from inside a clone of this repository: npm finds the local `package.json` with the same name and fails with `ghost-mcp-server: command not found`. Run it from any other folder.
61
+
62
+ Any other stdio MCP client can run the same command, `npx -y @proars/ghost-mcp-server`, with the two environment variables.
63
+
64
+ ## Install from source
65
+
66
+ Use this if you want to change the code or run an unpublished version.
67
+
68
+ ```bash
69
+ git clone https://github.com/proars/ghost-mcp-server.git
70
+ cd ghost-mcp-server
71
+ npm install
72
+ npm run build
73
+ cp .env.example .env
74
+ ```
75
+
76
+ Fill in `GHOST_API_URL` and `GHOST_ADMIN_API_KEY` in `.env`, then point the client at the build. Keep `--silent`: npm's startup banner would otherwise end up in the MCP protocol stream on stdout.
77
+
78
+ ```json
79
+ {
80
+ "mcpServers": {
81
+ "ghost": {
82
+ "command": "npm",
83
+ "args": ["--silent", "--prefix", "/ABSOLUTE/PATH/ghost-mcp-server", "start"]
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ The `.env` file in the project root is read regardless of the directory the client starts the server from. Variables that are already set take priority, and if both required variables are set, the file is not read at all. `GHOST_MCP_ENV_FILE` selects a different env file, and `GHOST_MCP_SKIP_DOTENV=1` turns file loading off.
90
+
91
+ ## What can the server do?
92
+
93
+ | Resource | Tools |
94
+ |---|---|
95
+ | Posts | `get_posts`, `get_post`, `get_post_by_slug`, `create_post`, `update_post`, `delete_post`, `copy_post` |
96
+ | Pages | `get_pages`, `get_page`, `get_page_by_slug`, `create_page`, `update_page`, `delete_page`, `copy_page` |
97
+ | Tags | `get_tags`, `get_tag`, `get_tag_by_slug`, `create_tag`, `update_tag`, `delete_tag` |
98
+ | Tiers | `get_tiers`, `get_tier`, `create_tier`, `update_tier` |
99
+ | Newsletters | `get_newsletters`, `get_newsletter`, `create_newsletter`, `update_newsletter` |
100
+ | Offers | `get_offers`, `get_offer`, `create_offer`, `update_offer` |
101
+ | Members | `get_members`, `get_member`, `create_member`, `update_member`, `delete_member` |
102
+ | Labels | `get_labels`, `create_label`, `update_label`, `delete_label` |
103
+ | Staff | `get_users`, `get_user`, `update_user`, `delete_user`, `get_roles`, `invite_user` |
104
+ | Images and themes | `upload_image`, `upload_theme`, `activate_theme` |
105
+ | Webhooks | `create_webhook`, `update_webhook`, `delete_webhook` |
106
+ | Site | `get_site`, `get_settings` |
107
+ | Shortcuts | `update_post_seo`, `update_post_tags` |
108
+ | Discovery and generic calls | `ghost_list_endpoints`, `ghost_api_request` |
109
+
110
+ Ghost has no delete endpoint for tiers, newsletters or offers, so those resources have no `delete_*` tool.
111
+
112
+ > **Warning: this server exposes every supported function, including destructive ones.** `delete_post`, `delete_page`, `delete_tag`, `delete_member`, `delete_user`, `activate_theme`, `upload_theme` and `ghost_api_request` can permanently remove or overwrite content, subscribers and site settings. Deleted records usually cannot be restored. Create a separate integration key for the server, make a backup (Ghost Admin → Settings → Labs → Export) before bulk work, and turn on manual approval for all `update_*`, `delete_*` and generic calls in your client.
113
+
114
+ ### How do I call the tools?
115
+
116
+ - **Create and update:** put the record fields in `data` and pass the record `id` as a separate argument. Post and page updates need `data.updated_at` from a fresh read. The SEO and tag shortcuts take `updated_at` directly.
117
+ - **Lists:** use `limit`, `page`, `filter`, `order`, `include` and `fields`. Posts and pages come back with compact fields and tags by default. Single-record reads return the full record.
118
+ - **Tags:** setting tags replaces the whole set. Tags that don't exist yet are created, and an empty array removes all tags.
119
+ - **Publishing:** call `update_post` with `data.status="published"`, or with `"scheduled"` and a future `data.published_at`. To send the post by email, add `newsletter` (a slug) and, optionally, `email_segment`.
120
+ - **Images:** `upload_image` takes `file_path`, an optional `purpose` (`image`, `profile_image` or `icon`) and `ref`.
121
+
122
+ ### How do I reach routes that have no dedicated tool?
123
+
124
+ Use `ghost_list_endpoints` to search by `group`, `method`, `access` or `search`. Set `without_dedicated_tool=true` to list the other 198 routes. Each entry shows access requirements, feature flags and upload fields.
125
+
126
+ Call any route with `ghost_api_request`. Its `path` is relative to `/ghost/api/admin`, contains real IDs or slugs, and has no query string.
127
+
128
+ ```text
129
+ ghost_api_request method=GET path=/labels/slug/vip/
130
+ ghost_api_request method=POST path=/members/upload/ files={membersfile: "/Users/me/members.csv"}
131
+ ghost_api_request method=GET path=/posts/export/ save_to="/Users/me/posts.csv"
132
+ ```
133
+
134
+ Send JSON payloads in `body`, using the structure Ghost expects. Put query parameters in `query`. Send multipart files as `files={formField: "/absolute/path"}`, with optional text `fields`.
135
+
136
+ For downloads, `save_to` must name a new file in an existing, writable folder. Trailing separators are rejected and existing files are never overwritten. When a POST, PUT or DELETE returns a file, set `save_to` on the first call, because repeating a mutation to get its response can repeat its effect.
137
+
138
+ ## Which Ghost permissions does it need?
139
+
140
+ | Class | Routes | Requirement |
141
+ |---|---:|---|
142
+ | `I` / `PUBLIC` | 125 | Integration-key allowlist or public access. Handler permissions still apply. |
143
+ | `U` | 116 | A staff user's access token with the required role, or a user session. |
144
+ | `SESSION` | 3 | User cookie session. Integration keys and staff tokens are blocked. |
145
+ | `FLOW` | 9 | Login, recovery and setup flows with their own authentication. |
146
+
147
+ To use a staff token, put the token from the user's Ghost Admin profile into `GHOST_ADMIN_API_KEY`. Its permissions follow the user's role. Staff tokens cannot call `DELETE /db/`, `PUT /users/owner/` or `POST /authentication/reset/`.
148
+
149
+ The server does not implement cookie sessions, login or 2FA. Those routes are in the catalog for discovery only.
150
+
151
+ Requests send `Accept-Version: v5.0`. The catalog is a snapshot of Ghost's `main` branch, so it includes newer or experimental routes that may return 404 on your installation. The public Content API is not included.
152
+
153
+ ## Is it safe to give an AI client access to my site?
154
+
155
+ Treat it like any account with write access to your blog, and keep a human in the loop.
156
+
157
+ - Keep keys in your client's environment or in `.env`, and never commit them. Turn on manual approval for destructive tools: all `update_*` and `delete_*` tools, `activate_theme`, `upload_theme` and `ghost_api_request`.
158
+ - If a mutation fails after it was sent, check Ghost before retrying, because it may have gone through. Use the read tools to inspect the result of a truncated response.
159
+ - Redirects are never followed. Configure the canonical Admin URL, and after a mutation receives a redirect, check the result before sending another request.
160
+ - Local file paths must be absolute. Hidden path components are refused, both as written and after symlink resolution. Uploads require regular files, and downloads are reserved before the request with owner-only permissions.
161
+ - The file checks are not a sandbox. They don't protect sensitive files that have visible names, and they don't stop a local process from rewriting directories during a call. Treat site content as untrusted and review upload requests.
162
+ - Uploads and downloads are buffered in memory. HTTP requests time out after 120 seconds, and tool responses longer than 100,000 characters are truncated.
163
+
164
+ ## Development
165
+
166
+ ```bash
167
+ npm run typecheck # tsc --noEmit
168
+ npm test # regression tests with synthetic credentials and a local fake Ghost server
169
+ npm run catalog # regenerate src/catalog.ts from GHOST_API.list
170
+ npm run build # compile to dist/
171
+ npm start # run the build over stdio (requires configuration)
172
+ ```
173
+
174
+ The route list lives in `GHOST_API.list`. `scripts/generate-catalog.mjs` turns it into `src/catalog.ts`, which you should never edit by hand. To change routes, edit the list, run `npm run catalog`, then run the tests. Logs go to stderr, because stdout is reserved for MCP messages.
175
+
176
+ GitHub Actions runs typecheck, build and tests on Node 20 and 22 for every push to `main` and every pull request.
177
+
178
+ The tests check catalog and tool consistency, request construction, file safety, redirects, retry guidance and configuration isolation. They don't prove compatibility with a live Ghost instance.
179
+
180
+ ## FAQ
181
+
182
+ **Does it work with self-hosted Ghost and Ghost(Pro)?**
183
+ Yes, as long as you can reach the Admin API and have a key. Use the Admin domain of your site as `GHOST_API_URL`.
184
+
185
+ **Which clients does it support?**
186
+ Any MCP client that can start a stdio server, including Claude Desktop, Claude Code and Cursor.
187
+
188
+ **Can it read my public content without an Admin key?**
189
+ No. It uses the Admin API only. The public Content API is not covered.
190
+
191
+ **Can it delete my content?**
192
+ Yes, `delete_post`, `delete_page` and similar tools are permanent. Require manual approval for them in your client.
193
+
194
+ ## License
195
+
196
+ [MIT](LICENSE).
@@ -0,0 +1,261 @@
1
+ // Generated from GHOST_API.list (TryGhost/Ghost commit 45498ed2eca0585e3542c852e57b275581a78d63).
2
+ // Do not edit by hand: change GHOST_API.list, run "npm run catalog", then run "npm test".
3
+ /**
4
+ * access: I = passes the integration-token allowlist, U = needs a staff user token or session,
5
+ * SESSION = needs a user cookie session, FLOW = login/recovery/setup flow, PUBLIC = no authentication.
6
+ */
7
+ export const CATALOG = [
8
+ ["GET", "/site/", "site.read", "PUBLIC", "SITE", "doc", "get site title, description, logo, URL, and version"],
9
+ ["GET", "/config/", "config.read", "I", "CONFIG", "src", "get record"],
10
+ ["GET", "/config/featurebase/", "config.featurebase", "I", "CONFIG", "src", "get Featurebase configuration"],
11
+ ["GET", "/posts/", "posts.browse", "I", "POSTS", "doc", "list records"],
12
+ ["GET", "/posts/export/", "posts.exportCSV", "I", "POSTS", "src", "export CSV"],
13
+ ["POST", "/posts/", "posts.add", "I", "POSTS", "doc", "create record"],
14
+ ["DELETE", "/posts/", "posts.bulkDestroy", "I", "POSTS", "src", "bulk delete records"],
15
+ ["PUT", "/posts/bulk/", "posts.bulkEdit", "I", "POSTS", "src", "bulk update records"],
16
+ ["POST", "/posts/upload/", "posts.importCSV", "I", "POSTS", "src", "import CSV", { flag: "csvContentImporter", upload: ["postsfile"] }],
17
+ ["GET", "/posts/{id}/", "posts.read", "I", "POSTS", "doc", "get record"],
18
+ ["GET", "/posts/slug/{slug}/", "posts.read", "I", "POSTS", "doc", "get record"],
19
+ ["PUT", "/posts/{id}/", "posts.edit", "I", "POSTS", "doc", "update record"],
20
+ ["DELETE", "/posts/{id}/", "posts.destroy", "I", "POSTS", "doc", "delete record"],
21
+ ["POST", "/posts/{id}/copy/", "posts.copy", "I", "POSTS", "src", "copy record"],
22
+ ["GET", "/posts/{id}/gift_links/", "giftLinks.browse", "I", "POSTS", "src", "list records"],
23
+ ["PUT", "/posts/{id}/gift_links/", "giftLinks.ensure", "I", "POSTS", "src", "ensure a gift link exists"],
24
+ ["POST", "/posts/{id}/gift_links/", "giftLinks.create", "I", "POSTS", "src", "create gift link"],
25
+ ["GET", "/mentions/", "mentions.browse", "U", "MENTIONS", "src", "list records"],
26
+ ["GET", "/comments/", "comments.browseAll", "I", "COMMENTS", "src", "get all comments"],
27
+ ["GET", "/comments/{id}/", "commentReplies.read", "I", "COMMENTS", "src", "get comment thread"],
28
+ ["GET", "/comments/{id}/replies/", "commentReplies.browse", "I", "COMMENTS", "src", "list records"],
29
+ ["GET", "/comments/{id}/reports/", "commentReports.browse", "I", "COMMENTS", "src", "list records"],
30
+ ["GET", "/comments/{id}/likes/", "commentLikes.browse", "I", "COMMENTS", "src", "list records"],
31
+ ["GET", "/comments/{id}/dislikes/", "commentDislikes.browse", "I", "COMMENTS", "src", "list records"],
32
+ ["GET", "/comments/post/{post_id}/", "comments.browse", "I", "COMMENTS", "src", "list records"],
33
+ ["POST", "/comments/", "comments.add", "I", "COMMENTS", "src", "create record"],
34
+ ["PUT", "/comments/{id}/", "comments.edit", "I", "COMMENTS", "src", "update record"],
35
+ ["GET", "/pages/", "pages.browse", "I", "PAGES", "doc", "list records"],
36
+ ["DELETE", "/pages/", "pages.bulkDestroy", "I", "PAGES", "src", "bulk delete records"],
37
+ ["PUT", "/pages/bulk/", "pages.bulkEdit", "I", "PAGES", "src", "bulk update records"],
38
+ ["POST", "/pages/", "pages.add", "I", "PAGES", "doc", "create record"],
39
+ ["GET", "/pages/{id}/", "pages.read", "I", "PAGES", "doc", "get record"],
40
+ ["GET", "/pages/slug/{slug}/", "pages.read", "I", "PAGES", "doc", "get record"],
41
+ ["PUT", "/pages/{id}/", "pages.edit", "I", "PAGES", "doc", "update record"],
42
+ ["DELETE", "/pages/{id}/", "pages.destroy", "I", "PAGES", "doc", "delete record"],
43
+ ["POST", "/pages/{id}/copy/", "pages.copy", "I", "PAGES", "doc", "copy record"],
44
+ ["GET", "/pages/{id}/gift_links/", "giftLinks.browse", "I", "PAGES", "src", "list records"],
45
+ ["PUT", "/pages/{id}/gift_links/", "giftLinks.ensure", "I", "PAGES", "src", "ensure a gift link exists"],
46
+ ["POST", "/pages/{id}/gift_links/", "giftLinks.create", "I", "PAGES", "src", "create gift link"],
47
+ ["PUT", "/gift_links/remove_all/", "giftLinks.removeAll", "U", "GIFT LINKS", "src", "revoke all gift links"],
48
+ ["GET", "/integrations/", "integrations.browse", "U", "INTEGRATIONS", "src", "list records"],
49
+ ["GET", "/integrations/{id}/", "integrations.read", "U", "INTEGRATIONS", "src", "get record"],
50
+ ["POST", "/integrations/", "integrations.add", "U", "INTEGRATIONS", "src", "create record"],
51
+ ["POST", "/integrations/{id}/api_key/{keyid}/refresh/", "integrations.edit", "U", "INTEGRATIONS", "src", "refresh integration key"],
52
+ ["PUT", "/integrations/{id}/", "integrations.edit", "U", "INTEGRATIONS", "src", "update record"],
53
+ ["DELETE", "/integrations/{id}/", "integrations.destroy", "U", "INTEGRATIONS", "src", "delete record"],
54
+ ["PUT", "/schedules/{resource}/{id}/", "schedules.publish", "I", "SCHEDULES", "src", "execute scheduled publication", { tokenUrl: true }],
55
+ ["PUT", "/gifts/flush_reminders/", "gifts.flushReminders", "I", "GIFTS", "src", "process pending gift reminders", { tokenUrl: true }],
56
+ ["PUT", "/gifts/flush_deliveries/", "gifts.flushDeliveries", "I", "GIFTS", "src", "process pending gift deliveries", { tokenUrl: true }],
57
+ ["GET", "/settings/routes/yaml/", "settings.download", "I", "SETTINGS", "src", "download file"],
58
+ ["POST", "/settings/routes/yaml/", "settings.upload", "U", "SETTINGS", "src", "upload file", { upload: ["routes"] }],
59
+ ["GET", "/settings/", "settings.browse", "I", "SETTINGS", "src", "list records"],
60
+ ["PUT", "/settings/", "settings.edit", "U", "SETTINGS", "src", "update record"],
61
+ ["POST", "/settings/access_code/regenerate/", "settings.regenerateAccessCode", "U", "SETTINGS", "src", "regenerate access code"],
62
+ ["PUT", "/settings/verifications/", "settings.verifyKeyUpdate", "U", "SETTINGS", "src", "confirm settings change"],
63
+ ["DELETE", "/settings/stripe/connect/", "settings.disconnectStripeConnectIntegration", "U", "SETTINGS", "src", "disconnect Stripe Connect"],
64
+ ["GET", "/users/", "users.browse", "I", "USERS", "doc", "list records"],
65
+ ["GET", "/users/{id}/", "users.read", "I", "USERS", "src", "get record"],
66
+ ["GET", "/users/slug/{slug}/", "users.read", "I", "USERS", "src", "get record"],
67
+ ["GET", "/users/email/{email}/", "users.read", "I", "USERS", "src", "get record"],
68
+ ["GET", "/users/{id}/token/", "users.readStaffToken", "I", "USERS", "src", "get staff token"],
69
+ ["PUT", "/users/password/", "users.changePassword", "U", "USERS", "src", "change password"],
70
+ ["PUT", "/users/owner/", "users.transferOwnership", "SESSION", "USERS", "src", "transfer site ownership"],
71
+ ["PUT", "/users/{id}/", "users.edit", "U", "USERS", "doc", "update record"],
72
+ ["PUT", "/users/{id}/token/", "users.regenerateStaffToken", "U", "USERS", "src", "regenerate staff token"],
73
+ ["DELETE", "/users/{id}/", "users.destroy", "U", "USERS", "doc", "delete record"],
74
+ ["GET", "/tags/", "tags.browse", "I", "TAGS", "src", "list records"],
75
+ ["GET", "/tags/{id}/", "tags.read", "I", "TAGS", "src", "get record"],
76
+ ["GET", "/tags/slug/{slug}/", "tags.read", "I", "TAGS", "src", "get record"],
77
+ ["POST", "/tags/", "tags.add", "I", "TAGS", "src", "create record"],
78
+ ["PUT", "/tags/{id}/", "tags.edit", "I", "TAGS", "src", "update record"],
79
+ ["DELETE", "/tags/{id}/", "tags.destroy", "I", "TAGS", "src", "delete record"],
80
+ ["GET", "/tiers/", "tiers.browse", "I", "TIERS", "doc", "list records"],
81
+ ["POST", "/tiers/", "tiers.add", "I", "TIERS", "doc", "create record"],
82
+ ["GET", "/tiers/{id}/", "tiers.read", "I", "TIERS", "src", "get record"],
83
+ ["PUT", "/tiers/{id}/", "tiers.edit", "I", "TIERS", "doc", "update record"],
84
+ ["GET", "/stripe/checkout/config/", "stripeCheckoutConfig.read", "U", "STRIPE CHECKOUT", "src", "get record", { flag: "stripeCheckoutDesign" }],
85
+ ["PUT", "/stripe/checkout/config/", "stripeCheckoutConfig.edit", "U", "STRIPE CHECKOUT", "src", "update record", { flag: "stripeCheckoutDesign" }],
86
+ ["POST", "/stripe/checkout/preview/", "stripeCheckoutPreview.add", "U", "STRIPE CHECKOUT", "src", "create record", { flag: "stripeCheckoutDesign" }],
87
+ ["GET", "/stripe/checkout/branding/", "stripeCheckoutBranding.read", "U", "STRIPE CHECKOUT", "src", "get record", { flag: "stripeCheckoutDesign" }],
88
+ ["GET", "/members/", "members.browse", "I", "MEMBERS", "doc", "list records"],
89
+ ["POST", "/members/", "members.add", "I", "MEMBERS", "doc", "create record"],
90
+ ["DELETE", "/members/", "members.bulkDestroy", "I", "MEMBERS", "src", "bulk delete records"],
91
+ ["PUT", "/members/bulk/", "members.bulkEdit", "I", "MEMBERS", "src", "bulk update records"],
92
+ ["GET", "/members/stats/count/", "members.memberStats", "I", "MEMBERS", "src", "get member count stats"],
93
+ ["GET", "/members/stats/mrr/", "members.mrrStats", "I", "MEMBERS", "src", "get monthly recurring revenue stats"],
94
+ ["GET", "/members/events/", "members.activityFeed", "I", "MEMBERS", "src", "get member activity feed"],
95
+ ["GET", "/members/upload/", "members.exportCSV", "I", "MEMBERS", "src", "export CSV"],
96
+ ["POST", "/members/upload/", "members.importCSV", "I", "MEMBERS", "src", "import CSV", { upload: ["membersfile"] }],
97
+ ["GET", "/members/stripe_connect/", "membersStripeConnect.auth", "I", "MEMBERS", "src", "start Stripe Connect authorization"],
98
+ ["GET", "/members/metafields/{namespace}/", "membersMetafields.browse", "I", "MEMBERS", "src", "list records"],
99
+ ["GET", "/members/metafields/{namespace}/{key}/", "membersMetafields.read", "I", "MEMBERS", "src", "get record"],
100
+ ["POST", "/members/metafields/{namespace}/", "membersMetafields.add", "I", "MEMBERS", "src", "create record", { flag: "membersCustomFields" }],
101
+ ["PUT", "/members/metafields/{namespace}/", "membersMetafields.reorder", "I", "MEMBERS", "src", "reorder field definitions", { flag: "membersCustomFields" }],
102
+ ["PUT", "/members/metafields/{namespace}/{key}/", "membersMetafields.edit", "I", "MEMBERS", "src", "update record", { flag: "membersCustomFields" }],
103
+ ["DELETE", "/members/metafields/{namespace}/{key}/", "membersMetafields.destroy", "I", "MEMBERS", "src", "delete record", { flag: "membersCustomFields" }],
104
+ ["GET", "/members/{id}/", "members.read", "I", "MEMBERS", "src", "get record"],
105
+ ["PUT", "/members/{id}/", "members.edit", "I", "MEMBERS", "doc", "update record"],
106
+ ["DELETE", "/members/{id}/", "members.destroy", "I", "MEMBERS", "src", "delete record"],
107
+ ["DELETE", "/members/{id}/sessions/", "members.logout", "I", "MEMBERS", "src", "end member sessions"],
108
+ ["DELETE", "/members/{id}/suppression/", "members.deleteEmailSuppression", "I", "MEMBERS", "src", "clear email suppression"],
109
+ ["POST", "/members/{id}/subscriptions/", "members.createSubscription", "I", "MEMBERS", "src", "create member subscription"],
110
+ ["PUT", "/members/{id}/subscriptions/{subscription_id}/", "members.editSubscription", "I", "MEMBERS", "src", "update member subscription"],
111
+ ["GET", "/members/{id}/signin_urls/", "memberSigninUrls.read", "I", "MEMBERS", "src", "get member login links"],
112
+ ["POST", "/members/{id}/commenting/disable/", "memberCommenting.disable", "I", "MEMBERS", "src", "disable comments"],
113
+ ["POST", "/members/{id}/commenting/enable/", "memberCommenting.enable", "I", "MEMBERS", "src", "enable comments"],
114
+ ["GET", "/offers/", "offers.browse", "I", "OFFERS", "doc", "list records"],
115
+ ["POST", "/offers/", "offers.add", "I", "OFFERS", "doc", "create record"],
116
+ ["GET", "/offers/{id}/", "offers.read", "I", "OFFERS", "src", "get record"],
117
+ ["PUT", "/offers/{id}/", "offers.edit", "I", "OFFERS", "doc", "update record"],
118
+ ["POST", "/apps/installations/preview/", "appInstallationPreviews.add", "U", "APPS", "src", "create record", { flag: "apps" }],
119
+ ["GET", "/apps/installations/", "appInstallations.browse", "U", "APPS", "src", "list records", { flag: "apps" }],
120
+ ["POST", "/apps/installations/", "appInstallations.add", "U", "APPS", "src", "create record", { flag: "apps" }],
121
+ ["GET", "/apps/installations/{id}/", "appInstallations.read", "U", "APPS", "src", "get record", { flag: "apps" }],
122
+ ["PUT", "/apps/installations/{id}/", "appInstallations.edit", "U", "APPS", "src", "update record", { flag: "apps" }],
123
+ ["POST", "/apps/installations/{id}/sessions/", "appSessions.start", "U", "APPS", "src", "start app session", { flag: "apps" }],
124
+ ["DELETE", "/apps/installations/{id}/", "appInstallations.destroy", "U", "APPS", "src", "delete record", { flag: "apps" }],
125
+ ["GET", "/stats/member_count/", "stats.memberCountHistory", "U", "STATS", "src", "get member-count history"],
126
+ ["GET", "/stats/mrr/", "stats.mrr", "U", "STATS", "src", "get MRR trends"],
127
+ ["GET", "/stats/subscriptions/", "stats.subscriptions", "U", "STATS", "src", "get subscription stats"],
128
+ ["GET", "/stats/referrers/", "stats.referrersHistory", "U", "STATS", "src", "get referral-source history"],
129
+ ["GET", "/stats/posts/{id}/stats/", "stats.postStats", "U", "STATS", "src", "get post stats"],
130
+ ["GET", "/stats/top-posts/", "stats.topPosts", "U", "STATS", "src", "get popular posts"],
131
+ ["GET", "/stats/top-posts-views/", "stats.topPostsViews", "U", "STATS", "src", "get popular posts by views"],
132
+ ["GET", "/stats/top-content/", "stats.topContent", "U", "STATS", "src", "get popular content"],
133
+ ["GET", "/stats/newsletter-stats/", "stats.newsletterStats", "U", "STATS", "src", "get newsletter stats"],
134
+ ["GET", "/stats/newsletter-basic-stats/", "stats.newsletterBasicStats", "U", "STATS", "src", "get newsletter overview metrics"],
135
+ ["GET", "/stats/newsletter-click-stats/", "stats.newsletterClickStats", "U", "STATS", "src", "get newsletter click stats"],
136
+ ["GET", "/stats/subscriber-count/", "stats.subscriberCount", "U", "STATS", "src", "get newsletter subscriber count"],
137
+ ["GET", "/stats/posts/{id}/top-referrers/", "stats.postReferrers", "U", "STATS", "src", "get post referral sources"],
138
+ ["GET", "/stats/posts/{id}/growth/", "stats.postGrowthStats", "U", "STATS", "src", "get audience growth attributed to a post"],
139
+ ["GET", "/stats/top-sources-growth/", "stats.topSourcesGrowth", "U", "STATS", "src", "get audience growth sources"],
140
+ ["POST", "/stats/posts-visitor-counts/", "stats.postsVisitorCounts", "U", "STATS", "src", "get visitor counts for a set of posts"],
141
+ ["POST", "/stats/posts-member-counts/", "stats.postsMemberCounts", "U", "STATS", "src", "get member counts for a set of posts"],
142
+ ["GET", "/labels/", "labels.browse", "I", "LABELS", "doc", "list records"],
143
+ ["GET", "/labels/{id}/", "labels.read", "I", "LABELS", "src", "get record"],
144
+ ["GET", "/labels/slug/{slug}/", "labels.read", "I", "LABELS", "src", "get record"],
145
+ ["POST", "/labels/", "labels.add", "I", "LABELS", "doc", "create record"],
146
+ ["PUT", "/labels/{id}/", "labels.edit", "I", "LABELS", "doc", "update record"],
147
+ ["DELETE", "/labels/{id}/", "labels.destroy", "I", "LABELS", "doc", "delete record"],
148
+ ["GET", "/automations/", "automations.browse", "U", "AUTOMATIONS", "src", "list records"],
149
+ ["GET", "/automations/{automation_id}/actions/{action_id}/links/", "automationActionLinks.browse", "U", "AUTOMATIONS", "src", "list records"],
150
+ ["GET", "/automations/{id}/", "automations.read", "U", "AUTOMATIONS", "src", "get record"],
151
+ ["GET", "/automations/{id}/performance-stats/", "automationPerformanceStats.read", "U", "AUTOMATIONS", "src", "get record"],
152
+ ["GET", "/automations/{id}/runs/", "automationRuns.browse", "U", "AUTOMATIONS", "src", "list records"],
153
+ ["GET", "/automations/{id}/runs/{run_id}/", "automationRunHistory.read", "U", "AUTOMATIONS", "src", "get record"],
154
+ ["POST", "/automations/{id}/email_preview/", "automationEmailPreviews.preview", "I", "AUTOMATIONS", "src", "generate preview"],
155
+ ["POST", "/automations/{id}/email_test/", "automationEmailPreviews.sendTestEmail", "I", "AUTOMATIONS", "src", "send a test email"],
156
+ ["PUT", "/automations/poll/", "automations.poll", "I", "AUTOMATIONS", "src", "run automation processing", { tokenUrl: true }],
157
+ ["POST", "/automations/", "automations.add", "I", "AUTOMATIONS", "src", "create record"],
158
+ ["PUT", "/automations/{id}/", "automations.edit", "I", "AUTOMATIONS", "src", "update record"],
159
+ ["GET", "/automated_emails/", "automatedEmails.browse", "U", "AUTOMATED EMAILS", "src", "list records"],
160
+ ["GET", "/automated_emails/design/", "automatedEmailDesign.read", "U", "AUTOMATED EMAILS", "src", "get record"],
161
+ ["PUT", "/automated_emails/senders/", "automatedEmails.editSenders", "U", "AUTOMATED EMAILS", "src", "update automated email senders"],
162
+ ["PUT", "/automated_emails/verifications/", "automatedEmails.verifySenderUpdate", "U", "AUTOMATED EMAILS", "src", "confirm sender change"],
163
+ ["GET", "/automated_emails/{id}/", "automatedEmails.read", "U", "AUTOMATED EMAILS", "src", "get record"],
164
+ ["POST", "/automated_emails/", "automatedEmails.add", "U", "AUTOMATED EMAILS", "src", "create record"],
165
+ ["PUT", "/automated_emails/design/", "automatedEmailDesign.edit", "U", "AUTOMATED EMAILS", "src", "update record"],
166
+ ["PUT", "/automated_emails/{id}/", "automatedEmails.edit", "U", "AUTOMATED EMAILS", "src", "update record"],
167
+ ["POST", "/automated_emails/{id}/preview/", "automatedEmails.preview", "U", "AUTOMATED EMAILS", "src", "generate preview"],
168
+ ["POST", "/automated_emails/{id}/test/", "automatedEmails.sendTestEmail", "U", "AUTOMATED EMAILS", "src", "send a test email"],
169
+ ["GET", "/roles/", "roles.browse", "I", "ROLES", "doc", "list records"],
170
+ ["GET", "/slugs/{type}/{name}/", "slugs.generate", "U", "SLUGS", "src", "generate a unique slug"],
171
+ ["GET", "/slugs/{type}/{name}/{id}/", "slugs.generate", "U", "SLUGS", "src", "generate a unique slug"],
172
+ ["GET", "/themes/", "themes.browse", "U", "THEMES", "src", "list records"],
173
+ ["GET", "/themes/{name}/download/", "themes.download", "U", "THEMES", "src", "download file"],
174
+ ["GET", "/themes/active/", "themes.readActive", "U", "THEMES", "src", "get active theme"],
175
+ ["POST", "/themes/upload/", "themes.upload", "I", "THEMES", "doc", "upload file", { upload: ["file"] }],
176
+ ["POST", "/themes/install/", "themes.install", "I", "THEMES", "src", "install theme"],
177
+ ["PUT", "/themes/{name}/activate/", "themes.activate", "I", "THEMES", "doc", "activate theme"],
178
+ ["DELETE", "/themes/{name}/", "themes.destroy", "U", "THEMES", "src", "delete record"],
179
+ ["GET", "/notifications/", "notifications.browse", "U", "NOTIFICATIONS", "src", "list records"],
180
+ ["POST", "/notifications/", "notifications.add", "U", "NOTIFICATIONS", "src", "create record"],
181
+ ["DELETE", "/notifications/{notification_id}/", "notifications.destroy", "U", "NOTIFICATIONS", "src", "delete record"],
182
+ ["GET", "/db/", "db.exportContent", "I", "DB", "src", "export content"],
183
+ ["POST", "/db/", "db.importContent", "I", "DB", "src", "import content", { upload: ["importfile"] }],
184
+ ["DELETE", "/db/", "db.deleteAllContent", "SESSION", "DB", "src", "DELETE ALL CONTENT"],
185
+ ["POST", "/db/backup/", "db.backupContent", "I", "DB", "src", "create content backup"],
186
+ ["POST", "/db/media/inline/", "db.inlineMedia", "I", "DB", "src", "process inline media"],
187
+ ["GET", "/exports/download/", "exports.download", "U", "EXPORTS", "src", "download file"],
188
+ ["POST", "/exports/", "exports.add", "U", "EXPORTS", "src", "create export job"],
189
+ ["POST", "/slack/test/", "slack.sendTest", "U", "SLACK", "src", "send a Slack test"],
190
+ ["POST", "/support_requests/", "supportRequests.add", "U", "SUPPORT REQUESTS", "src", "create record"],
191
+ ["GET", "/tinybird/token/", "tinybird.token", "U", "TINYBIRD", "src", "get service token"],
192
+ ["GET", "/featurebase/token/", "featurebase.token", "U", "FEATUREBASE", "src", "get service token"],
193
+ ["POST", "/session/", "session.add", "FLOW", "SESSION", "doc", "create user session"],
194
+ ["DELETE", "/session/", "session.delete", "U", "SESSION", "src", "end session"],
195
+ ["POST", "/session/verify/", "session.sendVerification", "FLOW", "SESSION", "doc", "resend verification code"],
196
+ ["PUT", "/session/verify/", "session.verify", "FLOW", "SESSION", "doc", "verify session with code"],
197
+ ["GET", "/identities/", "identities.read", "U", "IDENTITIES", "src", "get record"],
198
+ ["POST", "/authentication/password_reset/", "authentication.generateResetToken", "FLOW", "AUTHENTICATION", "src", "request a password reset"],
199
+ ["PUT", "/authentication/password_reset/", "authentication.resetPassword", "FLOW", "AUTHENTICATION", "src", "set password using reset token"],
200
+ ["POST", "/authentication/invitation/", "authentication.acceptInvitation", "FLOW", "AUTHENTICATION", "src", "accept invitation"],
201
+ ["GET", "/authentication/invitation/", "authentication.isInvitation", "FLOW", "AUTHENTICATION", "src", "check invitation"],
202
+ ["POST", "/authentication/setup/", "authentication.setup", "FLOW", "AUTHENTICATION", "src", "perform initial setup"],
203
+ ["PUT", "/authentication/setup/", "authentication.updateSetup", "U", "AUTHENTICATION", "src", "update settings data"],
204
+ ["GET", "/authentication/setup/", "authentication.isSetup", "FLOW", "AUTHENTICATION", "src", "check setup status"],
205
+ ["POST", "/authentication/reset/", "authentication.reset", "SESSION", "AUTHENTICATION", "src", "reset authentication"],
206
+ ["POST", "/images/upload/", "images.upload", "I", "IMAGES", "doc", "upload file", { upload: ["file"] }],
207
+ ["POST", "/media/upload/", "media.upload", "I", "MEDIA", "src", "upload file", { upload: ["file", "thumbnail"] }],
208
+ ["PUT", "/media/thumbnail/upload/", "media.uploadThumbnail", "U", "MEDIA", "src", "upload media thumbnail", { upload: ["file"] }],
209
+ ["POST", "/files/upload/", "files.upload", "I", "FILES", "src", "upload file", { upload: ["file"] }],
210
+ ["GET", "/invites/", "invites.browse", "U", "INVITES", "src", "list records"],
211
+ ["GET", "/invites/{id}/", "invites.read", "U", "INVITES", "src", "get record"],
212
+ ["POST", "/invites/", "invites.add", "I", "INVITES", "doc", "create record"],
213
+ ["DELETE", "/invites/{id}/", "invites.destroy", "U", "INVITES", "src", "delete record"],
214
+ ["GET", "/redirects/download/", "redirects.download", "U", "REDIRECTS", "src", "download file"],
215
+ ["POST", "/redirects/upload/", "redirects.upload", "U", "REDIRECTS", "src", "upload file", { upload: ["redirects"] }],
216
+ ["GET", "/upgrades/", "upgrades.browse", "U", "UPGRADES", "src", "get available hosting updates"],
217
+ ["POST", "/upgrades/", "upgrades.add", "U", "UPGRADES", "src", "request a hosting update"],
218
+ ["GET", "/upgrades/{id}/", "upgrades.read", "U", "UPGRADES", "src", "get update status"],
219
+ ["POST", "/webhooks/", "webhooks.add", "I", "WEBHOOKS", "doc", "create record"],
220
+ ["PUT", "/webhooks/{id}/", "webhooks.edit", "I", "WEBHOOKS", "doc", "update record"],
221
+ ["DELETE", "/webhooks/{id}/", "webhooks.destroy", "I", "WEBHOOKS", "doc", "delete record"],
222
+ ["GET", "/oembed/", "oembed.read", "I", "OEMBED", "src", "get record"],
223
+ ["GET", "/actions/", "actions.browse", "I", "ACTIONS", "src", "list records"],
224
+ ["GET", "/email_previews/posts/{id}/", "email_previews.read", "U", "EMAIL PREVIEWS", "src", "get record"],
225
+ ["POST", "/email_previews/posts/{id}/", "email_previews.sendTestEmail", "U", "EMAIL PREVIEWS", "src", "send a test email"],
226
+ ["GET", "/emails/", "emails.browse", "U", "EMAILS", "src", "list records"],
227
+ ["GET", "/emails/{id}/", "emails.read", "U", "EMAILS", "src", "get record"],
228
+ ["GET", "/emails/{id}/status/", "emails.sendingStatus", "U", "EMAILS", "src", "get sending status"],
229
+ ["PUT", "/emails/{id}/retry/", "emails.retry", "U", "EMAILS", "src", "retry email delivery"],
230
+ ["GET", "/emails/{id}/batches/", "emails.browseBatches", "U", "EMAILS", "src", "get delivery batches"],
231
+ ["GET", "/emails/{id}/recipient-failures/", "emails.browseFailures", "U", "EMAILS", "src", "get recipient delivery failures"],
232
+ ["GET", "/emails/{id}/analytics/", "emails.analyticsStatus", "U", "EMAILS", "src", "get analytics collection status"],
233
+ ["PUT", "/emails/{id}/analytics/", "emails.scheduleAnalytics", "U", "EMAILS", "src", "schedule analytics collection"],
234
+ ["DELETE", "/emails/analytics/", "emails.cancelScheduledAnalytics", "U", "EMAILS", "src", "cancel scheduled analytics collection"],
235
+ ["GET", "/snippets/", "snippets.browse", "U", "SNIPPETS", "src", "list records"],
236
+ ["GET", "/snippets/{id}/", "snippets.read", "U", "SNIPPETS", "src", "get record"],
237
+ ["POST", "/snippets/", "snippets.add", "U", "SNIPPETS", "src", "create record"],
238
+ ["PUT", "/snippets/{id}/", "snippets.edit", "U", "SNIPPETS", "src", "update record"],
239
+ ["DELETE", "/snippets/{id}/", "snippets.destroy", "U", "SNIPPETS", "src", "delete record"],
240
+ ["GET", "/custom_theme_settings/", "customThemeSettings.browse", "U", "CUSTOM THEME SETTINGS", "src", "list records"],
241
+ ["PUT", "/custom_theme_settings/", "customThemeSettings.edit", "U", "CUSTOM THEME SETTINGS", "src", "update record"],
242
+ ["GET", "/newsletters/", "newsletters.browse", "I", "NEWSLETTERS", "doc", "list records"],
243
+ ["GET", "/newsletters/{id}/", "newsletters.read", "I", "NEWSLETTERS", "src", "get record"],
244
+ ["POST", "/newsletters/", "newsletters.add", "I", "NEWSLETTERS", "doc", "create record"],
245
+ ["PUT", "/newsletters/verifications/", "newsletters.verifyPropertyUpdate", "I", "NEWSLETTERS", "src", "confirm newsletter property change"],
246
+ ["PUT", "/newsletters/{id}/", "newsletters.edit", "I", "NEWSLETTERS", "doc", "update record"],
247
+ ["GET", "/links/", "links.browse", "U", "LINKS", "src", "list records"],
248
+ ["PUT", "/links/bulk/", "links.bulkEdit", "U", "LINKS", "src", "bulk update records"],
249
+ ["GET", "/recommendations/", "recommendations.browse", "U", "RECOMMENDATIONS", "src", "list records"],
250
+ ["GET", "/recommendations/{id}/", "recommendations.read", "U", "RECOMMENDATIONS", "src", "get record"],
251
+ ["POST", "/recommendations/", "recommendations.add", "U", "RECOMMENDATIONS", "src", "create record"],
252
+ ["POST", "/recommendations/check/", "recommendations.check", "U", "RECOMMENDATIONS", "src", "check recommended publication"],
253
+ ["PUT", "/recommendations/{id}/", "recommendations.edit", "U", "RECOMMENDATIONS", "src", "update record"],
254
+ ["DELETE", "/recommendations/{id}/", "recommendations.destroy", "U", "RECOMMENDATIONS", "src", "delete record"],
255
+ ["GET", "/incoming_recommendations/", "incomingRecommendations.browse", "U", "INCOMING RECOMMENDATIONS", "src", "list records"],
256
+ ["GET", "/feedback/{id}/", "feedbackMembers.browse", "U", "FEEDBACK", "src", "list records"],
257
+ ["GET", "/search-index/posts/", "searchIndex.fetchPosts", "I", "SEARCH INDEX", "src", "get post stats"],
258
+ ["GET", "/search-index/pages/", "searchIndex.fetchPages", "I", "SEARCH INDEX", "src", "get page stats"],
259
+ ["GET", "/search-index/tags/", "searchIndex.fetchTags", "I", "SEARCH INDEX", "src", "get tag stats"],
260
+ ["GET", "/search-index/users/", "searchIndex.fetchUsers", "I", "SEARCH INDEX", "src", "get author stats"],
261
+ ];