Skip to content

fix: sync plugin with the real MCP server and extension parity - #2

Merged
ArnasDon merged 1 commit into
mainfrom
fix/sync-with-mcp-server-and-extension
Aug 6, 2026
Merged

fix: sync plugin with the real MCP server and extension parity#2
ArnasDon merged 1 commit into
mainfrom
fix/sync-with-mcp-server-and-extension

Conversation

@ArnasDon

@ArnasDon ArnasDon commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Why

The plugin was last touched on 2026-05-27. Since then hostinger-api-mcp moved to 1.29.0 (289 tools, 12 binaries) and the VS Code extension moved to 1.3.2. Some of the drift is cosmetic, but several parts of the plugin are non-functional as shipped — not merely dated.

The two repos are different kinds of artifact (a TypeScript extension with a sidebar and auth flow vs. a declarative plugin), so this doesn't chase feature parity. It fixes what's broken and aligns the three things that genuinely overlap: MCP wiring, the auth story, and tool names.

The three real defects

1. Every tool name in the rules, skills, agent, and command was invented

The plugin instructed the agent to call list_hosting_plans, create_nodejs_deployment, list_dns_records, create_dns_snapshot, query_logs, restore_backup, get_php_error_log and others. None of these have ever existed on the MCP server — searching api-mcp-server for them returns zero matches. Real names are OpenAPI operation IDs: hosting_listWebsitesV1, DNS_getDNSRecordsV1, billing_getSubscriptionListV1.

All 104 tool references are now real and verified in CI.

2. The token-leak hook never fired

hooks/hooks.json didn't match Cursor's hook schema on any axis: it was missing version, used an array where an object keyed by event name is expected, used script instead of command, and set "trigger": "pre-commit" — which isn't a Cursor hook event at all, since git commits aren't an agent lifecycle event. Meanwhile the README promised users it blocked leaks.

Now a beforeShellExecution hook matching git commit, with the script speaking the hook JSON protocol on stdin/stdout. Tested against five cases: clean repo, staged token, token in a .md, placeholder value, and outside a git repo.

It fails open by design. A path-resolution problem in a plugin distributed to many users would otherwise block every git commit they make; failing open degrades to today's behaviour (no protection) rather than something worse.

3. Guidance described APIs that don't exist

  • No framework presets. rules/framework-presets.mdc invented seven preset names. The real app_type override accepts only create-react-app, vite, angular, react, vue, parcel, express, fastify, nest — everything else is auto-detected from package.json. Replaced by rules/nodejs-deployments.mdc with the real overrides (node_version 18/20/22/24, package_manager, root_directory, output_directory, build_script, entry_file) and the 50 MB archive limit.
  • DNS is zone-oriented, not per-record. DNS_updateDNSRecordsV1 takes a whole zone array plus an overwrite flag, and there is no tool to create a snapshot on demand — so the old "snapshot before changing" step was impossible. The skill now explains overwrite semantics (the difference between silently duplicating and silently deleting records), uses DNS_validateDNSRecordsV1 as a dry run, and cites an existing snapshot ID for rollback.
  • No access or error logs. query-hosting-logs promised 4xx/5xx breakdowns and PHP fatals; the API exposes neither. Renamed query-deployment-logs, scoped to JS deployment logs, Node.js build logs, and cron output. The plugin now states plainly what's hPanel-only.

Alignment with the extension

mcp.json started a single hostinger-api-mcp, loading all 289 tools into context at once — the exact problem the extension's split solves. It now registers eight per-product servers mirroring the extension's groups, using the same server keys, so users can disable areas from Cursor's MCP settings.

Two more fixes there:

  • Dropped the ${HOSTINGER_API_TOKEN} interpolation. OAuth shipped in extension 1.1.0 on 2026-05-29 — two days after this repo's last commit — and the README still claimed it was "not supported by the Hostinger backend". The MCP server signs in via browser automatically on the first authenticated tool call when the variable is absent, so hardcoding it risked shadowing that fallback with a literal unexpanded string. An exported token still takes precedence.
  • Added USER_AGENT (plugin;cursor;<version>), matching the extension's attribution. Plugin traffic was previously invisible to Hostinger.

Preventing recurrence

scripts/check-tool-names.mjs validates every tool-shaped identifier in the docs against scripts/mcp-tools.json, a checked-in catalog so the check runs offline.

The design choice worth reviewing: it default-denies unknown snake_case identifiers rather than validating known prefixes. A prefix check would have missed this entire bug, because the fabricated names had no prefix at all. Non-tool identifiers (app_type, node_modules, public_html, …) live in an explicit allowlist. Verified by reintroducing list_hosting_plans, create_dns_snapshot, and query_logs — all three are caught.

It also asserts each mcp.json binary maps to a real tool group, and that USER_AGENT tracks the version in plugin.json.

.github/workflows/ci.yml runs both validators, parses every JSON file, shellchecks the hook, and checks it's executable. A second advisory job (continue-on-error) flags when the catalog snapshot falls behind hostinger-api-mcp@latest without failing unrelated PRs.

