ebay-mcp 1.13.2 โ†’ 1.13.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/README.md CHANGED
@@ -194,6 +194,9 @@ https://github.com/user-attachments/assets/0173c8df-221c-4943-a4ce-cd20bce79f4b
194
194
 
195
195
  ## Configuration
196
196
 
197
+ <details open>
198
+ <summary><strong>Environment variables, tool exposure, auth &amp; client compatibility</strong></summary>
199
+
197
200
  > ๐Ÿ“– Full reference โ€” every environment variable, OAuth step, and scope โ€” is in the [Configuration Guide](docs/auth/CONFIGURATION.md). `npm run setup` writes the `.env` for you; the variables below are for reference.
198
201
 
199
202
  ```bash
@@ -245,8 +248,13 @@ Auto-configured by `npm run setup`. Requires Node.js โ‰ฅ 18 and MCP protocol 1.0
245
248
  | **Claude Code CLI** | Terminal | `~/.claude.json` |
246
249
  | **Amazon Q Developer** | AWS | `~/.aws/amazonq/mcp.json` |
247
250
 
251
+ </details>
252
+
248
253
  ## Available tools
249
254
 
255
+ <details open>
256
+ <summary><strong>322 tools by category (100% Sell API coverage)</strong></summary>
257
+
250
258
  **322 tools**, 100% Sell API coverage, organized by category. Each link points to the tool definitions and handlers in [`src/tools/categories/`](src/tools/categories/):
251
259
 
252
260
  | Category | What you can do |
@@ -267,27 +275,35 @@ Auto-configured by `npm run setup`. Requires Node.js โ‰ฅ 18 and MCP protocol 1.0
267
275
 
268
276
  For the complete machine-readable index, see [llms.txt](llms.txt).
269
277
 
278
+ </details>
279
+
270
280
  ## Interactive UI (MCP Apps)
271
281
 
282
+ <details open>
283
+ <summary><strong>Interactive table, card, chart &amp; stat views (beta)</strong></summary>
284
+
272
285
  > **Beta** โ€” this feature is new and evolving alongside the MCP Apps spec, and host support is still rolling out. It is opt-in and falls back to plain JSON, so it never breaks existing clients. Toggle it with `EBAY_MCP_UI` (see [Configuration](#configuration)).
273
286
 
274
- On hosts that support [MCP Apps](https://modelcontextprotocol.io), common read tools render their results as interactive views instead of raw JSON โ€” a sortable **table**, a detail **card**, or a **chart** โ€” using the host's own theme. Everywhere else, the exact same tools return plain JSON, so nothing breaks. It is built on the official [MCP Apps SDK (`@modelcontextprotocol/ext-apps`)](https://github.com/modelcontextprotocol/ext-apps), the extension that lets MCP servers ship interactive UI to conversational clients.
287
+ On hosts that support [MCP Apps](https://modelcontextprotocol.io), common read tools render their results as interactive views instead of raw JSON โ€” a sortable **table**, a detail **card**, a **chart**, or a **stat grid** โ€” using the host's own theme. Everywhere else, the exact same tools return plain JSON, so nothing breaks. It is built on the official [MCP Apps SDK (`@modelcontextprotocol/ext-apps`)](https://github.com/modelcontextprotocol/ext-apps), the extension that lets MCP servers ship interactive UI to conversational clients.
275
288
 
276
289
  - **Opt-in and host-gated.** Views are advertised only to clients that announce the MCP Apps capability (e.g. Claude). Hosts without it (e.g. Cursor) silently get JSON.
277
290
  - **Kill-switch.** Set `EBAY_MCP_UI=off` to force plain JSON everywhere, even on capable hosts.
278
291
  - **Token-cheap.** Each view's HTML is fetched once by the host out of band (never into the model's context); the model only ever sees a one-line summary plus the structured data it would have received anyway.
279
292
  - **Read-only.** Views only ever trigger read tools (drill into a row, page, refresh) โ€” they never mutate your eBay data.
280
293
 
281
- 13 core-workflow tools opt in today, across three archetypes:
294
+ 15 core-workflow tools opt in today, across four archetypes:
282
295
 
283
296
  | Archetype | Tools |
284
297
  | --- | --- |
285
298
  | **Table** | `ebay_get_orders`, `ebay_get_shipping_fulfillments`, `ebay_get_offers`, `ebay_get_inventory_items`, `ebay_get_inventory_locations`, `ebay_get_payment_dispute_summaries` |
286
299
  | **Card** | `ebay_get_order`, `ebay_get_offer`, `ebay_get_inventory_item`, `ebay_get_payment_dispute`, `ebay_get_seller_standards_profile` |
287
300
  | **Chart** | `ebay_get_traffic_report`, `ebay_get_customer_service_metric` |
301
+ | **Stat** | `ebay_get_rate_limits`, `ebay_get_user_rate_limits` |
288
302
 
289
303
  The views build into self-contained HTML with `npm run build` (or `npm run build:ui`); they ship in the published package and load with no network access of their own.
290
304
 
305
+ </details>
306
+
291
307
  ## Usage examples
292
308
 
293
309
  Common tasks, phrased as you'd ask your AI assistant:
@@ -305,78 +321,132 @@ Common tasks, phrased as you'd ask your AI assistant:
305
321
 
306
322
  ## FAQ
307
323
 
308
- ### What is the eBay MCP server?
324
+ <details>
325
+ <summary><strong>What is the eBay MCP server?</strong></summary>
309
326
 
310
327
  A local [Model Context Protocol](https://modelcontextprotocol.io) server that exposes **322 tools** covering **100% of eBay's Sell APIs** (270 endpoints) to AI assistants โ€” inventory, order fulfillment, marketing, analytics, and developer tools.
311
328
 
312
- ### Is this an official eBay product?
329
+ </details>
330
+
331
+ <details>
332
+ <summary><strong>Is this an official eBay product?</strong></summary>
313
333
 
314
334
  No. This is an unofficial, third-party open-source project. It is **not affiliated with, authorized, or endorsed by eBay Inc.**
315
335
 
316
- ### Which AI assistants and MCP clients are supported?
336
+ </details>
337
+
338
+ <details>
339
+ <summary><strong>Which AI assistants and MCP clients are supported?</strong></summary>
317
340
 
318
341
  Nine clients are auto-configured by `npm run setup`: Claude Desktop, Cursor, Zed, Cline, Continue.dev, Windsurf, Roo Code, Claude Code CLI, and Amazon Q Developer. Any MCP-compatible client can connect.
319
342
 
320
- ### Can I use it with Claude, ChatGPT, or Cursor?
343
+ </details>
344
+
345
+ <details>
346
+ <summary><strong>Can I use it with Claude, ChatGPT, or Cursor?</strong></summary>
321
347
 
322
348
  Yes. It works with Claude Desktop and Claude Code out of the box, with Cursor and other MCP-enabled IDEs, and with any assistant that supports the Model Context Protocol. The one-click setup prompt above works with ChatGPT and other assistants too.
323
349
 
324
- ### Why don't I see the interactive tables and charts?
350
+ </details>
351
+
352
+ <details>
353
+ <summary><strong>Why don't I see the interactive tables and charts?</strong></summary>
325
354
 
326
355
  Interactive [MCP Apps](#interactive-ui-mcp-apps) views only appear on hosts that announce the capability (e.g. Claude); other clients get the same data as plain JSON. Also confirm you have not set `EBAY_MCP_UI=off` and that the views are built (`npm run build` runs `build:ui`).
327
356
 
328
- ### How many eBay APIs and tools does it cover?
357
+ </details>
358
+
359
+ <details>
360
+ <summary><strong>How many eBay APIs and tools does it cover?</strong></summary>
329
361
 
330
362
  322 tools across 270 unique endpoints โ€” 100% of eBay's Sell APIs.
331
363
 
332
- ### Is it free and open source?
364
+ </details>
365
+
366
+ <details>
367
+ <summary><strong>Is it free and open source?</strong></summary>
333
368
 
334
369
  Yes. It is released under the [MIT license](LICENSE).
335
370
 
336
- ### Does it run locally or in the cloud?
371
+ </details>
372
+
373
+ <details>
374
+ <summary><strong>Does it run locally or in the cloud?</strong></summary>
337
375
 
338
376
  It runs entirely on your machine over STDIO (or local HTTP). There is no cloud relay โ€” your eBay credentials never leave your computer.
339
377
 
340
- ### What do I need to get started?
378
+ </details>
379
+
380
+ <details>
381
+ <summary><strong>What do I need to get started?</strong></summary>
341
382
 
342
383
  Node.js โ‰ฅ 18, a free [eBay Developer Account](https://developer.ebay.com/) (Client ID + Client Secret), then run `npm run setup`.
343
384
 
344
- ### What are the eBay API rate limits?
385
+ </details>
386
+
387
+ <details>
388
+ <summary><strong>What are the eBay API rate limits?</strong></summary>
345
389
 
346
390
  Client credentials (the default) allow about 1,000 requests/day. Authenticating with a user token via OAuth raises this to 10,000โ€“50,000 requests/day depending on your account tier.
347
391
 
348
- ### Does it support both sandbox and production?
392
+ </details>
393
+
394
+ <details>
395
+ <summary><strong>Does it support both sandbox and production?</strong></summary>
349
396
 
350
397
  Yes. Switch with the `EBAY_ENVIRONMENT` variable (`sandbox` or `production`).
351
398
 
352
- ### Are my credentials and data secure?
399
+ </details>
400
+
401
+ <details>
402
+ <summary><strong>Are my credentials and data secure?</strong></summary>
353
403
 
354
404
  Credentials are stored locally in your `.env` file and used only to call eBay directly. See [SECURITY.md](SECURITY.md) and [EBAY_COMPLIANCE.md](EBAY_COMPLIANCE.md).
355
405
 
356
- ### How is this different from calling the eBay API directly?
406
+ </details>
407
+
408
+ <details>
409
+ <summary><strong>How is this different from calling the eBay API directly?</strong></summary>
357
410
 
358
411
  You interact in natural language through your AI assistant. OAuth token management, automatic retries with backoff, and type-safe Zod validation are built in. See the [comparison table](#ebay-mcp-vs-the-raw-ebay-api) above.
359
412
 
360
- ### Does it support eBay's legacy Trading API (XML)?
413
+ </details>
414
+
415
+ <details>
416
+ <summary><strong>Does it support eBay's legacy Trading API (XML)?</strong></summary>
361
417
 
362
418
  Yes. Fixed-price listing create, revise, relist, and end operations are supported through the Trading API tools.
363
419
 
364
- ### How do I get higher rate limits?
420
+ </details>
421
+
422
+ <details>
423
+ <summary><strong>How do I get higher rate limits?</strong></summary>
365
424
 
366
425
  Complete the OAuth flow with `npm run setup` to authenticate with a user token (10kโ€“50k requests/day instead of the default 1k).
367
426
 
368
- ### What is it built with?
427
+ </details>
428
+
429
+ <details>
430
+ <summary><strong>What is it built with?</strong></summary>
369
431
 
370
432
  TypeScript and Node.js (ESM), using the official MCP SDK, Zod for validation, and OpenAPI-generated types.
371
433
 
372
- ### How do I update to the latest version?
434
+ </details>
435
+
436
+ <details>
437
+ <summary><strong>How do I update to the latest version?</strong></summary>
373
438
 
374
439
  Run `npm install -g ebay-mcp@latest` (or `npm update -g ebay-mcp`).
375
440
 
376
- ### Does it work offline?
441
+ </details>
442
+
443
+ <details>
444
+ <summary><strong>Does it work offline?</strong></summary>
377
445
 
378
446
  No. "Runs locally" means the server process runs on your machine โ€” it still needs an internet connection and valid credentials to reach eBay's live APIs.
379
447
 
448
+ </details>
449
+
380
450
  ## Contributing
381
451
 
382
452
  Contributions welcome. Fork โ†’ branch โ†’ add tests โ†’ `npm run check && npm test` โ†’ commit with [Conventional Commits](https://www.conventionalcommits.org/) โ†’ open a PR.
@@ -1,5 +1,5 @@
1
1
  import { assertRequiredString, buildPaginatedQueryParams, getPathWithContextError, getWithContextError, } from './shared.js';
2
- import { buildTruthyPaginatedParams } from '../shared/query-params.js';
2
+ import { buildTruthyPaginatedParams } from '../../api/shared/query-params.js';
3
3
  import { withApiError } from '../../api/shared/request.js';
4
4
  /**
5
5
  * Negotiation API - Buyer-seller negotiations and offers
@@ -1,4 +1,4 @@
1
- import { buildContinuationParams, deleteWithApiError, getWithApiError, postWithApiError, putWithApiError, requireObject, requireString, } from '../shared/request.js';
1
+ import { buildContinuationParams, deleteWithApiError, getWithApiError, postWithApiError, putWithApiError, requireObject, requireString, } from '../../api/shared/request.js';
2
2
  /**
3
3
  * Notification API - Event notifications and subscriptions
4
4
  * Based on: docs/sell-apps/communication/commerce_notification_v1_oas3.json
@@ -1,4 +1,4 @@
1
- import { buildValidatedPaginatedParams, getWithApiError, requireString, } from '../shared/request.js';
1
+ import { buildValidatedPaginatedParams, getWithApiError, requireString, } from '../../api/shared/request.js';
2
2
  /**
3
3
  * Build validated pagination query params.
4
4
  *
@@ -1,4 +1,4 @@
1
- import { buildOptionalStringParams, buildValidatedPaginatedParams, optionalStringParam, requireObject, requireString, withApiError, } from '../shared/request.js';
1
+ import { buildOptionalStringParams, buildValidatedPaginatedParams, optionalStringParam, requireObject, requireString, withApiError, } from '../../api/shared/request.js';
2
2
  /**
3
3
  * Inventory API - Manage listings and inventory
4
4
  * Based on: docs/sell-apps/listing-management/sell_inventory_v1_oas3.json
@@ -1,4 +1,4 @@
1
- import { buildOptionalStringParams, requireObject, requireString, withApiError, } from '../shared/request.js';
1
+ import { buildOptionalStringParams, requireObject, requireString, withApiError, } from '../../api/shared/request.js';
2
2
  /**
3
3
  * Metadata API - Marketplace policies and configurations
4
4
  * Based on: docs/sell-apps/listing-metadata/sell_metadata_v1_oas3.json
@@ -1,4 +1,4 @@
1
- import { buildTruthyPaginatedParams } from '../shared/query-params.js';
1
+ import { buildTruthyPaginatedParams } from '../../api/shared/query-params.js';
2
2
  import { withApiError } from '../../api/shared/request.js';
3
3
  /**
4
4
  * VERO API - Verified Rights Owner program
@@ -43,6 +43,10 @@ export function summarizeView(view) {
43
43
  const pointCount = view.series.reduce((total, series) => total + series.points.length, 0);
44
44
  return `${view.title ?? 'Chart'} (${view.kind}): ${view.series.length} series, ${pointCount} ${pointCount === 1 ? 'point' : 'points'}. Rendered as an interactive chart.`;
45
45
  }
46
+ case 'stat': {
47
+ const count = view.tiles.length;
48
+ return `${view.title ?? 'Metrics'}: ${count} ${count === 1 ? 'metric' : 'metrics'}. Rendered as an interactive stat grid.`;
49
+ }
46
50
  }
47
51
  }
48
52
  /**
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  import { zodToJsonSchema } from 'zod-to-json-schema';
3
3
  import { MarketplaceId } from '../../types/ebay-enums.js';
4
4
  import { defineTool } from '../../tools/define-tool.js';
5
- import { bulkSalesTaxRequestSchema, customPolicySchema, fulfillmentPolicySchema, paymentPolicySchema, programRequestSchema, returnPolicySchema, salesTaxBaseSchema, } from '../schemas.js';
5
+ import { bulkSalesTaxRequestSchema, customPolicySchema, fulfillmentPolicySchema, paymentPolicySchema, programRequestSchema, returnPolicySchema, salesTaxBaseSchema, } from '../../tools/schemas.js';
6
6
  import { customPolicyResponseSchema, getFulfillmentPoliciesOutputSchema, createFulfillmentPolicyOutputSchema, fulfillmentPolicyResponseSchema, getPaymentPoliciesOutputSchema, createPaymentPolicyOutputSchema, paymentPolicyResponseSchema, getReturnPoliciesOutputSchema, createReturnPolicyOutputSchema, returnPolicyResponseSchema, createCustomPolicyOutputSchema, getSalesTaxesOutputSchema, salesTaxSchema, kycOutputSchema, privilegesOutputSchema, programsOutputSchema, } from '../../schemas/account-management/account.js';
7
7
  /** Account Management API tools for seller policies, tax, KYC, privileges, and programs. */
8
8
  export const accountEntries = [
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { defineTool } from '../../tools/define-tool.js';
3
+ import { mapRateLimitsToStat, mapUserRateLimitsToStat } from '../../tools/ui/maps.js';
3
4
  import { getApiStatusFeed } from '../../utils/api-status-feed.js';
4
5
  /** Developer API tools for eBay application and keyset management. */
5
6
  export const developerEntries = [
@@ -86,6 +87,7 @@ export const developerEntries = [
86
87
  description: 'Rate limit data for application APIs',
87
88
  },
88
89
  handler: (api, args) => api.developer.getRateLimits(args.apiContext, args.apiName),
90
+ ui: { archetype: 'stat', map: mapRateLimitsToStat },
89
91
  }),
90
92
  defineTool({
91
93
  name: 'ebay_get_user_rate_limits',
@@ -108,6 +110,7 @@ export const developerEntries = [
108
110
  description: 'Rate limit data for user APIs',
109
111
  },
110
112
  handler: (api, args) => api.developer.getUserRateLimits(args.apiContext, args.apiName),
113
+ ui: { archetype: 'stat', map: mapUserRateLimitsToStat },
111
114
  }),
112
115
  defineTool({
113
116
  name: 'ebay_register_client',
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  import { zodToJsonSchema } from 'zod-to-json-schema';
3
3
  import { defineTool } from '../../tools/define-tool.js';
4
4
  import { mapDisputeSummariesToTable, mapDisputeToCard, mapFulfillmentsToTable, mapOrdersToTable, mapOrderToCard, } from '../../tools/ui/maps.js';
5
- import { shippingFulfillmentSchema } from '../schemas.js';
5
+ import { shippingFulfillmentSchema } from '../../tools/schemas.js';
6
6
  import { getOrdersOutputSchema, getOrderOutputSchema, createShippingFulfillmentOutputSchema, getShippingFulfillmentsOutputSchema, issueRefundOutputSchema, getPaymentDisputesOutputSchema, } from '../../schemas/fulfillment/orders.js';
7
7
  /** Fulfillment API tools for orders, shipping fulfillments, refunds, and cancellations. */
8
8
  export const fulfillmentEntries = [
@@ -3,7 +3,7 @@ import { zodToJsonSchema } from 'zod-to-json-schema';
3
3
  import { MarketplaceId } from '../../types/ebay-enums.js';
4
4
  import { defineTool } from '../../tools/define-tool.js';
5
5
  import { mapInventoryItemsToTable, mapInventoryItemToCard, mapLocationsToTable, mapOffersToTable, mapOfferToCard, } from '../../tools/ui/maps.js';
6
- import { bulkInventoryItemRequestSchema, bulkMigrateRequestSchema, bulkOfferRequestSchema, bulkPriceQuantityRequestSchema, bulkPublishRequestSchema, inventoryItemGroupSchema, inventoryItemSchema, listingFeesRequestSchema, locationSchema, offerSchema, productCompatibilitySchema, } from '../schemas.js';
6
+ import { bulkInventoryItemRequestSchema, bulkMigrateRequestSchema, bulkOfferRequestSchema, bulkPriceQuantityRequestSchema, bulkPublishRequestSchema, inventoryItemGroupSchema, inventoryItemSchema, listingFeesRequestSchema, locationSchema, offerSchema, productCompatibilitySchema, } from '../../tools/schemas.js';
7
7
  import { getInventoryItemsOutputSchema, getInventoryItemOutputSchema, createInventoryItemOutputSchema, getOffersOutputSchema, createOfferOutputSchema, publishOfferOutputSchema, offerResponseSchema, getInventoryLocationsOutputSchema, createInventoryLocationOutputSchema, getProductCompatibilityOutputSchema, getInventoryItemGroupOutputSchema, bulkInventoryItemResponseSchema, bulkOfferResponseSchema, bulkPublishResponseSchema, } from '../../schemas/inventory-management/inventory.js';
8
8
  /** Inventory API tools for seller inventory items, offers, locations, and bulk operations. */
9
9
  export const inventoryEntries = [
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { MarketplaceId } from '../../types/ebay-enums.js';
3
3
  import { defineTool } from '../../tools/define-tool.js';
4
- import { compatibilityDataSchema, compatibilitySpecificationSchema } from '../schemas.js';
4
+ import { compatibilityDataSchema, compatibilitySpecificationSchema } from '../../tools/schemas.js';
5
5
  /** Metadata API tools for marketplace, business policy, and sales tax metadata. */
6
6
  export const metadataEntries = [
7
7
  defineTool({
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { defineTool } from '../../tools/define-tool.js';
3
- import { shippingQuoteRequestSchema, veroReportDataSchema } from '../schemas.js';
3
+ import { shippingQuoteRequestSchema, veroReportDataSchema } from '../../tools/schemas.js';
4
4
  /** Miscellaneous eBay API tools that do not fit the primary seller API categories. */
5
5
  export const otherEntries = [
6
6
  // Identity API
@@ -8,4 +8,5 @@ export const uiArchetypes = {
8
8
  table: { uri: 'ui://ebay/table.html', name: 'eBay table view', htmlFile: 'table.html' },
9
9
  card: { uri: 'ui://ebay/card.html', name: 'eBay detail card view', htmlFile: 'card.html' },
10
10
  chart: { uri: 'ui://ebay/chart.html', name: 'eBay chart view', htmlFile: 'chart.html' },
11
+ stat: { uri: 'ui://ebay/stat.html', name: 'eBay stat grid view', htmlFile: 'stat.html' },
11
12
  };
@@ -417,3 +417,63 @@ export function mapCustomerServiceMetricToChart(result) {
417
417
  series,
418
418
  };
419
419
  }
420
+ /**
421
+ * Buckets remaining API headroom into a tile tone: healthy above a quarter of
422
+ * the quota, warning as it drains, danger near exhaustion. A missing or zero
423
+ * limit is neutral โ€” there is no meaningful ratio to colour.
424
+ */
425
+ function headroomTone(remaining, limit) {
426
+ if (limit <= 0) {
427
+ return 'neutral';
428
+ }
429
+ const ratio = remaining / limit;
430
+ if (ratio <= 0.1) {
431
+ return 'danger';
432
+ }
433
+ if (ratio <= 0.25) {
434
+ return 'warning';
435
+ }
436
+ return 'success';
437
+ }
438
+ /**
439
+ * Flattens a rate-limit response into one tile per API resource, showing calls
440
+ * remaining against the quota with a tone that reflects headroom. Shared by the
441
+ * application- and user-scoped rate-limit tools, which return the same shape.
442
+ */
443
+ function rateLimitTiles(result) {
444
+ const tiles = [];
445
+ for (const rateLimit of result.rateLimits ?? []) {
446
+ for (const resource of rateLimit.resources ?? []) {
447
+ const rate = resource.rates?.[0];
448
+ if (!rate) {
449
+ continue;
450
+ }
451
+ const remaining = rate.remaining ?? 0;
452
+ const limit = rate.limit ?? 0;
453
+ const parts = [rateLimit.apiContext, rateLimit.apiName, resource.name].filter(Boolean);
454
+ tiles.push({
455
+ label: parts.length > 0 ? parts.join(' ยท ') : 'Resource',
456
+ value: remaining.toLocaleString('en-US'),
457
+ sub: `of ${limit.toLocaleString('en-US')}`,
458
+ tone: headroomTone(remaining, limit),
459
+ });
460
+ }
461
+ }
462
+ return tiles;
463
+ }
464
+ /** Projects application rate limits into a stat grid (calls remaining per resource). */
465
+ export function mapRateLimitsToStat(result) {
466
+ return {
467
+ archetype: 'stat',
468
+ title: 'Application rate limits',
469
+ tiles: rateLimitTiles(result),
470
+ };
471
+ }
472
+ /** Projects user rate limits into a stat grid (per-user calls remaining per resource). */
473
+ export function mapUserRateLimitsToStat(result) {
474
+ return {
475
+ archetype: 'stat',
476
+ title: 'User rate limits',
477
+ tiles: rateLimitTiles(result),
478
+ };
479
+ }