npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fluentcommerce/fluent-mcp-extn

v0.3.6

Published

[Experimental] MCP (Model Context Protocol) extension server for Fluent Commerce. Exposes event dispatch, transition actions, GraphQL execution, Prometheus metrics, batch ingestion, and webhook validation as MCP tools.

Downloads

1,014

Readme

@fluentcommerce/fluent-mcp-extn

[!CAUTION]

🧪 EXPERIMENTAL — LABS PROJECT

This package is NOT production-ready. It is an internal labs experiment under active development.

  • No stability guarantees — APIs, tool names, schemas, and config may change or break between any release
  • No support — this is not an officially supported Fluent Commerce product
  • No warranty — provided as-is for experimentation and internal evaluation only
  • Do NOT use in production without thorough review

Pin to an exact version (@0.3.4) if you depend on current behavior.

MCP (Model Context Protocol) extension server for Fluent Commerce.

Exposes event dispatch, transition actions, GraphQL operations, Prometheus metrics queries, batch ingestion, webhook validation, entity lifecycle management, workflow management, settings management, environment discovery, and test automation as MCP tools — powered by @fluentcommerce/fc-connect-sdk.

What this does: This server runs as a background process inside your AI coding assistant (Claude Code, Cursor, VS Code Copilot, Windsurf, etc.). It gives the AI direct, authenticated access to Fluent Commerce APIs — so the AI can query orders, send events, inspect workflows, check metrics, and run diagnostics on your behalf, using natural language.


Already using @fluentcommerce/ai-skills? You're already set up — ai-skills install --profile auto-configures this server in your .mcp.json. Skip to Verify connection or Tools (45) to see what's available.


Table of Contents

Why This Extension

The official fluent mcp server (bundled with Fluent CLI) covers core GraphQL and workflow operations. This extension adds capabilities typically needed for implementation and diagnostics:

| Capability | Official MCP | This Extension | |---|:---:|:---:| | Event dispatch (event.build / event.send / event.list / event.get) | | Yes | | Event runtime forensics (event.flowInspect) | | Yes | | Workflow transitions (workflow.transitions) | | Yes | | Auto-paginated GraphQL (graphql.queryAll) | | Yes | | Batch mutations (graphql.batchMutate) | | Yes | | Batch ingestion (batch.*) | | Yes | | Prometheus metrics (metrics.query) | | Yes | | Metrics health assessment (metrics.healthCheck) | | Yes | | Managed SLO snapshot (metrics.sloReport) | | Yes | | Metric label discovery (metrics.labelCatalog) | | Yes | | Event analytics rankings (metrics.topEvents) | | Yes | | Webhook signature validation | | Yes | | Schema introspection (graphql.introspect) | | Yes | | Multi-strategy auth (profile, OAuth, token command, static token) | | Yes | | Entity CRUD (entity.create / entity.update / entity.get) | | Yes | | Workflow management (workflow.get / workflow.list / workflow.upload / workflow.diff / workflow.simulate) | | Yes | | Settings management (setting.get / setting.upsert / setting.bulkUpsert) | | Yes | | Environment snapshot (environment.discover / environment.validate) | | Yes | | Test assertions with polling (test.assert) | | Yes |

Best practice: run both the official MCP server and this extension together.

Quick Start

Automated setup (recommended)

If you use @fluentcommerce/ai-skills, a single command installs skills AND configures this MCP server:

npx @fluentcommerce/ai-skills install --profile YOUR_PROFILE --profile-retailer YOUR_RETAILER_REF

This creates .mcp.json with fluent-mcp-extn pre-configured. Skip to Verify connection.

Manual setup

If you're using this server standalone (without ai-skills), add it to your project's .mcp.json.

| IDE | MCP config file | |---|---| | Claude Code | .mcp.json (workspace root) | | Cursor | .mcp.json (workspace root) or .cursor/mcp.json | | VS Code Copilot | .vscode/mcp.json | | Windsurf | Workspace/app MCP settings |

1. Add MCP server entry

Pick one of the auth options below.

Option A: Fluent CLI Profile (recommended)