Also

  • repository.url in plugin.json pointed at hostinger/api-mcp-server.
  • The README's "Links" sent people to the Open VSX listing for the extension as if it were the plugin. Now correctly labelled, alongside a warning that running both in Cursor duplicates all eight servers and ~200 tools, since the extension writes ~/.cursor/mcp.json too.
  • Product naming matches the extension's June regrouping (Websites / Email Marketing / Subscriptions & Payments, DNS under Domains).
  • Added the LICENSE file that plugin.json has always declared MIT.

Verification

All green locally:

Validation passed.
Tool-name check passed: 104 distinct tools referenced, all present in hostinger-api-mcp@1.29.0.
MCP binary check passed: 8 servers map to real tool groups.
shellcheck clean

Open question for reviewers

hostinger-api-mcp also publishes hostinger-mail-mcp (38 tools) and hostinger-agency-hosting-mcp (27), which neither this plugin nor the extension wires up. hostinger-horizons-mcp was added to the extension in hostinger/hostinger-vscode#32 and removed again in hostinger/hostinger-vscode#37. I left all three out to keep this PR at parity rather than ahead of the extension — worth deciding separately whether they should be exposed in both.

The plugin was last touched on 2026-05-27 and had drifted from both
hostinger-api-mcp (now 1.29.0) and the VS Code extension (1.3.2). Several
parts were not merely stale but non-functional.

Every Hostinger tool name in the rules, skills, agent, and command was
invented. The plugin told the agent to call list_hosting_plans,
create_nodejs_deployment, list_dns_records, create_dns_snapshot,
query_logs and others, none of which the MCP server has ever exposed. All
104 references now use the real OpenAPI operation IDs.

The token-leak hook never fired: hooks.json used a "pre-commit" trigger,
which is not a Cursor hook event, plus an array shape and a "script" key
the v1 schema does not read. It is now a beforeShellExecution hook that
matches git commit and speaks the hook JSON protocol, failing open so a
guard that cannot read the staged diff does not block every commit.

Deployment guidance described an API that does not exist. There is no
framework preset parameter; the real app_type override accepts only
create-react-app, vite, angular, react, vue, parcel, express, fastify and
nest, with everything else auto-detected. DNS guidance assumed per-record
tools, but the API is zone-oriented with an overwrite flag and no
on-demand snapshot creation. query-hosting-logs promised access and error
logs the API does not expose, so it is now query-deployment-logs, scoped
to build, deployment and cron logs.

mcp.json now registers eight per-product servers mirroring the extension's
groups instead of one monolith loading all 289 tools, drops the fragile
${HOSTINGER_API_TOKEN} interpolation that shadowed the OAuth fallback, and
sets USER_AGENT so plugin traffic is attributable.

To stop the tool-name class of bug recurring, check-tool-names.mjs
validates every tool-shaped identifier in the docs against a checked-in
catalog. It default-denies unknown snake_case names rather than checking
known prefixes, because the fabricated names had no prefix at all. CI runs
it alongside the manifest validator, JSON parsing and shellcheck.
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The plugin release updates Hostinger service coverage, MCP server configuration, authentication, safety rules, operational workflows, validation tooling, CI, documentation, and licensing.

Changes

Hostinger plugin platform

