voog-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| voog_list_sitesA | List all sites configured in the global voog.json. Returns [{name, host}, ...]. Call this first to see what sites are available before invoking any other voog_* tool. If a site you just registered is missing, call voog_reload_config. |
| voog_reload_configA | Re-read the global voog.json (and its .env) and drop cached clients, so sites registered AFTER this server started become usable without restarting the MCP host. Returns the current site list plus what was added/removed. Use when 'unknown site' comes back for a site you just added, or after rotating a token in .env. Running tool calls are unaffected — they finish against the client they already hold. A malformed config leaves the current one in place. |
| articles_listA | List blog articles on the Voog site (simplified: id, title, path, public_url, published, published_at, updated_at, created_at, language_code, page_id). All filters optional. Read-only. |
| article_getA | Get full article details by id (title, path, body, autosaved_*, published_at, language, page, data, image, tags). Read-only. |
| article_createA | Create a new blog article. Required: page_id (the parent blog page), title. Optional: body (HTML), excerpt, description (meta), path (auto from title if omitted), image_id, tag_names (array), data (custom dict), publish (default false). Title and body go to autosaved_* fields per Voog convention; if publish=true, publishing:true is set so values copy to published fields atomically. NOT idempotent — repeat calls create multiple articles. |
| article_updateA | Update an existing article. Title/body/excerpt go to autosaved_* per Voog convention (the public fields are read-only — call article_publish to push autosaved → published). description/path/image_id/tag_names/data are non-autosaved fields and update directly. At least one field must be supplied.
|
| article_publishA | Publish an article. Voog only copies autosaved_* → published fields when publishing:true is sent in the SAME PUT as the autosaved values — that's why this needs a separate tool rather than a Two modes:
Mixed (some autosaved_* provided, some not) is rejected — the caller must be explicit. |
| article_deleteB | Delete an article. IRREVERSIBLE — Voog does not retain deleted articles. Requires force=true. |
| article_set_dataA | Set a single article.data. value (PUT /articles/{id}/data/{key}). To delete a key use article_delete_data. Keys starting with 'internal_' are server-protected and rejected client-side. |
| article_delete_dataA | Delete a single article.data. (DELETE /articles/{id}/data/{key}). IRREVERSIBLE — the key is removed permanently. Requires force=true; without it the call is rejected. Keys starting with 'internal_' are server-protected and rejected client-side. |
| asset_uploadA | Upload local image files into the site's media library (POST /assets -> PUT bytes -> PUT confirm) WITHOUT attaching them to anything. Use for images referenced from site.data / page.data maps, article galleries or template markup; use product_set_images when the images are a product's gallery. Returns each asset's id, dimensions, public path (/photos/) and the derivative By default an existing asset with the same filename is REUSED rather than uploaded again: Voog auto-suffixes duplicate filenames (photo-1.jpg), so re-uploading silently orphans the original. Pass allow_duplicate=true to force a new asset (e.g. a corrected re-shoot under a fresh sequence letter). Waits for Voog to finish its async resizes before returning — up to 120s per file, polling the API every 5s, so a large batch is slow by design. Each result carries Do NOT request a derivative URL over HTTP to check whether it exists — a too-early request gets a 403 that the CDN caches for ~1h, breaking a URL that was about to work. |
| cart_rules_listB | List all cart rules (GET /admin/api/ecommerce/v1/cart_rules). Read-only. |
| cart_rule_getB | Get a single cart rule by id (GET /admin/api/ecommerce/v1/cart_rules/{id}). Read-only. |
| cart_rule_createA | Create a cart rule (POST /admin/api/ecommerce/v1/cart_rules). Envelope {cart_rule: {...}}. Required: kind, target_kind, target_id, conditions[], result{}. Inner conditions[] entries are {value, comparator, field, value_type}. result is {value, field, value_type}. Inner key validation is left to Voog — invalid combos return a 422 with the offending field. |
| cart_rule_updateB | Update a cart rule (PUT /admin/api/ecommerce/v1/cart_rules/{id}). Envelope {cart_rule: {...}}. Partial — at least one field must be supplied. Common partial updates: enabled, position. |
| cart_rule_deleteA | Delete a cart rule (DELETE /admin/api/ecommerce/v1/cart_rules/{id}). Requires force=true. Past orders that already had the rule applied are not affected. |
| categories_listA | List all ecommerce product categories (GET /admin/api/ecommerce/v1/categories). Read-only. Each entry has id, name, slug, parent_id, depth, created_at, updated_at. Use category.id from the results as the products_list(category_id=...) filter. |
| category_getA | Get a single category by id (GET /admin/api/ecommerce/v1/categories/{id}). Read-only. |
| category_createA | Create a category (POST /admin/api/ecommerce/v1/categories). Envelope: {category: {...}}. Required: name. Optional: slug (auto-generated if omitted), parent_id (for sub-categories). NOTE: Voog does not support description / image_id on categories despite some doc pages suggesting otherwise — verified empirically 2026-05-27. |
| category_updateA | Update a category (PUT /admin/api/ecommerce/v1/categories/{id}). Envelope: {category: {...}}. Partial — at least one of name / slug / parent_id must be supplied. |
| category_deleteA | Delete a category (DELETE /admin/api/ecommerce/v1/categories/{id}). Requires force=true. Products in the category are NOT deleted; they're orphaned from the category. Voog may reject if the category has child categories. |
| site_cloneA | Copy one Voog site's content onto another (layouts, layout assets, media, site settings, pages, content areas, articles). DRY RUN BY DEFAULT — without force=true nothing is written and the result reports what would happen. Run phase 'plan' first: it returns source object counts, the target's remaining asset quota, and the specific things Voog will not let a clone reproduce. RESUMABLE. Phases run in dependency order regardless of the order you list them (a page cannot reference a layout that does not exist yet): layouts, layout_assets, assets, site, pages, contents, articles, cleanup, verify. NOT COPIED: ecommerce (products, categories, discounts, cart rules, orders), elements, redirects, webhooks, forms, comments. Languages are matched by code, never created. Voog limits the clone cannot work around: created_at is not settable — PUT returns 200 and the value resets to now, so every copied article and page carries the clone date. published_at is not settable, for the same reason. Duplicate article paths cannot be reproduced — Voog now auto-suffixes a colliding path with -1. Legacy sites that hold two articles on one path will have the twin land on a different URL. Asset storage is capped per plan. The clone checks the target's remaining quota before uploading and stops cleanly rather than hitting 422 quota_exceeded partway through. |
| comments_listA | List comments on an article ( |
| comment_deleteA | Remove a comment ( |
| comment_toggle_spamA | Flip a comment's spam flag ( |
| content_partial_updateA | Update a content partial (PUT /content_partials/{id}). Content partials are reusable template fragments embedded in pages and layouts. PUT body is flat (no envelope). At least one of |
| discounts_listA | List all ecommerce discounts (GET /admin/api/ecommerce/v1/discounts). Read-only. |
| discount_getA | Get a single discount by id (GET /admin/api/ecommerce/v1/discounts/{id}). Read-only. |
| discount_createA | Create a discount (POST /admin/api/ecommerce/v1/discounts). Envelope {discount: {...}}. Required: code. Empirically-verified enum values (rejected client-side with a clear error before round-tripping to Voog): status ∈ {open, closed} amount_mode ∈ {net, gross} discount_type ∈ {fixed, percentage} applies_to ∈ {cart, cart_and_shipping, categories, products, shipping} Optional: name, description, amount, valid_from (ISO8601), valid_to, redemption_limit, stackable, currency. |
| discount_updateA | Update a discount (PUT /admin/api/ecommerce/v1/discounts/{id}). Envelope {discount: {...}}. Partial — at least one discount field must be supplied. Enum-restricted fields (client-validated): status ∈ {open, closed}; amount_mode ∈ {net, gross}; discount_type ∈ {fixed, percentage}; applies_to ∈ {cart, cart_and_shipping, categories, products, shipping}. |
| discount_deleteA | Delete a discount (DELETE /admin/api/ecommerce/v1/discounts/{id}). Requires force=true. Already-used discount records remain on past orders; deletion only prevents future use. |
| ecommerce_settings_getA | Get ecommerce store settings (currency, tax_rate, value_date_days, default_language, decimal_places, company_name, bank_details, terms, privacy_policy, products_url_slug, etc.). Includes per-language translations. Read-only. Note: this is also the source of truth for |
| ecommerce_settings_updateA | Update ecommerce settings. attributes: flat root-level fields (currency, tax_rate, notification_email, ...). translations: nested {field: {lang: value}} for translatable settings. The set of translatable keys is discovered at runtime from |
| elements_listA | List elements (id, title, path, page_id, element_definition_id, position). Optional filters: page_id, language_id, language_code, element_definition_id, element_definition_title, page_path, page_path_prefix. Pass include_values=true to include the values hash in the projection (off by default — values clutter list views; use element_get for full shape). Read-only. |
| element_getA | Get a single element by id, with full values hash. Use elements_list to find ids. |
| element_definitions_listA | List element definitions (id, title, property_keys — the field keys each definition expects). Use the returned id for element_create.element_definition_id. Read-only. Mutating definitions (POST/PUT/DELETE) is deferred — handle via voog_admin_api_call when needed. |
| element_createA | Create an element (POST /elements). Body is FLAT. Required: element_definition_id OR element_definition_title (id takes precedence per Voog docs); page_id; title. Optional: path (auto-generated from title if omitted), values (custom-properties hash matching the element_definition's schema). |
| element_updateA | Update an element (PUT /elements/{id}). Partial — supply ONLY the fields to change. Body is FLAT. Updatable: title, path, values. At least one besides element_id is required. |
| element_deleteA | Delete an element (DELETE /elements/{id}). Voog returns 204. Requires force=true; without it the call is rejected. Run elements_list first to confirm the id. |
| element_moveA | Re-order or re-parent an element instance ( |
| layout_renameA | Rename a layout (PUT /layouts/{id} {title}). Reversible — rename back to the original title to undo. The new title must not contain '/' or '\' or start with '.'. |
| layout_createA | Create a new layout or component (POST /layouts). kind='layout' for full templates (defaults content_type='page'; use 'blog_article' for blog post templates); kind='component' for shared partials (content_type ignored). Returns the new id. NOT idempotent — calling twice creates two separate layouts. |
| asset_replaceA | Rename a layout_asset by creating a new one with the desired filename (DELETE+POST workaround — Voog API rejects PUT with filename changes). Returns both old and new ids. The OLD asset is intentionally left in place; after updating templates that reference the old filename, delete the old asset manually with DELETE /layout_assets/{old_id}. |
| layout_updateA | Update a layout — body (Liquid template source), title, or both. At least one must be supplied. Reversible by calling again with the previous values; idempotent. |
| layout_deleteA | Delete a layout. IRREVERSIBLE — Voog does not retain deleted layouts. Refuses without force=true. Voog blocks deletion of layouts that still have pages assigned — the API returns an error, the layout is NOT deleted. Reassign those pages first via page_set_layout, then retry. Back up with site_snapshot before this operation. |
| layout_asset_createA | Create a layout_asset. TEXT content only, and |
| layout_asset_updateA | Update a layout_asset's content (PUT /layout_assets/{id} {data}). filename is read-only — Voog returns 500 if filename is sent on PUT. Use asset_replace to rename. NOT byte-exact for a file on disk: |
| layout_asset_uploadA | Upload a BINARY layout asset from disk — favicon, icon, font, inline image (multipart POST /layout_assets, issue #140 item 4). layout_asset_create only carries text Served from /images/ (or the site's asset path), not /photos — these live with the templates, not in the media library. For photos referenced from content or site.data use asset_upload instead. Voog derives asset_type and content_type from the file; the result is editable=false (no text body to edit). Uploading the same filename again creates a SECOND asset — delete the old one, or use asset_replace semantics, if you meant to replace it. |
| layout_asset_deleteA | Delete a layout_asset. IRREVERSIBLE. Refuses without force=true. Templates referencing the deleted file will render with empty content. |
| layouts_pullA | Fetch every layout + component from /layouts, plus the editable layout_assets (CSS/JS), and write them under target_dir: .tpl files to layouts/ and components/, assets to stylesheets/ javascripts/ assets/. Binary assets are skipped (no text to round-trip — use layout_asset_upload for those). Builds manifest.json mapping each local path to {id, type, updated_at}. REFUSES to overwrite an existing tree that already contains .tpl files — pick a fresh location or clear it first. Empty/non-tpl content in target_dir is fine (e.g. README.md, .gitignore are preserved). |
| layouts_pushA | Read manifest.json + tracked files from target_dir and PUT each to the endpoint its manifest type maps to: type=layout → /layouts/{id} {body}, type=asset (legacy: layout_asset) → /layout_assets/{id} {data}. Optional files=["javascripts/app.js", ...] filter pushes only the named relative paths; files=null (or omitted) pushes every manifest entry. THE BYTE-EXACT WAY to deploy a .js/.css asset: content is read from disk here, whereas a string passed to layout_asset_update crosses a JSON boundary that decodes literal \uXXXX escapes in the source (issue #138). A PUT that returns 200 without persisting is reported as a failure, not a ✓. Returns per-file success/failure breakdown; missing files and PUT errors are captured per-entry and do not abort the remaining pushes. Recommended pre-flight: site_snapshot for full backup before a mass push. |
| voog_list_my_sitesA | Probe |
| media_set_getA | Get a media_set (gallery) by id ( |
| media_set_update_asset_titlesA | Safely edit one or more asset titles in a media_set (gallery). Pass WHY THIS TOOL: Every key in |
| media_set_set_assetsA | Set a media_set's FULL asset list in one call — for filling, reordering or pruning an EXISTING gallery (issue #140 item 5; media_set_update_asset_titles only edits titles of what is already there).
Titles and per-asset link settings are carried over for assets that stay; pass The media_set must already exist: POST /media_sets returns 500, and a freshly created gallery content area has no media_set until Voog makes one. Find the id on the content area's |
| language_createA | Add a new language to the Voog site (POST /languages). Required: code (ISO 639-1 two-letter), title. Optional: region (ISO 3166-1 alpha-2), site_title, site_header, default_language, published, content_origin_id (duplicate content from another language). Body is FLAT — no envelope wrapper. |
| language_deleteA | Remove a language from the site (DELETE /languages/{id}). IRREVERSIBLE — Voog deletes the language and unbinds associated content. Requires force=true; without it the call is rejected. Run site_snapshot first if uncertain. |
| languages_listA | List all languages on the Voog site (id, code, title, default_language, published, position). Use the returned ids for page_create.language_id / article fields. Read-only. |
| nodes_listC | List all page nodes (id, title, parent_id, position). Each node represents a language-agnostic page identity; its parallel translations are pages sharing the same node.id. Read-only. |
| node_getA | Get a single node by id, with its full pages array — one entry per language. Use this when preparing a parallel translation: read the node id from one page, then pass node_id to page_create with the second-language details. |
| node_updateA | Update a node's title (PUT /nodes/{id}). Per Voog docs, only |
| node_moveA | Move/reorder a node within the page tree (PUT /nodes/{id}/move). Inputs travel as query-string params per Voog docs. Required: parent_id (current or new parent — pass current to just reorder). Optional: position (1-indexed, Voog default 1). |
| node_relocateA | Relocate a node to a precise position relative to a sibling, or to the first slot under a new parent (PUT /nodes/{id}/relocate). Body is FLAT. Supply EXACTLY ONE of: before (place this node before the given sibling id), after (place after sibling id), or parent_node_id (move to first position under new parent). Mutually exclusive — handler rejects multiple. |
| orders_listA | List ecommerce orders (GET /admin/api/ecommerce/v1/orders). Read-only. Optional filters: status (e.g. 'created', 'cancelled'), payment_status (e.g. 'paid', 'unpaid'), created_after (ISO8601), created_before (ISO8601). include_pii=false (default) strips customer email / name / address / phone / IP via whitelist. include_pii=true REQUIRES force=true alongside — passing include_pii=true without force=true is rejected (LLM-side PII-exfiltration gate; see SECURITY.md). MCP hosts surface force as a destructive-hint approval, which keeps prompt-injected |
| order_getA | Get a single order by id (GET /admin/api/ecommerce/v1/orders/{id}). Read-only. include_pii=false (default) strips PII via whitelist. include_pii=true REQUIRES force=true alongside (LLM-side PII-exfiltration gate; see SECURITY.md). |
| pages_listA | List pages on the Voog site (id, path, title, hidden, layout name). All filters are optional; with no filters this returns every page. Read-only. |
| page_getA | Get full details of a single page by id (title, path, hidden, layout, language, parent, timestamps, public_url). |
| page_set_hiddenA | Bulk toggle the |
| page_set_layoutA | Reassign a page's layout. Reversible — call again with the original layout_id to revert. |
| page_deleteA | Delete a page. IRREVERSIBLE — Voog does not retain deleted pages. Requires force=true; without it the call is rejected to prevent accidental deletion. Run |
| page_createA | Create a new page. Required: title, slug, language_id. Optional: parent_id (page id, NOT node_id) for subpages, node_id for parallel-translation pages of an existing page in another language, layout_id, content_type ('page'|'link'|'blog'|'product'|...), hidden, image_id, description, keywords, data (custom dict). Multilingual: pass node_id of the first-language page instead of parent_id when creating its translation in another language. Voog binds them as parallels (admin Translate UI works correctly). parent_id and node_id are mutually exclusive. |
| page_updateA | Update arbitrary fields on a page. At least one of title, slug, layout_id, image_id, content_type, parent_id, description, keywords, data must be supplied. For just hidden / layout id, prefer the dedicated page_set_hidden / page_set_layout — they're more explicit in tool listings.
|
| page_set_dataA | Set a single page.data. value (PUT /pages/{id}/data/{key}). To delete a key use page_delete_data. Keys starting with 'internal_' are server-protected and rejected client-side. |
| page_delete_dataA | Delete a single page.data. (DELETE /pages/{id}/data/{key}). IRREVERSIBLE — the key is removed permanently. Requires force=true; without it the call is rejected. Keys starting with 'internal_' are server-protected and rejected client-side. |
| page_duplicateA | POST /pages/{id}/duplicate — create a copy of the page (including its content). The new page is hidden by default per Voog convention. |
| products_listA | List all ecommerce products on the Voog site (simplified: id, name, slug, sku, status, in_stock, on_sale, price, effective_price, stock, reserved_quantity, uses_variants, variants_count, translations, created_at, updated_at). Read-only. Same shape as the voog://products resource — consistent across the tools and resources surfaces. For per-variant stock on a variant-bearing product, follow up with product_get. Pass |
| product_getA | Get full product details by id, including the per-variant |
| product_updateA | Update a product. Three argument shapes (combinable):
|
| product_createA | Create a new product (POST /products on ecommerce v1). Required: name, slug, price (Voog rejects POST without these). Three argument shapes (combinable):
|
| product_deleteA | Delete a product (DELETE /admin/api/ecommerce/v1/products/{id}). IRREVERSIBLE — Voog does not retain deleted products. Requires force=true; without it the call is rejected to prevent accidental deletion. Run products_list or product_get first to confirm the id, and site_snapshot if the product might be needed later. |
| product_duplicateA | Duplicate a product (POST /admin/api/ecommerce/v1/products/{id}/duplicate). The new product inherits status='draft' per Voog default — call product_update(status='live') after editing if the duplicate should be public. Returns the new product's full payload; summary surfaces new_id and new title for easy chaining into product_update. |
| products_bulk_actionA | Apply the same actions to many products in one request (PUT /admin/api/ecommerce/v1/products). This is NOT per-row arbitrary updates — every product in target_ids receives every action in actions. For one-off varied edits use product_update. Request shape:
Response: {counters: {processed, failed}, processed_ids, failed_ids}. Duplicate ids in target_ids are collapsed server-side. No empirical batch-size cap observed up to 1001 ids (Stella, 2026-05-27); send what you need. |
| product_set_imagesA | Replace a product's images. Gallery ORDER is applied by re-reading it back and repeating the PUT: Voog lands the requested order only about half the time on the first write (200 either way). If the order still has not taken, the call comes back as an ERROR carrying |
| voog_admin_api_readA | Read-only Admin API passthrough. Forward a GET request to https:///admin/api. Use this when no typed read tool covers the endpoint (forms, tickets, tags, media_sets, etc.). Read-only — MCP hosts may skip the destructive-action confirmation prompt. |
| voog_ecommerce_api_readA | Read-only Ecommerce v1 API passthrough. Forward a GET request to https:///admin/api/ecommerce/v1. Supports ?include=... and ?language_code=.... Read-only — MCP hosts may skip the destructive-action confirmation prompt. |
| voog_admin_api_callA | Generic Admin API WRITE passthrough. Forward an HTTP request to https:///admin/api using the configured site's API token. method ∈ {POST, PUT, PATCH, DELETE}; body is JSON-serialised on POST/PUT/PATCH. Use this when no typed tool covers the endpoint (orders, forms, tickets, elements, tags, media_sets, webhooks, etc.). Conservative annotations (destructiveHint=true) — Claude will confirm before calling. For READS use voog_admin_api_read — this tool no longer accepts method='GET' (removed in v1.5). ⚠️ ⚠️ Ordered |
| voog_ecommerce_api_callA | Generic Ecommerce v1 API WRITE passthrough. Forward an HTTP request to https:///admin/api/ecommerce/v1. Same shape as voog_admin_api_call, different base URL. Supports ?include=... and ?language_code=... per Voog ecommerce conventions. Use for orders, carts, discounts, shipping_methods, gateways, cart_fields, cart_rules, delivery_provider_configs, templates, bulk product actions, products imports, etc. For READS use voog_ecommerce_api_read — this tool no longer accepts method='GET' (removed in v1.5). PUT gotchas (Voog ecommerce v1 quirks — typed tools handle these for you, passthrough does not):
|
| redirects_listA | List all redirect rules on the Voog site (id, source, destination, redirect_type, active). Read-only. |
| redirect_addA | Add a redirect rule. source/destination are paths (e.g. /old → /new). redirect_type defaults to 301; allowed: 301, 302, 307, 410. Set regexp=true to treat source as a regex pattern. Set active=false to create the rule disabled. For 410 (Gone), destination is semantically meaningless — Voog still stores it but never redirects there; pass any value (e.g. source path). |
| redirect_updateA | Update an existing redirect rule. At least one of source, destination, redirect_type, active, regexp must be supplied. redirect_type ∈ {301, 302, 307, 410}. Reversible by calling again with previous values. Voog's PUT /redirect_rules/{id} is full-replace — missing fields are coerced to defaults (e.g. active flips to True). The tool GETs the current rule, merges your updates, then PUTs the full envelope, so unspecified fields are preserved. |
| redirect_deleteA | Delete a redirect rule. Refuses without force=true. Reversible only by re-creating the rule via redirect_add. |
| voog_searchA | Full-text search across the site's published content ( |
| shipping_methods_listA | List all shipping methods (GET /admin/api/ecommerce/v1/shipping_methods). Read-only. Response includes the full options[] nested list for parcel-machine carriers (Omniva, SmartPost, …) — expect multi-KB payloads per method. |
| gateways_listA | List all payment gateways (GET /admin/api/ecommerce/v1/gateways). Read-only. Each entry has code, name, enabled, enabled_methods[], all_payment_methods[], url, created_at, updated_at. |
| site_getA | Get the site singleton (title, code, data, languages, ...). Read-only. |
| site_updateA | Update site singleton. attributes: flat root-level fields. site.code is immutable once set — passing it raises an error. For per-key data, use site_set_data. |
| site_set_dataA | Set site.data. to a value (PUT /site/data/{key}). To delete a key use site_delete_data. 'internal_*' keys are server-protected and refused client-side. |
| site_delete_dataA | Delete site.data. (DELETE /site/data/{key}). IRREVERSIBLE — the key is removed from site.data permanently. Requires force=true; without it the call is rejected. 'internal_*' keys are server-protected and refused client-side. |
| pages_snapshotA | Backup all pages + per-page contents to JSON files in output_dir. Creates the directory (and parents) if needed; overwrites existing pages.json. Lighter than site_snapshot — use this when you only need page structure and contents. |
| site_snapshotA | Comprehensive read-only backup of every mutable Voog resource: pages, articles, elements, layouts, layout_assets, languages, redirect_rules, nodes, texts, content_partials, tags, forms, media_sets, assets, webhooks, site, me, products (with translations + variant_types), per-page contents, per-article details, per-product details, and rendered HTML samples for VoogStyle capture. By default REFUSES to overwrite an existing directory — pick a fresh location. Pass overwrite=true to write into an existing directory (automation/cron use case); files from a prior snapshot may persist alongside new files if the underlying Voog state has shrunk. REQUIRED pre-flight before any risky operation: layout rename, mass push, layout swap, VoogStyle template push, page_delete. Writes _meta.json manifest to output_dir documenting voog-mcp version, attempted/succeeded/skipped/failed endpoints, request_count, duration_seconds, and (if the snapshot aborted mid-run) aborted_reason. Restore tooling reads this to refuse partial snapshots. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| Articles | All blog articles on the Voog site (simplified: id, title, path, public_url, published, published_at, updated_at, created_at, language_code, page_id — without bodies). Single article body (rendered HTML) at voog://{site}/articles/{id} as text/html. |
| Layouts | All layouts on the Voog site (simplified: id, title, component, content_type, updated_at — without bodies). Single layout body (raw .tpl source) at voog://{site}/layouts/{id} as text/plain. |
| Pages | All pages on the Voog site (simplified: id, path, title, hidden, layout, content_type, language, public_url). Per-page details available at voog://{site}/pages/{id}, page contents at voog://{site}/pages/{id}/contents. |
| Products | All ecommerce products on the Voog site (simplified: id, name, slug, sku, status, in_stock, on_sale, price, effective_price, stock, reserved_quantity, uses_variants, variants_count, translations, created_at, updated_at). Full product details with per-variant stock at voog://{site}/products/{id}. |
| Redirect rules | All redirect rules on the Voog site (id, source, destination, redirect_type, active). |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/runnel/voog-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server