Reuses your existing Fluent CLI profile — no credentials in .mcp.json:

{
  "mcpServers": {
    "fluent-mcp-extn": {
      "type": "stdio",
      "command": "npx",
      "args": ["@fluentcommerce/fluent-mcp-extn"],
      "env": {
        "FLUENT_PROFILE": "YOUR_PROFILE",
        "FLUENT_PROFILE_RETAILER": "YOUR_RETAILER_REF"
      }
    }
  }
}

Use retailer ref in FLUENT_PROFILE_RETAILER (for example RETAILER_REF), not retailer ID.

Reads base URL, client ID/secret, username/password, and retailer ID from ~/.fluentcommerce/YOUR_PROFILE/. Requires Fluent CLI to be installed with at least one profile configured (fluent profile list).

Option B: Explicit OAuth credentials

Set credentials as shell environment variables (never in .mcp.json):

export FLUENT_CLIENT_ID=your-client-id
export FLUENT_CLIENT_SECRET=your-client-secret
export FLUENT_USERNAME=your-username
export FLUENT_PASSWORD=your-password

Then in .mcp.json, only the non-sensitive connection details:

{
  "mcpServers": {
    "fluent-mcp-extn": {
      "type": "stdio",
      "command": "npx",
      "args": ["@fluentcommerce/fluent-mcp-extn"],
      "env": {
        "FLUENT_BASE_URL": "https://YOUR_ACCOUNT.sandbox.api.fluentretail.com",
        "FLUENT_RETAILER_ID": "YOUR_RETAILER_ID"
      }
    }
  }
}

The MCP server inherits all parent shell environment variables automatically.

Option C: Profile + overrides (hybrid)

Use a profile as the base, override specific values via env vars:

{
  "mcpServers": {
    "fluent-mcp-extn": {
      "type": "stdio",
      "command": "npx",
      "args": ["@fluentcommerce/fluent-mcp-extn"],
      "env": {
        "FLUENT_PROFILE": "YOUR_PROFILE",
        "FLUENT_PROFILE_RETAILER": "YOUR_RETAILER_REF",
        "FLUENT_RETAILER_ID": "YOUR_RETAILER_ID"
      }
    }
  }
}

Any explicit FLUENT_* env var overrides the value from the profile. Setting FLUENT_BASE_URL or OAuth env vars disables createClientFromProfile and falls back to standard OAuth (profile values still used as defaults for unset vars).

Option D: Token command (vault / CI integration)

For CI pipelines or environments where credentials come from a vault or external process:

{
  "mcpServers": {
    "fluent-mcp-extn": {
      "type": "stdio",
      "command": "npx",
      "args": ["@fluentcommerce/fluent-mcp-extn"],
      "env": {
        "FLUENT_BASE_URL": "https://YOUR_ACCOUNT.sandbox.api.fluentretail.com",
        "FLUENT_RETAILER_ID": "YOUR_RETAILER_ID",
        "TOKEN_COMMAND": "vault read -field=token secret/fluent/api",
        "TOKEN_COMMAND_TIMEOUT_MS": "10000"
      }
    }
  }
}

The command must print a valid bearer token to stdout. Token is cached for 55 minutes before re-executing the command.

Option E: Static bearer token

For quick testing with a pre-obtained token:

{
  "mcpServers": {
    "fluent-mcp-extn": {
      "type": "stdio",
      "command": "npx",
      "args": ["@fluentcommerce/fluent-mcp-extn"],
      "env": {
        "FLUENT_BASE_URL": "https://YOUR_ACCOUNT.sandbox.api.fluentretail.com",
        "FLUENT_RETAILER_ID": "YOUR_RETAILER_ID",
        "FLUENT_ACCESS_TOKEN": "YOUR_BEARER_TOKEN"
      }
    }
  }
}

No automatic refresh — the token will expire according to its original grant TTL.

Auth priority order