Layer / File(s) Summary
MCP routing and operation safety
.cursor-plugin/plugin.json, mcp.json, hooks/*, scripts/check-no-token-leak.sh, rules/confirm-destructive-actions.mdc, rules/prefer-mcp-tools.mdc, README.md
The plugin now uses eight product-specific MCP servers, OAuth-first authentication, expanded destructive-action checks, and a fail-open Cursor token-leak hook.
Tool catalog validation and CI
scripts/mcp-tools.json, scripts/sync-mcp-tools.mjs, scripts/check-tool-names.mjs, .github/workflows/ci.yml, README.md
The repository adds an MCP catalog, catalog generation, tool-reference validation, server mapping checks, version checks, and CI jobs.
Deployment, status, and log workflows
agents/hostinger-deployment-reviewer.md, commands/hostinger-status.md, rules/nodejs-deployments.mdc, skills/deploy-nodejs-app/*, skills/diagnose-build-failure/*, skills/query-deployment-logs/*
Deployment, status, diagnosis, and log workflows now use current Hostinger tools, supported overrides, polling, and documented API limitations.
DNS and WordPress workflows
skills/manage-dns-records/*, skills/troubleshoot-wordpress/*
DNS guidance now uses zone payloads, validation, snapshots, and verification. WordPress guidance adds product-specific diagnosis and controlled remediation.
Release metadata and documentation
CHANGELOG.md, LICENSE, README.md
The release adds version 0.2.0 notes, an MIT license, expanded service documentation, installation requirements, development checks, and updated links.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant hostinger-status
  participant HostingMCP
  participant DomainsMCP
  participant VPSMCP
  participant BillingMCP
  User->>hostinger-status: Request read-only account status
  par Query enabled services
    hostinger-status->>HostingMCP: Query websites and deployments
    hostinger-status->>DomainsMCP: Query domains
    hostinger-status->>VPSMCP: Query VPS state
    hostinger-status->>BillingMCP: Query subscriptions
  end
  HostingMCP-->>hostinger-status: Return hosting data
  DomainsMCP-->>hostinger-status: Return domain data
  VPSMCP-->>hostinger-status: Return VPS data
  BillingMCP-->>hostinger-status: Return subscription data
  hostinger-status-->>User: Render compact sections and attention markers
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: synchronizing the plugin with the real MCP server and matching extension behavior.
Description check ✅ Passed The description directly explains the tool, hook, API guidance, MCP configuration, validation, and extension-alignment changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/sync-with-mcp-server-and-extension

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ArnasDon
ArnasDon requested a review from a team August 6, 2026 11:36
@ArnasDon
ArnasDon merged commit 79efd15 into main Aug 6, 2026
2 of 3 checks passed
@ArnasDon
ArnasDon deleted the fix/sync-with-mcp-server-and-extension branch August 6, 2026 11:41

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 18

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 3-12: Harden the CI workflow by declaring read-only contents
permissions for the workflow and setting persist-credentials to false on both
checkout steps using actions/checkout@v4. Apply the same checkout configuration
in the duplicated checkout location.

In `@CHANGELOG.md`:
- Line 10: Update scripts/check-no-token-leak.sh to fail closed whenever it
cannot obtain or parse the staged diff, including unavailable git, non-work-tree
state, unreadable git diff --cached output, or malformed hook JSON/stdin; return
the blocking result through the existing hook protocol while preserving normal
token-scan behavior.

In `@commands/hostinger-status.md`:
- Line 21: Update the hostinger status snapshot handling so only the specific
case where a configured server is disabled is marked unavailable and skipped.
Preserve and surface authentication, permission, timeout, and API errors in
their affected sections instead of treating all MCP request failures as
unavailable or aborting the entire snapshot.

In `@LICENSE`:
- Around line 9-10: Remove the Hostinger Terms of Service acceptance clause and
its URL from LICENSE, leaving only the canonical MIT license text. Do not add
replacement licensing language; keep any ToS reference outside the license file.

In `@mcp.json`:
- Line 5: Update every hostinger-api-mcp entry in the mcp.json command
arguments, including the shown hostinger-hosting-mcp entry, replacing the
`@latest` package tag with `@1.29.0` so all eight commands match the catalog
version.

In `@README.md`:
- Around line 31-33: Add language identifiers to the affected Markdown fences:
use text or console for the /add-plugin fence in README.md (31-33), text for the
checklist fence in agents/hostinger-deployment-reviewer.md (32-40), and text for
the output fence in commands/hostinger-status.md (25-45).
- Around line 76-93: The runtime package version and tool catalog version are
inconsistent. Update the MCP configuration and validation flow so Cursor
launches and CI validates the same exact hostinger-api-mcp version recorded in
scripts/mcp-tools.json (currently 1.29.0), replacing the floating latest
reference or resolving it from that shared version.

In `@rules/confirm-destructive-actions.mdc`:
- Around line 71-73: Replace the name-prefix exemption in the “Read-only is
safe” section with an explicit catalog of approved read-only tools or required
read-only catalog metadata, so arbitrary tools named list*, get*, show*, check*,
or validate* cannot bypass confirmation. Retain DNS_validateDNSRecordsV1 as an
approved entry and document that it has no side effects and serves as the dry
run for DNS_updateDNSRecordsV1.

In `@rules/nodejs-deployments.mdc`:
- Around line 32-34: Replace the archive command with a tested file-list
generation step that honors .gitignore, then apply explicit exclusions for all
documented build-output directories and secret files, including .env.local. Keep
the resulting archive example consistent with the exclusions described in Lines
26-29 and prevent ignored credentials or generated files from being included.

In `@rules/prefer-mcp-tools.mdc`:
- Around line 22-37: Update the “Which server to use” guidance to route requests
by the operation ID and server mapping, explicitly treating the shared hosting_
prefix as ambiguous. Clarify that WordPress operation IDs must use
hostinger-wordpress, while non-WordPress hosting operations use
hostinger-hosting, preventing agents from selecting the wrong server.

In `@scripts/check-no-token-leak.sh`:
- Around line 37-38: Update the staged-file handling in the token-leak hook so
filenames are JSON-encoded before interpolation into the agent_message response,
preserving valid JSON for quotes and control characters. Alternatively, remove
the dynamic files list from the response; keep the existing token-blocking
behavior unchanged.

In `@scripts/check-tool-names.mjs`:
- Around line 21-24: Align the MCP server runtime package version with the
catalog’s validated hostinger-api-mcp@1.29.0 by updating every configured server
entry to use that exact version instead of latest. Ensure all entries checked by
the catalog validation flow, including the additional server configuration,
remain pinned consistently.

In `@skills/deploy-nodejs-app/SKILL.md`:
- Line 26: Update step 2 in the deployment instructions so build-output
directories are excluded only for server-built Node.js deployments. For the
hosting_deployStaticWebsite path, retain the finished files from dist, build, or
out in the archive while continuing to exclude node_modules, .git, and .env and
enforce the 50 MB limit.

In `@skills/manage-dns-records/SKILL.md`:
- Around line 52-60: Update the Deleting and Rolling back guidance for
DNS_deleteDNSRecordsV1 and DNS_restoreDNSSnapshotV1 to require explicit
confirmation immediately before each call. Instruct the assistant to show the
exact deletion filters or snapshot target before requesting confirmation; keep
DNS_getDNSSnapshotV1 inspection separate from approval and retain the existing
DNS_updateDNSRecordsV1 confirmation guidance.

In `@skills/query-deployment-logs/SKILL.md`:
- Around line 34-35: Update the reporting guidance in the “Summarize rather than
dumping” section so the final 20 log lines are redacted for credentials and
sensitive environment values before being quoted verbatim. Preserve the existing
requirement to report those lines for failures.

In `@skills/troubleshoot-wordpress/SKILL.md`:
- Around line 57-63: Update the “Confirm before” list to include
hosting_updatePHPExtensionsV1, hosting_updatePHPOptionsV1, and
hosting_updateHostingerWordPressPluginV1 alongside the existing high-impact
update operations, preserving the explicit confirmation requirement for each.
- Line 55: Update the plugin isolation procedure to reactivate a plugin with
hosting_activateWordPressPluginV1 only if the symptom persists while it is
disabled. Keep the plugin deactivated when its removal resolves the symptom,
identify it as the confirmed suspect, and preserve the requirement to announce
the plugin and affected feature before deactivation.
- Around line 45-47: Update the troubleshooting steps for cacheless mode,
Memcached object cache, and maintenance mode to inspect each setting’s current
state before invoking its toggle tool. Call hosting_toggleCachelessModeV1,
hosting_toggleMemcachedObjectCacheV1, and hosting_toggleMaintenanceModeV1 only
when the observed state differs from the intended troubleshooting state;
otherwise leave the setting unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 34491975-2ba2-465a-9646-4612f1ffa0b9

📥 Commits

Reviewing files that changed from the base of the PR and between 037cda9 and d460ab2.

📒 Files selected for processing (23)
  • .cursor-plugin/plugin.json
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • LICENSE
  • README.md
  • agents/hostinger-deployment-reviewer.md
  • commands/hostinger-status.md
  • hooks/hooks.json
  • mcp.json
  • rules/confirm-destructive-actions.mdc
  • rules/framework-presets.mdc
  • rules/nodejs-deployments.mdc
  • rules/prefer-mcp-tools.mdc
  • scripts/check-no-token-leak.sh
  • scripts/check-tool-names.mjs
  • scripts/mcp-tools.json
  • scripts/sync-mcp-tools.mjs
  • skills/deploy-nodejs-app/SKILL.md
  • skills/diagnose-build-failure/SKILL.md
  • skills/manage-dns-records/SKILL.md
  • skills/query-deployment-logs/SKILL.md
  • skills/query-hosting-logs/SKILL.md
  • skills/troubleshoot-wordpress/SKILL.md
💤 Files with no reviewable changes (2)
  • rules/framework-presets.mdc
  • skills/query-hosting-logs/SKILL.md

Comment thread .github/workflows/ci.yml
Comment on lines +3 to +12
on:
pull_request:
push:
branches: [main, master]

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Restrict token access in this workflow.

This workflow executes repository code from pull requests but relies on repository-default GITHUB_TOKEN permissions. Both checkout steps also persist credentials. Limit the token to read-only contents access and disable credential persistence.

Proposed workflow hardening
 on:
   pull_request:
   push:
     branches: [main, master]

+permissions:
+  contents: read
+
 jobs:
   validate:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v4
+        with:
+          persist-credentials: false
...
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v4
+        with:
+          persist-credentials: false

Also applies to: 46-46

🧰 Tools
🪛 zizmor (1.29.0)

[warning] 12-12: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 3 - 12, Harden the CI workflow by
declaring read-only contents permissions for the workflow and setting
persist-credentials to false on both checkout steps using actions/checkout@v4.
Apply the same checkout configuration in the duplicated checkout location.

Source: Linters/SAST tools

Comment thread CHANGELOG.md
### Fixed

- **Every Hostinger tool name in the rules, skills, agent, and command was invented.** The plugin instructed the agent to call `list_hosting_plans`, `create_nodejs_deployment`, `list_dns_records`, `create_dns_snapshot`, `query_logs`, `restore_backup`, and others — none of which the MCP server has ever exposed. All 104 tool references now use the real OpenAPI operation IDs (`hosting_listWebsitesV1`, `DNS_getDNSRecordsV1`, `billing_getSubscriptionListV1`, …) and are verified in CI.
- **The token-leak hook never ran.** `hooks/hooks.json` used a `pre-commit` trigger, which is not a Cursor hook event, along with an array shape and a `script` key that Cursor's v1 schema doesn't read. It is now a `beforeShellExecution` hook matching `git commit`, and the script speaks the hook JSON protocol on stdin/stdout. It fails open, so a guard that can't read the staged diff won't block every commit.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail
rg -n -C 5 'beforeShellExecution|git commit|fail|exit|staged|diff' \
  hooks/hooks.json scripts/check-no-token-leak.sh

Repository: hostinger/hostinger-cursor-plugin

Length of output: 3953


Fail closed when the staged diff cannot be read.

scripts/check-no-token-leak.sh lets commits pass on git unavailable, non-work-tree state, unreadable git diff --cached, or malformed JSON/stdin. Since the hook fails open, these cases bypass token scanning. Use fail-close behavior for input failures, or narrow/suppress fail-open cases and add tests for them.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CHANGELOG.md` at line 10, Update scripts/check-no-token-leak.sh to fail
closed whenever it cannot obtain or parse the staged diff, including unavailable
git, non-work-tree state, unreadable git diff --cached output, or malformed hook
JSON/stdin; return the blocking result through the existing hook protocol while
preserving normal token-scan behavior.

2. Render as compact sections — do not paginate.
3. Flag anything that needs attention with `[!]`: a failed deployment, a disabled website, a stopped VPS, or a subscription renewing within 30 days without auto-renewal.

If a server isn't enabled in the user's Cursor MCP settings, its section will error. Note the section as unavailable and carry on — don't abort the whole snapshot.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files matching hostinger-status:"
fd -i 'hostinger-status' . || true

echo
echo "Search relevant symbols:"
rg -n "hostinger-status|Hostinger|server isn't enabled|unavailable|Cursor MCP settings|timeout|authentication|permission|API" . -S || true

Repository: hostinger/hostinger-cursor-plugin

Length of output: 19918


🌐 Web query:

hostinger-api-mcp disabled server timeout authentication error handling

💡 Result:

If you are experiencing authentication errors, connection timeouts, or service issues with the Hostinger API Model Context Protocol (MCP) server, please follow the troubleshooting steps outlined below. Authentication Errors - Unauthorized (401) or Authentication Errors: These typically indicate that your session has expired, the token was revoked, or the credentials are invalid [1][2]. - Troubleshooting Steps: Run the Hostinger: Disconnect command in your IDE to clear all stored credentials [1][3]. Re-authenticate using the recommended OAuth flow, or if you are using an API token, generate a fresh one via hPanel (Account → API) and ensure it is set correctly in your environment variables without leading or trailing spaces [1][4][2]. - Environment Variables: When using an API token, ensure it is set via the HOSTINGER_API_TOKEN environment variable (note that API_TOKEN is a deprecated alias) [5][6]. Connection Timeouts and Setup Issues - Connection Timeouts: Often caused by environmental or network issues. Verify that you have a stable internet connection and that your system meets requirements, such as running a modern version of Node.js (v20+) [1][2]. - OAuth Sign-in Timeouts: The browser-based OAuth flow must be completed within 3 minutes [1]. If the browser fails to open, manually copy the sign-in link printed in your terminal [1]. Ensure that you do not close any terminal windows explicitly opened for the "Hostinger OAuth" process on Windows, as this will cancel the flow [1]. - Transport Modes: The Hostinger MCP server supports both stdio (default) and HTTP transport modes [5][7]. Note that OAuth sign-in is not supported in --http mode; if you use the --http flag, you must provide a valid HOSTINGER_API_TOKEN [5][6]. General Troubleshooting - Debugging: You can enable verbose logging by setting the DEBUG environment variable to true to help identify specific failure points [5][7]. - Rate Limits: If you receive a 429 Too Many Requests response, you have exceeded API rate limits [8][9]. Reduce your request frequency, as repeated violations may lead to temporary IP blocks [8]. - Verification: Ensure the MCP server is correctly installed globally (e.g., npm install -g hostinger-api-mcp) and that your AI client (Claude Desktop, Cursor, etc.) has been restarted after any configuration changes [2]. If issues persist, consult the official Hostinger Connector troubleshooting documentation or contact Hostinger support for further assistance [1][4].

Citations:


🌐 Web query:

github hostinger/api-mcp-server error handling unavailable section disabled server

💡 Result:

There is no specific issue or official documentation within the hostinger/api-mcp-server project that refers to an "error handling unavailable section disabled server" error. The phrasing you mentioned likely conflates general MCP error handling patterns or issues from other MCP server implementations [1][2][3] with the Hostinger MCP server's actual operations. Here is a clarification of how error handling and server availability function within the hostinger/api-mcp-server ecosystem: 1. Standard Hostinger API Errors: The Hostinger API returns standard HTTP status codes (e.g., 403 for permission issues, 404 for missing resources, 422 for invalid requests) with a JSON response containing an error field and a correlation_id for support tracking [4]. The hostinger/api-mcp-server passes these underlying API errors back to the MCP client [5][6]. 2. Tool Availability and Server State: While the hostinger/api-mcp-server documentation does not have a specific "disabled" mode for its internal tools, the Model Context Protocol (MCP) specification and related community discussions (such as SEP-2140) emphasize that servers should report "Tool not callable" errors when a tool is unavailable, disabled, or policy-restricted [3]. This is a protocol-level recommendation, not a bug specific to Hostinger. 3. Common Configuration Errors: Users of the hostinger/api-mcp-server often encounter issues related to: - Authentication: Ensure HOSTINGER_API_TOKEN (or the deprecated APITOKEN) is correctly set in your environment [5][7][8]. OAuth is not supported in --http mode [5][7]. - Resource Pathing: Certain tools (like hosting_deployStaticWebsite) require specific path formats, such as prefixing archive paths with public_html/ [9]. - Feature Availability: Some features, such as "Patch Node.js Vulnerabilities," are only available on specific hosting plans (Business/Cloud) and require a connected GitHub repository [5][10]. If you are experiencing an error where a server section appears "unavailable" or "disabled," it is likely a client-side display issue (e.g., in Claude Desktop or an n8n workflow) where the server has failed to authenticate or initialize correctly, rather than a built-in "disabled server" state within the code [11][12]. Check your logs by enabling the DEBUG=true environment variable to see the exact API response being returned by the Hostinger service [5][7].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "README section around hostinger-status command:"
fd -i '^README\.md$' . -x sed -n '120,145p' {} \;

echo
echo "Exact command file:"
cat -n commands/hostinger-status.md | sed -n '1,80p'

echo
echo "Search for hostinger-status command implementation or references outside docs:"
rg -n '"hostinger-status"|hostinger-status|/hostinger-status' . -S

Repository: hostinger/hostinger-cursor-plugin

Length of output: 3812


Surface failed MCP requests instead of marking every missing section unavailable.

Only suppress the enabled-but-disabled-server case. Render authentication, permission, timeout, and API failures in the affected section so users can fix the broken account connection.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@commands/hostinger-status.md` at line 21, Update the hostinger status
snapshot handling so only the specific case where a configured server is
disabled is marked unavailable and skipped. Preserve and surface authentication,
permission, timeout, and API errors in their affected sections instead of
treating all MCP request failures as unavailable or aborting the entire
snapshot.

Comment thread LICENSE
Comment on lines +9 to +10
By using this plugin you agree to Hostinger's Terms of Service:
https://www.hostinger.com/legal/universal-terms-of-service-agreement

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== LICENSE =="
if [ -f LICENSE ]; then
  cat -n LICENSE
else
  echo "LICENSE not found"
fi

echo
echo "== candidate license/toc files =="
git ls-files | rg -i '(^|/)(LICENSE|license|README\.md|readme\.md|terms|terms-of-service|hostinger)' | head -100

echo
echo "== references to Hostinger Terms of Service / license type =="
rg -n -i "hostinger.*terms|terms of service|mit license|license" -S -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**' | head -200

Repository: hostinger/hostinger-cursor-plugin

Length of output: 1667


🌐 Web query:

MIT license canonical SPDX license text additional restrictions

💡 Result:

The canonical SPDX short identifier for the MIT License is MIT [1][2][3]. The authoritative text for this license is maintained by the Open Source Initiative (OSI) and indexed by the Software Package Data Exchange (SPDX) [1][4][3]. Regarding additional restrictions, the MIT License explicitly grants permission to deal in the software without restriction, provided that the original copyright notice and permission notice are included in all copies or substantial portions of the software [5][4][6]. Because the license requires the inclusion of these specific notices, any attempt to remove or modify them violates the license terms [7]. While the MIT License is permissive and allows for sublicensing—meaning you can incorporate MIT-licensed code into larger works that may be distributed under different or proprietary terms—you cannot remove the original license or copyright notice from the MIT-licensed components themselves [7][8]. Any redistribution of the MIT-licensed code must retain the original notice [4][7]. If you distribute a modified version of the license or add extra conditions that contradict the original permissions, it is no longer the standard MIT License, but rather a custom or modified license [9]. Adding restrictive conditions to the original MIT text or demanding they apply to the original code effectively nullifies the standard MIT grant for that software [10].

Citations:


🌐 Web query:

Hostinger universal terms of service agreement website services plugin terms

💡 Result:

Hostinger's primary legal framework is centered on its Universal Terms of Service Agreement (UTOS) [1][2]. This document establishes the general terms and conditions for using the Hostinger website and all products or services accessed through it [1][2]. Key aspects of Hostinger's legal agreements include: Universal Terms of Service Agreement (UTOS): The UTOS acts as the overarching contract between you and the relevant Hostinger group entity [1][2]. It is incorporated by reference into all other specific product agreements, such as the Hosting Agreement and the Domain Name Registration Agreement [3][4]. If a conflict arises between the UTOS and a specific product agreement, the terms of the specific product agreement typically control [3][5]. Product-Specific Terms: Hostinger utilizes various agreements to govern specific services [2]. For example: - The Hosting Agreement covers the terms for hosting services and explicitly incorporates the UTOS [3][5]. - The Domain Name Registration Agreement governs domain services and incorporates both the UTOS and relevant Registry Policies [4]. - These agreements, along with others like the Refund Policy and Privacy Policy, are part of the broader legal framework that binds users [6][2][7]. Plugin and Third-Party Terms: Hostinger's UTOS contains a specific section regarding Product Specific Terms and Third-Party Products (Section 17) [2]. Because Hostinger often provides access to third-party software (such as plugins or applications via platforms like WordPress), users are typically required to adhere to the terms set forth by those third-party providers in addition to Hostinger's own terms. Compliance and Policy: Users are expected to comply with applicable laws and Hostinger's policies [8]. The use of prohibited items, such as nulled or cracked scripts (often associated with plugins or themes), is strictly forbidden and can result in service suspension under the terms outlined in the UTOS [8]. You can review the official Universal Terms of Service Agreement and related legal documents directly on the Hostinger legal portal [2].

Citations:


Remove the Hostinger ToS clause from LICENSE.

LICENSE should remain the canonical MIT text. The TOU adds an acceptance clause that is not part of MIT and can be read as an additional condition on use of the plugin. Keep Terms of Service language out of the license file and reference it separately only where appropriate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@LICENSE` around lines 9 - 10, Remove the Hostinger Terms of Service
acceptance clause and its URL from LICENSE, leaving only the canonical MIT
license text. Do not add replacement licensing language; keep any ToS reference
outside the license file.

Comment thread mcp.json
"env": {
"HOSTINGER_API_TOKEN": "${HOSTINGER_API_TOKEN}"
}
"args": ["--yes", "--package=hostinger-api-mcp@latest", "hostinger-hosting-mcp"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

jq -r '
  .mcpServers
  | to_entries[]
  | "\(.key): \(.value.args[] | select(startswith("--package=hostinger-api-mcp@")))"
' mcp.json

rg -n -C2 'hostinger-api-mcp@|1\.29\.0' \
  mcp.json scripts/sync-mcp-tools.mjs scripts/mcp-tools.json README.md

Repository: hostinger/hostinger-cursor-plugin

Length of output: 4153


Pin every hostinger-api-mcp entry in mcp.json to 1.29.0.

The catalog is checked in as scripts/mcp-tools.json with version: "1.29.0", but the MCP server commands still use --package=hostinger-api-mcp@latest. Pin all eight entries to --package=hostinger-api-mcp@1.29.0 so the plugin runs against the same package/version as the checked-in tool catalog.

Proposed fix
- "--package=hostinger-api-mcp@latest"
+ "--package=hostinger-api-mcp@1.29.0"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"args": ["--yes", "--package=hostinger-api-mcp@latest", "hostinger-hosting-mcp"],
"args": ["--yes", "--package=hostinger-api-mcp@1.29.0", "hostinger-hosting-mcp"],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mcp.json` at line 5, Update every hostinger-api-mcp entry in the mcp.json
command arguments, including the shown hostinger-hosting-mcp entry, replacing
the `@latest` package tag with `@1.29.0` so all eight commands match the catalog
version.

Comment on lines +52 to +60
## Deleting

## Validation
`DNS_deleteDNSRecordsV1` filters by name and type, and removes *all* records matching each filter. To drop only some of several records sharing a name and type, use `DNS_updateDNSRecordsV1` with `overwrite: true` and the records you want to keep.

- Reject syntactically invalid records before calling the API:
- A → IPv4 only.
- AAAA → IPv6 only.
- CNAME → cannot coexist with other records on the same name.
- MX → must reference a hostname, not an IP.
- TXT → quote-escape inner double quotes.
- Warn if TTL is below 300s (propagation thrash) or above 86400s (slow recovery).
`DNS_resetDNSRecordsV1` returns the entire zone to Hostinger defaults. It is not a targeted delete — treat it as a last resort and confirm explicitly.

## Confirm before
## Rolling back

- Deleting any record (always).
- Replacing all MX records (mail delivery risk).
- Changing NS records (delegation change — can break the domain).
- Changing the A/AAAA record of the apex (`@`) — site downtime risk.
`DNS_restoreDNSSnapshotV1` with the domain and a snapshot ID from `DNS_getDNSSnapshotListV1`. Inspect a snapshot's contents first with `DNS_getDNSSnapshotV1` so the user knows what state they're reverting to.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Gate DNS deletion and snapshot restoration with explicit confirmation.

DNS_deleteDNSRecordsV1 and DNS_restoreDNSSnapshotV1 can remove or replace zone state. Require the assistant to show the exact filters or snapshot target and wait for explicit confirmation immediately before each call. The current confirmation step is scoped to DNS_updateDNSRecordsV1, and snapshot inspection alone is not approval.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/manage-dns-records/SKILL.md` around lines 52 - 60, Update the Deleting
and Rolling back guidance for DNS_deleteDNSRecordsV1 and
DNS_restoreDNSSnapshotV1 to require explicit confirmation immediately before
each call. Instruct the assistant to show the exact deletion filters or snapshot
target before requesting confirmation; keep DNS_getDNSSnapshotV1 inspection
separate from approval and retain the existing DNS_updateDNSRecordsV1
confirmation guidance.

Comment on lines +34 to +35
5. Summarize rather than dumping. Report:
- The final state and, for a failure, the first error and the last 20 lines verbatim.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Require redaction before reporting the final log lines.

The report format says to provide the last 20 lines verbatim. The privacy section requires credential redaction before quoting logs. A build log can contain a token or an environment value.

State that the final 20 lines must be redacted before they are quoted.

Proposed fix
-   - The final state and, for a failure, the first error and the last 20 lines verbatim.
+   - The final state and, for a failure, the first error and the last 20 lines after credential redaction.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
5. Summarize rather than dumping. Report:
- The final state and, for a failure, the first error and the last 20 lines verbatim.
5. Summarize rather than dumping. Report:
- The final state and, for a failure, the first error and the last 20 lines after credential redaction.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/query-deployment-logs/SKILL.md` around lines 34 - 35, Update the
reporting guidance in the “Summarize rather than dumping” section so the final
20 log lines are redacted for credentials and sensitive environment values
before being quoted verbatim. Preserve the existing requirement to report those
lines for failures.

Comment on lines +45 to +47
| Changes not appearing | LiteSpeed or website cache serving stale content | `hosting_showLiteSpeedCacheStatusV1`, then `hosting_purgeLiteSpeedCacheV1`; also `hosting_clearWebsiteCacheV1`, and `hosting_toggleCachelessModeV1` while actively debugging |
| Object cache errors after a plugin change | Memcached object cache out of sync | `hosting_showMemcachedObjectCacheStatusV1`, then `hosting_toggleMemcachedObjectCacheV1` |
| Site stuck showing "briefly unavailable" | Maintenance mode left on | `hosting_showMaintenanceStatusV1`, then `hosting_toggleMaintenanceModeV1` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Make toggle operations conditional on the observed state.

hosting_toggleCachelessModeV1, hosting_toggleMemcachedObjectCacheV1, and hosting_toggleMaintenanceModeV1 invert state. Call each tool only when the current state differs from the intended state. Otherwise, the troubleshooting step can disable a correct setting or enable a setting that is causing the issue.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/troubleshoot-wordpress/SKILL.md` around lines 45 - 47, Update the
troubleshooting steps for cacheless mode, Memcached object cache, and
maintenance mode to inspect each setting’s current state before invoking its
toggle tool. Call hosting_toggleCachelessModeV1,
hosting_toggleMemcachedObjectCacheV1, and hosting_toggleMaintenanceModeV1 only
when the observed state differs from the intended troubleshooting state;
otherwise leave the setting unchanged.


## Isolating a plugin conflict

Deactivate one plugin at a time with `hosting_deactivateWordPressPluginV1`, re-test, and reactivate with `hosting_activateWordPressPluginV1` before moving to the next. Say which plugin you're about to disable and what user-facing feature might break. Do not bulk-deactivate a production site without explicit approval.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not always reactivate the plugin before continuing isolation.

If deactivation removes the symptom, reactivating the plugin immediately restores the failure and can hide a plugin conflict. Reactivate it only when the symptom persists after deactivation. Keep a plugin disabled when it is the confirmed suspect.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/troubleshoot-wordpress/SKILL.md` at line 55, Update the plugin
isolation procedure to reactivate a plugin with
hosting_activateWordPressPluginV1 only if the symptom persists while it is
disabled. Keep the plugin deactivated when its removal resolves the symptom,
identify it as the confirmed suspect, and preserve the requirement to announce
the plugin and affected feature before deactivation.

Comment on lines +57 to +63
## Confirm before

- `restore_backup` (overwrites current site).
- `disable_wordpress_plugin` on production (could break a customer-facing feature).
- `update_php_version` (can break themes/plugins that don't support the new version).
- `hosting_deleteWordPressInstallationV1` — destroys the site.
- `hosting_uninstallWordPressPluginsV1`, `hosting_uninstallWordPressThemesV1` — may drop plugin data.
- `hosting_updateWordPressCoreV1`, `hosting_updateWordPressPluginsV1`, `hosting_updateWordPressThemesV1` — can introduce new breakage.
- `hosting_updatePHPVersionV1` — can break themes and plugins that don't support the new version.
- `hosting_toggleMaintenanceModeV1` on production — takes the site offline for visitors.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Include all high-impact update operations in the confirmation list.

Add hosting_updatePHPExtensionsV1, hosting_updatePHPOptionsV1, and hosting_updateHostingerWordPressPluginV1. These operations can change runtime behavior or introduce site breakage, but the current list names only hosting_updatePHPVersionV1 and the standard WordPress update tools. The generic instruction at Line 35 helps, but the explicit safety contract is incomplete.

🧰 Tools
🪛 LanguageTool

[grammar] ~61-~61: Ensure spelling is correct
Context: ...eWordPressThemesV1— can introduce new breakage. -hosting_updatePHPVersionV1` — can b...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/troubleshoot-wordpress/SKILL.md` around lines 57 - 63, Update the
“Confirm before” list to include hosting_updatePHPExtensionsV1,
hosting_updatePHPOptionsV1, and hosting_updateHostingerWordPressPluginV1
alongside the existing high-impact update operations, preserving the explicit
confirmation requirement for each.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants