glippy-mcp 0.3.2 → 0.3.3

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/LICENSE CHANGED
@@ -14,7 +14,7 @@ you a non-exclusive, non-transferable, revocable license to install and
14
14
  use the Software solely for your own internal business or personal use.
15
15
 
16
16
  A valid, paid license key (format: GLMCP-XXXX-XXXX-XXXX) is required to
17
- use the Software. License keys may be purchased at https://glippy.dev.
17
+ use the Software. License keys may be purchased at https://www.glippy.dev.
18
18
  Running the Software without a valid license key, or in a manner that
19
19
  circumvents license verification, is not permitted.
20
20
 
@@ -61,4 +61,4 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
61
61
  This Agreement is governed by the laws of the Netherlands, without regard
62
62
  to its conflict of laws principles.
63
63
 
64
- For license purchases or enquiries: https://glippy.dev
64
+ For license purchases or enquiries: https://www.glippy.dev
package/README.md CHANGED
@@ -78,7 +78,7 @@ npx -y glippy-mcp
78
78
 
79
79
  ### License Key
80
80
 
81
- A valid Glippy MCP license key (`GLMCP-XXXX-XXXX-XXXX`) is required. Get one at [glippy.dev](https://glippy.dev).
81
+ A valid Glippy MCP license key (`GLMCP-XXXX-XXXX-XXXX`) is required. Get one at [glippy.dev](https://www.glippy.dev).
82
82
 
83
83
  The server validates the key against the Glippy API on first use and caches the result for 24 hours. **Analysis runs locally on your machine** — only the license check calls the server.
84
84
 
@@ -300,7 +300,7 @@ Analyse multiple domains in parallel and compare scores.
300
300
 
301
301
  | Parameter | Type | Required | Description |
302
302
  |-----------|------|----------|-------------|
303
- | `domains` | array[string] | Yes | List of 2-10 domains to compare, e.g. `["example.com", "competitor.com"]`. Do not include `https://` prefix. |
303
+ | `domains` | array[string] | Yes | List of 2-50 domains to compare, e.g. `["example.com", "competitor.com"]`. Do not include `https://` prefix. For more than 50 domains, split across multiple runs and merge the results. |
304
304
  | `max_pages` | integer | No | Maximum pages to crawl per domain (1-10). Default: `10`. |
305
305
  | `render_mode` | enum | No | `"static"` (default), `"auto"` (static with Chrome fallback on bot-block), or `"chrome"` (always Chrome). See [Chrome Rendering Fallback](#chrome-rendering-fallback). |
306
306
  | `output_format` | enum | No | `"text"` (default) for comparison table, `"json"` for raw results to pass to `export_bulk_report`. |
@@ -428,7 +428,7 @@ Generate a styled report for bulk analysis.
428
428
  | Parameter | Type | Required | Description |
429
429
  |-----------|------|----------|-------------|
430
430
  | `format` | enum | Yes | Report format: `"markdown"` or `"html"` |
431
- | `domains` | array[string] | No* | Compare 2-10 domains. Do not include `https://`. |
431
+ | `domains` | array[string] | No* | Compare 2-50 domains. Do not include `https://`. For more than 50, run multiple times. |
432
432
  | `urls` | array[string] | No* | Analyse 1-50,000 specific URLs. Include `https://`. |
433
433
  | `sitemap_url` | string | No* | Crawl a sitemap URL. |
434
434
  | `analysis_results` | object | No* | Pre-computed results from `compare_domains`, `analyze_urls`, or `analyze_sitemap` (with `output_format="json"`). |
@@ -734,7 +734,7 @@ echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":
734
734
 
735
735
  **Cause:** Invalid or expired license key.
736
736
 
737
- **Fix:** Get a valid key at [glippy.dev](https://glippy.dev).
737
+ **Fix:** Get a valid key at [glippy.dev](https://www.glippy.dev).
738
738
 
739
739
  ### "Could not reach license server"
740
740
 
@@ -795,16 +795,16 @@ The server checks access rules for these AI crawlers in robots.txt:
795
795
 
796
796
  ## License
797
797
 
798
- See LICENSE file for licensing terms. Get your license key at [glippy.dev](https://glippy.dev).
798
+ See LICENSE file for licensing terms. Get your license key at [glippy.dev](https://www.glippy.dev).
799
799
 
800
800
  ---
801
801
 
802
802
  ## Support
803
803
 
804
804
  - **Integration Guide:** [docs/INTEGRATIONS.md](docs/INTEGRATIONS.md)
805
- - **Online Documentation:** [glippy.dev/docs](https://glippy.dev)
805
+ - **Online Documentation:** [glippy.dev/docs](https://www.glippy.dev)
806
806
  - **Issues:** [github.com/jbobbink/glippy/issues](https://github.com/jbobbink/glippy/issues)
807
- - **Homepage:** [glippy.dev](https://glippy.dev)
807
+ - **Homepage:** [glippy.dev](https://www.glippy.dev)
808
808
 
809
809
  ---
810
810
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glippy-mcp",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "MCP server for GEO (Generative Engine Optimization) analysis — check any domain's AI-readiness",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -26,7 +26,7 @@
26
26
  "claude",
27
27
  "glippy"
28
28
  ],
29
- "homepage": "https://glippy.dev",
29
+ "homepage": "https://www.glippy.dev",
30
30
  "repository": {
31
31
  "type": "git",
32
32
  "url": "git+https://github.com/jbobbink/glippy.git"
package/src/index.js CHANGED
@@ -1609,7 +1609,7 @@ function bulkHTMLScript() {
1609
1609
 
1610
1610
  const server = new McpServer({
1611
1611
  name: "glippy-geo",
1612
- version: "0.1.0",
1612
+ version: "0.3.3",
1613
1613
  });
1614
1614
 
1615
1615
  // ---------------------------------------------------------------------------
@@ -2137,15 +2137,16 @@ server.tool(
2137
2137
  "Analyse multiple domains in parallel and compare their GEO scores side by side. " +
2138
2138
  "Returns a comparison table with overall scores, per-category breakdowns, and a ranked summary. " +
2139
2139
  "Useful for competitive analysis or auditing a portfolio of sites. " +
2140
+ "Accepts up to 50 domains per call - for larger lists, split them across multiple runs and merge the results. " +
2140
2141
  "Requires Pro or Agency tier. " +
2141
2142
  "Use output_format='json' to get raw results that can be passed to export_bulk_report.",
2142
2143
  {
2143
2144
  domains: z
2144
2145
  .array(z.string())
2145
2146
  .min(2)
2146
- .max(10)
2147
+ .max(50, "compare_domains accepts at most 50 domains per call. Split larger lists across multiple runs and merge the results.")
2147
2148
  .describe(
2148
- 'List of domains to compare, e.g. ["example.com", "competitor.com"]. Do not include https:// prefix.'
2149
+ 'List of 2-50 domains to compare, e.g. ["example.com", "competitor.com"]. Do not include https:// prefix. For more than 50 domains, run multiple times and combine the output.'
2149
2150
  ),
2150
2151
  max_pages: z
2151
2152
  .number()
@@ -2178,15 +2179,22 @@ server.tool(
2178
2179
  const maxPages = max_pages ?? 10;
2179
2180
  const renderMode = render_mode ?? "static";
2180
2181
 
2181
- // Run all analyses in parallel
2182
- const results = await Promise.allSettled(
2183
- domains.map((domain) =>
2184
- checkGEO(domain, { maxPages, renderMode }).then((result) => ({
2185
- domain,
2186
- result,
2187
- }))
2188
- )
2189
- );
2182
+ // Cap concurrent domain analyses so a 50-domain × 10-page run does not
2183
+ // fan out into 500 simultaneous fetches.
2184
+ const DOMAIN_CONCURRENCY = 10;
2185
+ const results = [];
2186
+ for (let i = 0; i < domains.length; i += DOMAIN_CONCURRENCY) {
2187
+ const batch = domains.slice(i, i + DOMAIN_CONCURRENCY);
2188
+ const batchResults = await Promise.allSettled(
2189
+ batch.map((domain) =>
2190
+ checkGEO(domain, { maxPages, renderMode }).then((result) => ({
2191
+ domain,
2192
+ result,
2193
+ }))
2194
+ )
2195
+ );
2196
+ results.push(...batchResults);
2197
+ }
2190
2198
 
2191
2199
  // JSON output mode - return raw results for use with export_bulk_report
2192
2200
  if (output_format === "json") {
@@ -3085,10 +3093,10 @@ server.tool(
3085
3093
  domains: z
3086
3094
  .array(z.string())
3087
3095
  .min(2)
3088
- .max(10)
3096
+ .max(50, "export_bulk_report accepts at most 50 domains per call. Split larger lists across multiple runs.")
3089
3097
  .optional()
3090
3098
  .describe(
3091
- 'Compare multiple domains. E.g. ["example.com", "competitor.com"]. Do not include https://.'
3099
+ 'Compare 2-50 domains. E.g. ["example.com", "competitor.com"]. Do not include https://. For more than 50, run multiple times.'
3092
3100
  ),
3093
3101
  urls: z
3094
3102
  .array(z.string())
@@ -3258,14 +3266,20 @@ server.tool(
3258
3266
  // ------------------------------------------------------------------
3259
3267
  if (domains) {
3260
3268
  const maxPages = max_pages ?? 10;
3261
- const results = await Promise.allSettled(
3262
- domains.map((domain) =>
3263
- checkGEO(domain, { maxPages, renderMode }).then((result) => ({
3264
- domain,
3265
- result,
3266
- }))
3267
- )
3268
- );
3269
+ const DOMAIN_CONCURRENCY = 10;
3270
+ const results = [];
3271
+ for (let i = 0; i < domains.length; i += DOMAIN_CONCURRENCY) {
3272
+ const batch = domains.slice(i, i + DOMAIN_CONCURRENCY);
3273
+ const batchResults = await Promise.allSettled(
3274
+ batch.map((domain) =>
3275
+ checkGEO(domain, { maxPages, renderMode }).then((result) => ({
3276
+ domain,
3277
+ result,
3278
+ }))
3279
+ )
3280
+ );
3281
+ results.push(...batchResults);
3282
+ }
3269
3283
 
3270
3284
  const entries = [];
3271
3285
  for (const r of results) {