When multiple auth methods are configured, the first valid method wins:

  1. ProfileFLUENT_PROFILE set → uses SDK createClientFromProfile
  2. OAuthFLUENT_CLIENT_ID + FLUENT_CLIENT_SECRET → SDK-native OAuth with automatic refresh
  3. Token commandTOKEN_COMMAND → executes shell command, caches token for 55 min
  4. Static tokenFLUENT_ACCESS_TOKEN → no refresh, dev fallback only

2. Restart your IDE

Restart so the MCP client picks up the new server.

3. Verify connection

Run these tools in order to confirm everything works:

  1. config.validate — should return ok: true
  2. health.ping — should return ok: true
  3. connection.test — should return ok: true with your user/account details

If any returns ok: false, see Troubleshooting.

4. Try a real call

event.build  →  build a payload (no API call)
event.send with dryRun: true  →  validate without sending
event.send with dryRun: false  →  send for real

Requirements

  • Node.js 20+
  • Fluent CLI installed when using profile auth (FLUENT_PROFILE)
  • Fluent Commerce API credentials (see Configuration)

Install

From npm (recommended)

No install needed — npx runs it directly from the npm registry:

npx @fluentcommerce/fluent-mcp-extn

This starts the MCP stdio server process. In a plain terminal it appears idle because it is waiting for MCP JSON-RPC input from your IDE/agent.

Or install as a project dependency:

npm install @fluentcommerce/fluent-mcp-extn

From source

git clone https://bitbucket.org/fluentcommerce/fluent-mcp-extn.git
cd fluent-mcp-extn
npm install && npm run build

Then use in .mcp.json:

{
  "command": "node",
  "args": ["path/to/fluent-mcp-extn/dist/index.js"]
}

Configuration

All configuration is via environment variables in your .mcp.json env block. Never commit credentials to git.

Required

| Variable | Description | |---|---| | FLUENT_BASE_URL | Fluent Commerce API base URL |

Plus at least one auth method below.

Authentication (first valid method wins)

1. Fluent CLI profile (recommended for local development)

| Variable | Required | Description | |---|---|---| | FLUENT_PROFILE | Yes | Fluent CLI profile name (~/.fluentcommerce/<profile>) | | FLUENT_PROFILE_RETAILER | No | Retailer ref (matches retailer.<ref>.json) | | FLUENT_PROFILE_DIR | No | Override profile base directory (defaults to ~/.fluentcommerce) |

FLUENT_PROFILE_RETAILER allows retailer-scoped user credential overrides from profile files.

2. OAuth

| Variable | Required | Description | |---|---|---| | FLUENT_CLIENT_ID | Yes | OAuth client ID | | FLUENT_CLIENT_SECRET | Yes | OAuth client secret | | FLUENT_USERNAME | No | Username (for password grant) | | FLUENT_PASSWORD | No | Password (for password grant) |

Security: These credentials must be set as shell environment variables, never in .mcp.json. MCP server processes inherit all parent shell env vars automatically. The mcp-setup command strips any secrets found in .mcp.json during re-runs.

3. Token command

| Variable | Default | Description | |---|---|---| | TOKEN_COMMAND | — | Shell command that prints a bearer token to stdout | | TOKEN_COMMAND_TIMEOUT_MS | 10000 | Timeout for the command |

4. Static token

| Variable | Description | |---|---| | FLUENT_ACCESS_TOKEN | Pre-obtained bearer token |

Optional

| Variable | Default | Description | |---|---|---| | FLUENT_RETAILER_ID | — | Default retailer for events and batch operations | | FLUENT_ACCOUNT_ID | — | Default account for events |

Resilience Tuning

| Variable | Default | Description | |---|---|---| | FLUENT_REQUEST_TIMEOUT_MS | 30000 | Request timeout | | FLUENT_RETRY_ATTEMPTS | 3 | Retry attempts for read operations | | FLUENT_RETRY_INITIAL_DELAY_MS | 300 | Initial backoff delay | | FLUENT_RETRY_MAX_DELAY_MS | 5000 | Max backoff delay | | FLUENT_RETRY_FACTOR | 2 | Backoff multiplier |

Response Shaping

Controls how large responses are handled before returning to the AI. When a response exceeds the budget, arrays are auto-summarized (not truncated) with record counts, field inventory, value distributions, and sample records — giving the AI a complete analytical picture instead of cut-off data.

| Variable | Default | Description | |---|---|---| | FLUENT_RESPONSE_BUDGET_CHARS | 50000 | Max serialized response size (~12.5k tokens). 0 disables (unlimited). | | FLUENT_RESPONSE_MAX_ARRAY | 50 | Arrays exceeding this size are auto-summarized. Only active when budget > 0. | | FLUENT_RESPONSE_SAMPLE_SIZE | 3 | Number of sample records included in array summaries. |

Cache

Filesystem-based cache for near-static read responses (schema introspection, workflows, settings, plugins). Enabled automatically when FLUENT_PROFILE is set.

| Variable | Default | Description | |---|---|---| | FLUENT_CACHE_ENABLED | true | Set to "false" to disable the disk cache entirely | | FLUENT_CACHE_DIR | accounts/<PROFILE>/.cache | Override the cache directory | | FLUENT_CACHE_TTL_WORKFLOW | 3600000 (1h) | Workflow cache TTL in ms | | FLUENT_CACHE_TTL_SETTING | 3600000 (1h) | Setting cache TTL in ms | | FLUENT_CACHE_TTL_INTROSPECT | 86400000 (24h) | Schema introspection cache TTL in ms | | FLUENT_CACHE_TTL_PLUGIN | 3600000 (1h) | Plugin list cache TTL in ms |

Behavior:

  • Per-profile isolation — each profile gets its own cache directory under accounts/<PROFILE>/.cache
  • Cached tools: graphql.introspect, plugin.list, workflow.get, workflow.list, setting.get
  • Write-through invalidation — write operations auto-invalidate related cache entries: workflow.upload clears workflow:*, setting.upsert/setting.bulkUpsert clears matching setting:get:* entries, graphql.introspect with force: true clears introspect:*
  • _cache metadata — all cached tool responses include a _cache field ({ hit, ageMs } on cache hit, { hit: false, stored: true } on cache miss) so the AI can reason about data freshness
  • baseUrl fingerprint — cache auto-clears if the profile is re-pointed to a different environment, preventing cross-environment contamination
  • Fail-open — cache errors (corrupt files, permission issues) become cache misses; the tool continues with a live API call
  • Requires FLUENT_PROFILE — no profile means no safe namespace, so caching is disabled

Tools (45)

Diagnostics

| Tool | Description | |---|---| | config.validate | Validate auth and base URL configuration | | health.ping | Quick connectivity check | | connection.test | Full auth + GraphQL end-to-end test (returns user/account context) |

Events

| Tool | Description | |---|---| | event.build | Build event payload without sending (validation only) | | event.send | Build and send event (supports dryRun: true) | | event.get | Fetch a single event by ID | | event.list | List/filter events with pagination | | event.flowInspect | One-call root-entity flow forensics — works for ORDER/FULFILMENT/LOCATION/WAVE/PRODUCT and more |

event.flowInspect supports any entity type. Pass rootEntityType when you want strict filtering; omit it to inspect by root ref only. Use rootEntityId when refs are reused and you need exact disambiguation.

Compact mode (default compact: true): Returns a pre-analyzed summary (~2-3k tokens) with an analysis section containing anomaly findings, status flow, failed webhook endpoints, and slowest rulesets. Set compact: false for full raw data (~24k tokens).

Default-on flags: compact, includeAudit, includeExceptions, includeNoMatchDetails, includeEventDetails, includeScheduled

Opt-in flags (default false):

  • includeRuleDetails — per-rule execution trace with class name, props, and timing
  • includeCustomLogs — custom plugin log messages (LogCollection)
  • includeSnapshots — entity state snapshots at each processing point
  • includeCrossEntity — child entity events (FULFILMENT_CHOICE, FULFILMENT)

Example — compact forensics (recommended first call):

{
  "rootEntityRef": "ORD-001",
  "rootEntityType": "ORDER"
}

Example — full data with all sections:

{
  "rootEntityRef": "ORD-001",
  "rootEntityType": "ORDER",
  "compact": false,
  "includeRuleDetails": true,
  "includeCustomLogs": true,
  "includeSnapshots": true,
  "includeCrossEntity": true
}

Example — lightweight (minimal output):

{
  "rootEntityRef": "ORD-001",
  "rootEntityType": "ORDER",
  "includeAudit": false,
  "includeEventDetails": false,
  "includeExceptions": false,
  "includeNoMatchDetails": false,
  "maxDrilldowns": 0
}

Local-First LLM Reduction (flowInspect)

If event.flowInspect returns large JSON, run local analysis first and only send compact artifacts to an LLM:

npx tsx scripts/run-flow-inspect.ts <ROOT_ENTITY_REF> --profile <PROFILE>

This writes:

  • EVENT_FLOW_INSPECT_<ref>.json (raw)
  • EVENT_FLOW_INSPECT_<ref>.summary.json (local anomaly + metrics summary)
  • EVENT_FLOW_INSPECT_<ref>.drilldown.json (focused event.get extraction for top evidence IDs)
  • EVENT_FLOW_INSPECT_<ref>.llm-packet.md (small LLM handoff packet)

Useful flags:

  • --light uses compact fetch mode for faster runs
  • --root-type ... and --root-id ... tighten entity matching
  • --drilldown / --no-drilldown toggle focused event.get enrichment
  • --drilldown-limit controls how many top evidence IDs get enriched
  • --drilldown-classes webhook,mutation,sendEvent,mismatch,exception,scheduled,slow,status limits enrichment to selected evidence classes
  • --top-n, --evidence-limit, --truncate control summary/packet compactness
  • --no-llm-pack skips markdown packet output

Metrics

| Tool | Description | |---|---| | metrics.query | Query Prometheus metrics using instant or range mode | | metrics.healthCheck | One-call anomaly check with Prometheus-first + Event API fallback | | metrics.sloReport | Managed-services SLO snapshot (rates + p95 latency + findings) | | metrics.labelCatalog | Discover supported metric labels from live series + known Fluent hints | | metrics.topEvents | Aggregate and rank top events by name/entity/status in a time window |

Orchestration

| Tool | Description | |---|---| | workflow.transitions | Query available user actions/transitions for provided triggers (POST /api/v4.1/transition) | | plugin.list | List all registered rules with metadata (GET /orchestration/rest/v1/plugin). Supports optional name filter. |

flexType auto-derive: When type and subtype are provided but flexType is omitted, it is auto-derived as TYPE::SUBTYPE. All three params (module, flexType, flexVersion) are required by the Transition API — omitting any one silently returns empty results.

Example — get actions for a ServicePoint manifest trigger:

{
  "triggers": [
    {
      "type": "MANIFEST",
      "subtype": "DEFAULT",
      "status": "PENDING",
      "module": "servicepoint",
      "flexType": "CARRIER::DEFAULT",
      "retailerId": "2"
    }
  ]
}

Example — auto-derive flexType from type + subtype:

{
  "triggers": [
    {
      "type": "CREDIT_MEMO",
      "subtype": "APPEASEMENT",
      "status": "CREATED",
      "module": "adminconsole",
      "flexVersion": "1.0",
      "retailerId": "2"
    }
  ]
}

Example — list all rules matching "SendEvent":

{
  "name": "SendEvent"
}

GraphQL

| Tool | Description | |---|---| | graphql.query | Execute any query or mutation | | graphql.queryAll | Auto-paginated query — follows cursors across all pages | | graphql.batchMutate | Execute up to 50 mutations in one request | | graphql.introspect | Inspect schema types, mutations, and input fields |

Example — query orders:

{
  "query": "{ orders(first: 5) { edges { cursor node { id ref status } } pageInfo { hasNextPage } } }"
}

Example — auto-paginate all active orders:

{
  "query": "{ orders(first: 100, after: $cursor) { edges { cursor node { id ref status } } pageInfo { hasNextPage } } }",
  "variables": { "cursor": null },
  "maxRecords": 5000
}

Example — batch update 3 orders:

{
  "mutation": "updateOrder",
  "inputs": [
    { "id": "1", "status": "SHIPPED" },
    { "id": "2", "status": "SHIPPED" },
    { "id": "3", "status": "SHIPPED" }
  ],
  "returnFields": ["id", "ref", "status"]
}

Example — dry-run batch mutation (validates query without executing):

{
  "mutation": "updateOrder",
  "inputs": [{ "id": "1", "status": "SHIPPED" }],
  "returnFields": ["id", "ref", "status"],
  "dryRun": true
}

With dryRun: true, returns the generated aliased mutation query and variables for review without making any API call. Use this to preview what will be sent before executing bulk operations.

Batch Ingestion

| Tool | Description | |---|---| | batch.create | Create an ingestion job | | batch.send | Send records to a job | | batch.status | Check job status | | batch.batchStatus | Check a specific batch within a job | | batch.results | Get per-record outcomes |

Typical flow: batch.createbatch.sendbatch.status (poll) → batch.results

Webhook

| Tool | Description | |---|---| | webhook.validate | Validate payload fields and optionally verify cryptographic signature |

Entity Lifecycle

| Tool | Description | |---|---| | entity.create | Type-safe entity creation with field validation, compound key encoding, and retailer auto-injection. Supports 12 entity types. | | entity.update | Status-aware entity updates with optional transition validation via workflow.transitions | | entity.get | Unified entity lookup by ID or ref with optional edge inclusion |

Supported types: ORDER, FULFILMENT, LOCATION, NETWORK, CUSTOMER, PRODUCT, INVENTORY_POSITION, VIRTUAL_CATALOGUE, VIRTUAL_POSITION, CATEGORY, CARRIER, SETTING

Example — create a location:

{
  "entityType": "LOCATION",
  "data": {
    "ref": "LOC_WH_01",
    "type": "WAREHOUSE",
    "name": "Main Warehouse",
    "openingSchedule": { "allHours": true }
  },
  "dryRun": true
}

Workflow Management

| Tool | Description | |---|---| | workflow.get | Fetch a specific workflow by entity type and subtype via REST API. Works even when the list endpoint returns 401. | | workflow.list | List all workflows for a retailer. Deduplicates to latest version per workflow name. | | workflow.upload | Deploy workflow JSON via REST API with structure validation. For production, prefer fluent module install via CLI. | | workflow.diff | Compare two workflow definitions — returns added/removed/modified rulesets with risk assessment. Supports summary, detailed, and mermaid formats. | | workflow.simulate | Static analysis prediction of which rulesets would fire for a given status + event name. Does NOT execute Java rules or check runtime state — use workflow.transitions for authoritative live validation. |

Example — fetch a workflow and save to file:

{
  "entityType": "ORDER",
  "entitySubtype": "HD",
  "retailerId": "2",
  "outputFile": "accounts/MYPROFILE/workflows/MyRetailer/ORDER-HD.json"
}

When outputFile is set, the full workflow JSON is saved to disk and only a summary is returned (status count, ruleset count, total rules). This reads from the live server via REST API — not the CLI workflowlog cache.

Example — list all workflows and download to directory:

{
  "retailerId": "2",
  "outputDir": "accounts/MYPROFILE/workflows/MyRetailer/"
}

With outputDir, each workflow is saved as {TYPE}-{SUBTYPE}.json (e.g., ORDER-HD.json). The response lists saved files with paths and sizes. Without outputDir, returns metadata only (name, version, status count per workflow).

Settings Management

| Tool | Description | |---|---| | setting.get | Fetch settings by name (% wildcards supported), optionally save to local file to keep large JSON out of LLM context | | setting.upsert | Create or update a setting with upsert semantics — queries existing by name + context + contextId first | | setting.bulkUpsert | Batch create/update up to 50 settings with per-setting error handling |

Contexts: RETAILER, ACCOUNT, LOCATION, NETWORK, AGENT, CUSTOMER

Example — fetch a manifest setting and save to file (keeps large JSON out of LLM context):

{
  "name": "fc.mystique.manifest.oms",
  "context": "ACCOUNT",
  "contextId": 0,
  "outputFile": "accounts/MYPROFILE/manifests/backups/fc.mystique.manifest.oms.json"
}

When outputFile is set, the response returns metadata only (name, context, valueType, sizeBytes, savedTo path) — the full JSON goes to disk. For multiple matches (e.g., name: "fc.mystique.manifest.%"), each setting is saved as a separate file in the outputFile directory.

Example — create/update a manifest setting with explicit valueType:

{
  "name": "fc.mystique.manifest.oms.fragment.custom",
  "context": "ACCOUNT",
  "contextId": 0,
  "valueType": "JSON",
  "lobValue": "{\"manifestVersion\":\"2.0\",\"routes\":[]}"
}

Provide either value (for small strings ≤255 chars) or lobValue (for large JSON payloads, as a JSON string). The valueType parameter accepts "STRING", "LOB", or "JSON". For Mystique manifest settings, always use valueType: "JSON" — the default LOB breaks manifest parsing. A warning is emitted if a fc.mystique.manifest.* setting is created without valueType: "JSON".

Environment

| Tool | Description | |---|---| | environment.discover | Full environment snapshot — retailer, locations, networks, catalogues, workflows, settings, modules, users. Each section is opt-in via include array. | | environment.validate | Pre-flight validation checks: auth, retailer, locations, inventory, workflows, settings, modules |

Test Automation

| Tool | Description | |---|---| | test.assert | Assert entity state matches expectations. Supports status, type, attribute, and edge assertions. Optional polling mode retries until pass or timeout. |

Example — assert an order reached BOOKED with at least 1 fulfilment:

{
  "entityType": "ORDER",
  "ref": "HD-001",
  "assertions": {
    "status": "BOOKED",
    "edges": { "fulfilments": { "minCount": 1 } }
  },
  "poll": true,
  "timeoutMs": 60000
}

Cache

| Tool | Description | |---|---| | cache.status | Show local cache statistics — entry count, size, hit/miss rate, per-category breakdown. No API call. | | cache.clear | Clear cached entries by pattern (e.g. workflow:*) or all. No API call, operates on local filesystem only. |

See Cache configuration for env vars, TTLs, and behavior details. Write operations auto-invalidate related cache entries, so manual clearing is only needed after out-of-band changes (CLI deployments, REST API calls, admin console edits).

| Pattern | Clears | |---|---| | workflow:* | All cached workflow list/get responses | | setting:get:fc.mystique.* | Cached manifest and setting lookups | | introspect:* | GraphQL schema introspection cache | | plugin:list | Cached plugin metadata | | (omit pattern) | Everything |

Example — check cache health:

{}

Returns enabled, directory, entries, totalBytes, per-categories breakdown, and session hits/misses.

Example — clear workflow cache after a CLI deploy:

{
  "pattern": "workflow:*"
}

Error Handling

All tools return a consistent envelope:

Success:

{
  "ok": true,
  "response": { }
}

Failure:

{
  "ok": false,
  "error": {
    "code": "AUTH_ERROR",
    "message": "OAuth token request failed.",
    "retryable": false,
    "details": {}
  }
}

| Error Code | Meaning | Retryable | |---|---|---| | CONFIG_ERROR | Missing or invalid environment variables | No | | AUTH_ERROR | Authentication failed | No | | VALIDATION_ERROR | Invalid tool arguments | No | | TIMEOUT_ERROR | Request timed out | Yes | | RATE_LIMIT | API rate limit hit | Yes | | UPSTREAM_UNAVAILABLE | Fluent API unreachable | Yes | | NETWORK_ERROR | Network connectivity issue | Yes | | SDK_ERROR | Unexpected SDK error | Varies | | UNKNOWN_ERROR | Unclassified error | No |

Retry Behavior

Read operations (queries, list, get) use execute() which retries on transient failures (timeout, rate limit, network errors) with exponential backoff up to FLUENT_RETRY_ATTEMPTS times. Write operations (create, update, send, upload, upsert) use executeOnce() with no automatic retry to prevent duplicate side effects. Tune retry parameters via the Resilience Tuning env vars above.

Support Scripts (Debugging and Validation)

These scripts are useful during tenant validation, support, and failure triage:

# Positive smoke test
npm run e2e:smoke -- --profile YOUR_PROFILE --retailer YOUR_RETAILER_REF_OR_ID

# Interactive smoke setup
npm run e2e:smoke -- --wizard

# Negative-path validation (bad payloads, schema failures, error envelopes)
npx tsx scripts/e2e-negative.ts --profile YOUR_PROFILE --retailer YOUR_RETAILER_REF_OR_ID

# Check status of specific events and filtered event lists
npx tsx scripts/check-event-status.ts --profile YOUR_PROFILE --retailer YOUR_RETAILER_REF_OR_ID --event-id <EVENT_ID>

Recommended operator flow:

  1. Run positive smoke (e2e:smoke).
  2. Run negative validation (e2e-negative.ts) to verify expected error handling.
  3. Use check-event-status.ts to trace real event outcomes when diagnosing failures.

Troubleshooting

| Symptom | Likely Cause | Fix | |---|---|---| | config.validate fails | Missing or invalid env vars | Check FLUENT_BASE_URL and at least one complete auth method | | FLUENT_PROFILE auth fails | Profile/retailer ref mismatch or missing files | Verify fluent profile list, profile name, and FLUENT_PROFILE_RETAILER ref | | AUTH_ERROR on any tool | Bad credentials or expired token | Verify OAuth values or regenerate token | | connection.test fails | Network or URL mismatch | Verify API URL, check VPN/proxy, confirm tenant is reachable | | event.send succeeds but workflow doesn't trigger | Event name not mapped in workflow | Check workflow event handlers and ruleset conditions | | Server doesn't appear in MCP client | Config not reloaded | Restart IDE/client after editing .mcp.json | | Events sent to wrong tenant | Wrong FLUENT_BASE_URL | Confirm the API URL and retailer ID | | RATE_LIMIT errors | Too many requests | Reduce request frequency; retryable errors auto-retry up to FLUENT_RETRY_ATTEMPTS |

Development (Contributors)

Using these tools in a development workflow

For a step-by-step guide on using MCP tools to scaffold rules, build modules, fire events, assert state transitions, and debug failures, see docs/DEV_WORKFLOW.md in the @fluentcommerce/ai-skills package.

Workspace layout

When used alongside @fluentcommerce/ai-skills, this server integrates with a workspace convention for managing source code, workflows, and analysis artifacts:

accounts/
  <PROFILE>/
    SOURCE/           # custom source code (account-level, shared across retailers)
      backend/        # Java Maven plugin repos and JAR files
      frontend/       # Mystique SDK component projects
    workflows/        # downloaded workflow JSONs (scoped by retailer)
    analysis/         # generated analysis artifacts

Skills use this server's tools (plugin.list, graphql.query, connection.test, etc.) to:

  • Build a deployed rule inventory by cross-referencing live registered rules with local source
  • Validate connectivity during guided onboarding (/fluent-connect)
  • Run entity count discovery queries during workspace setup
  • Power end-to-end test flows with event dispatch and state assertions

See the Getting Started section in @fluentcommerce/ai-skills for the full directory layout and guided onboarding.

Contributing to this package

git clone https://bitbucket.org/fluentcommerce/fluent-mcp-extn.git
cd fluent-mcp-extn
npm install && npm run build && npm test   # ~378 unit tests
npm run dev                                # hot-reload via tsx

Publish checklist:

  1. Bump version in package.json
  2. npm run build && npm test
  3. npm run e2e:smoke -- --profile <PROFILE> --retailer <RETAILER> (requires live API)
  4. npm pack — inspect contents
  5. npm publish --access public
  6. Post-publish: start via MCP client, run config.validate, health.ping, connection.test

prepublishOnly enforces build && test automatically. Keep credentials out of .mcp.json and docs.

Companion Packages

| Package | Purpose | |---|---| | @fluentcommerce/ai-skills | Install Fluent domain skills across AI coding assistants | | Fluent CLI (@fluentcommerce/cli) | Official CLI and built-in MCP server |

License

MIT