Skip to main content
Glama
nik-net

FastSpring MCP Server

by nik-net

FastSpring MCP Server

Production-ready Model Context Protocol (MCP) server for the FastSpring API. Exposes FastSpring orders, subscriptions, and accounts as MCP tools for use with Claude, Cursor, and any other MCP-compatible client.

Supports two transport modes:

  • STDIO — default; for local MCP clients (Claude Desktop, Cursor, MCP Inspector)

  • Streamable HTTP — for remote clients, hosted deployments, and Docker


Table of Contents

  1. Stack

  2. Environment Variables Reference

  3. Sensitive Information — How to Handle Credentials

  4. Running Locally

  5. Running in Docker

  6. CI/CD Deployments

  7. Connecting MCP Clients

  8. Testing & Inspection

  9. Tools Reference

  10. Logging

  11. Scripts Reference


Related MCP server: Shopify MCP Server

Stack

Concern

Choice

Runtime

Node.js 22 (≥ 20 required)

Language

TypeScript — strict mode

MCP SDK

@modelcontextprotocol/sdk v1.26+

HTTP transport

StreamableHTTPServerTransport (MCP spec)

HTTP client

Axios (Basic auth + interceptors)

Testing

Vitest — mocked HTTP, 80 %+ coverage

Logging

Winston — daily rotation, structured JSON

Container

Docker / Docker Compose


Environment Variables Reference

Required — FastSpring credentials

Variable

Description

FS_API_USERNAME

FastSpring API username

FS_API_PASSWORD

FastSpring API password

Credentials are created in the FastSpring dashboard: Developer Tools → APIs → Create.

Optional — FastSpring settings

Variable

Default

Description

FS_COMPANY_ID

Classic (legacy) API company ID. Required only for order-reference lookups via find_orders_by_reference / get_order_by_reference.

FS_BASE_URL

https://api.fastspring.com

Override if your account uses a company-scoped base URL.

FS_DEBUG

false

Set to true to log every API request and response body.

FS_LOG_LEVEL

debug

Log verbosity: debug info warn error fatal.

FS_LOG_DIR

logs

Directory for daily log files.

Optional — Transport & HTTP server

Variable

Default

Description

MCP_TRANSPORT

stdio

Transport mode: stdio or http.

MCP_HTTP_PORT

3000

Port the HTTP server listens on.

MCP_HTTP_HOST

0.0.0.0

Interface to bind to (0.0.0.0 = all interfaces).

MCP_HTTP_PATH

/mcp

URL path for the MCP endpoint.

MCP_HTTP_STATELESS

false

true = create a new server per request (no session tracking). Suitable for serverless/ephemeral callers.

Optional — HTTP authentication

Variable

Default

Description

MCP_AUTH_ENABLED

false

Set to true to require Bearer token auth on all MCP endpoints. GET /health is always exempt.

MCP_API_KEYS

Comma-separated list of valid API keys. Required when MCP_AUTH_ENABLED=true. Any single key grants full access.

Note: Authentication only applies to the HTTP transport. The STDIO transport is secured by the OS process model and needs no auth configuration.


Sensitive Information — How to Handle Credentials

Rule: credentials (FS_API_USERNAME, FS_API_PASSWORD, FS_COMPANY_ID) are never stored inside the container image or committed to source control. They are always injected at runtime as environment variables.

What is safe and what is not

Location

Safe?

Notes

.env file on your local machine

Never committed (.gitignore), never copied into the image (.dockerignore)

Baked into Dockerfile via ENV

Would be visible in every layer of the image

Committed to git

Permanent, hard to rotate

Docker image layers

docker history / docker inspect exposes them

Runtime environment variable (-e, env:)

The correct approach for all environments

Local development

Use a .env file — it is loaded automatically by the server at startup (via dotenv) and by Docker Compose for variable substitution:

cp .env.example .env
# Edit .env and fill in your credentials

The .env file is excluded from git and Docker builds:

  • .gitignore → never committed

  • .dockerignore → never copied into the image

CI/CD and production

Do not use a .env file. Inject credentials as environment variables from your platform's secret store:

GitHub Actions

env:
  FS_API_USERNAME: ${{ secrets.FS_API_USERNAME }}
  FS_API_PASSWORD: ${{ secrets.FS_API_PASSWORD }}
  FS_COMPANY_ID:   ${{ secrets.FS_COMPANY_ID }}

AWS ECS

{
  "secrets": [
    { "name": "FS_API_USERNAME", "valueFrom": "arn:aws:secretsmanager:..." },
    { "name": "FS_API_PASSWORD", "valueFrom": "arn:aws:secretsmanager:..." }
  ]
}

Kubernetes

env:
  - name: FS_API_USERNAME
    valueFrom:
      secretKeyRef:
        name: fastspring-credentials
        key: username

Render / Railway / Fly.io / Heroku — use the platform's "Environment Variables" or "Secrets" UI dashboard.


Running Locally

Prerequisites

node --version   # must be ≥ 20
npm --version

Install and build:

npm install
npm run build

Configure credentials:

cp .env.example .env
# Edit .env — set FS_API_USERNAME and FS_API_PASSWORD at minimum

STDIO transport (default)

STDIO is the standard transport for local MCP clients. The client (Cursor, Claude Desktop, MCP Inspector) spawns the server as a child process and communicates over stdin/stdout.

npm start
# or explicitly:
npm run start:stdio

The server produces no console output on startup (MCP protocol runs over stdio — any stdout/stderr would corrupt the stream). All logs go to the logs/ directory.


Streamable HTTP transport

HTTP mode starts a local web server. Use this when you want to call the server from a script, another process, or a remote MCP client.

npm run start:http

Default endpoint: http://localhost:3000/mcp

Custom port or path:

MCP_HTTP_PORT=8080 MCP_HTTP_PATH=/api/mcp npm run start:http

Verify it is running:

curl http://localhost:3000/health
# → {"status":"ok","transport":"streamable-http","mode":"stateful","sessions":0}

Stateless mode (new server instance per request — useful for scripts or one-shot callers):

MCP_HTTP_STATELESS=true npm run start:http

Test with the MCP Inspector UI (HTTP mode):

npm run test:inspector:http
# Starts the server in HTTP mode, then opens the Inspector UI pointing at it

Running in Docker

The Docker image defaults to HTTP transport (MCP_TRANSPORT=http) and binds to 0.0.0.0 so it is reachable from outside the container. Credentials are never baked into the image — they are always passed at runtime.

Persistent container (recommended) — runs in the background and restarts automatically after a machine reboot:

npm run docker:start

Stop it with npm run docker:stop. Ensure .env exists with FS_API_USERNAME and FS_API_PASSWORD (see Environment variables).

Prerequisites

You need both the Docker daemon and the Compose plugin. The easiest way to get both together is Docker Desktop.

Download and install from https://www.docker.com/products/docker-desktop/

Docker Desktop bundles the Docker daemon, the docker CLI, and the docker compose plugin (v2). After installing and starting Docker Desktop:

docker --version          # Docker version 29.x or later
docker compose version    # Docker Compose version v2.x or later

Option B — Docker CLI + Compose plugin via Homebrew (Mac)

If you already have the Docker CLI installed via Homebrew (brew install docker) but without Docker Desktop, install the standalone Compose plugin separately:

brew install docker-compose

Then use the hyphenated docker-compose command (v1) or the :v1 npm script variants:

docker-compose --version  # docker-compose version 1.x or 2.x

How to tell which you have: Run docker compose version (with a space). If it says unknown command, you have the CLI only and need Option A or B above.


Docker Compose reads your .env file automatically for variable substitution and passes each credential as a runtime environment variable into the container. The .env file itself is never copied into the image. The Compose file sets restart: unless-stopped, so the container survives reboots when run in detached mode.

Action

Command

Start (persistent, restarts on reboot)

npm run docker:start or docker compose up -d --build

Start (foreground, see logs in terminal)

npm run docker:up or docker compose up

Stop

npm run docker:stop or npm run docker:down

Logs

npm run docker:logs

Compose v1 (Homebrew docker-compose): use npm run docker:up:v1, npm run docker:down:v1, npm run docker:logs:v1.

Verify:

curl http://localhost:3000/health

Custom port — set MCP_HTTP_PORT in your .env or shell before starting:

MCP_HTTP_PORT=8080 npm run docker:start

What Docker Compose does with your .env:

Docker Compose reads .env from the project directory and substitutes ${VAR} placeholders in docker-compose.yml. The result is that each variable is passed to the container as a standard environment variable. The .env file stays on your machine — it is not mounted into the container, and .dockerignore prevents it from entering the build context.


Plain Docker run

Build the image once, then run with env from a file. For a persistent container (restarts on reboot), use docker:run:env which uses --restart unless-stopped and a named container (no --rm).

Build:

npm run docker:build

Run persistent (loads .env, container survives reboot; stop with docker stop fastspring-mcp):

npm run docker:run:env

Run one-off (container removed when it stops; credentials from shell):

export FS_API_USERNAME=your_username FS_API_PASSWORD=your_password
docker run --rm --env-file .env -p 3000:3000 fastspring-mcp

CI/CD Deployments

For CI/CD pipelines, there is no .env file. Inject all variables as secrets provided by your platform.

Generic pattern:

# 1. Build the image (no secrets needed at build time)
docker build -t fastspring-mcp .

# 2. Push to a registry
docker tag fastspring-mcp registry.example.com/fastspring-mcp:latest
docker push registry.example.com/fastspring-mcp:latest

# 3. Deploy — pass secrets as environment variables at runtime
docker run -d --restart unless-stopped --name fastspring-mcp \
  -e FS_API_USERNAME="$FS_API_USERNAME" \
  -e FS_API_PASSWORD="$FS_API_PASSWORD" \
  -e FS_COMPANY_ID="$FS_COMPANY_ID" \
  -e MCP_TRANSPORT=http \
  -e MCP_HTTP_HOST=0.0.0.0 \
  -e MCP_HTTP_PORT=3000 \
  -p 3000:3000 \
  registry.example.com/fastspring-mcp:latest

The --restart unless-stopped and --name fastspring-mcp flags make the container persistent and restart automatically after a reboot.

The server performs fail-fast validation at startup: if FS_API_USERNAME or FS_API_PASSWORD are missing, the process exits immediately with a clear error. Misconfiguration is caught at boot, not at the first API call.


Connecting MCP Clients

Cursor / Claude Desktop (STDIO)

Add to your MCP config file (e.g. ~/.cursor/mcp.json):

{
  "mcpServers": {
    "fastspring": {
      "command": "node",
      "args": ["/absolute/path/to/fs-mcp/dist/index.js"],
      "env": {
        "FS_API_USERNAME": "your_username",
        "FS_API_PASSWORD": "your_password",
        "FS_COMPANY_ID":   "your_company_id"
      }
    }
  }
}

The client spawns the server as a subprocess. The env block passes credentials directly — no .env file required when using this approach.


Cursor / Claude Desktop (HTTP)

Start the server in HTTP mode first (locally or via Docker), then configure your client to connect by URL.

Claude Desktop only supports stdio transport natively. To connect it to an HTTP MCP server, use mcp-remote as a proxy bridge — npx fetches it automatically, no install required.

Without authentication (MCP_AUTH_ENABLED=false, default):

{
  "mcpServers": {
    "fastspring": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "http://localhost:3000/mcp"
      ]
    }
  }
}

With authentication (MCP_AUTH_ENABLED=true):

{
  "mcpServers": {
    "fastspring": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "http://localhost:3000/mcp",
        "--header",
        "Authorization:Bearer <your-api-key>"
      ]
    }
  }
}

Claude.ai (remote HTTP)

Claude.ai connects to remote MCP servers over the Streamable HTTP transport. Deploy this server (via Docker or any Node host), then add the public URL in Claude.ai's MCP server settings:

https://your-server.example.com/mcp

If authentication is enabled, include the Authorization: Bearer <key> header in your client configuration. Ensure the server is behind HTTPS (e.g. a reverse proxy such as nginx or Caddy) for production use.


Generating API keys

Use Node.js to generate a cryptographically secure random key:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Add one or more keys to your .env:

MCP_AUTH_ENABLED=true
MCP_API_KEYS=a3f8c2...,b7d1e9...

The server accepts any key in the list, so different clients can use different keys and be revoked independently by removing their key and restarting.


Testing & Inspection

Unit tests

Run the full test suite with coverage (thresholds: 80 % lines/statements/functions, 75 % branches). All HTTP calls are mocked — no real FastSpring API calls are made.

npm test

Watch mode:

npm run test:watch

Type-check only (no emit):

npm run typecheck

Smoke test (no browser)

Spawns the server, sends MCP initialize and tools/list over STDIO, and prints the JSON responses. Useful for verifying the server starts correctly without a browser or UI:

npm run test:smoke

Save output for sharing or debugging:

npm run test:smoke > logs/smoke.txt 2>&1

MCP Inspector — STDIO mode

The MCP Inspector provides a browser UI to list and invoke tools. In STDIO mode it spawns the server as a child process:

npm run test:inspector
# Opens Inspector UI at http://localhost:6274

Pass credentials if you are not using a .env file:

FS_API_USERNAME=xxx FS_API_PASSWORD=yyy npm run test:inspector

MCP Inspector — HTTP mode

In HTTP mode the Inspector connects to an already-running server by URL. This command starts the server in HTTP mode in the background, waits for it to be ready, then opens the Inspector:

npm run test:inspector:http
# Opens Inspector UI connected to http://localhost:3000/mcp

Custom port:

MCP_HTTP_PORT=8080 npm run test:inspector:http

Integration test (real API)

Calls the real FastSpring API with your credentials. Requires a valid .env with credentials and optionally TEST_CUSTOMER_EMAIL:

npm run test:integration

Tools Reference

All tools return JSON. Errors include an error field, and when available statusCode and responseBody from FastSpring. All string inputs are trimmed before calling the API.

Orders

Tool

Description

Inputs

get_order

Fetch a single order by internal FastSpring order ID.

orderId (string)

find_orders_by_email

List all orders for a customer by email.

email (string)

find_orders_by_reference

Look up orders by reference (e.g. VI8201014-6538-11102S).

reference (string)

get_order_by_reference

Fetch full order detail by reference via the Classic API.

reference (string)

Subscriptions

Tool

Description

Inputs

get_subscription

Fetch a subscription by internal subscription ID.

subscriptionId (string)

get_subscription_by_reference

Look up a subscription by reference.

reference (string)

list_subscriptions

List subscriptions with optional filters.

status (optional), product (optional), email (optional)

get_subscription_entries

Get line items for a subscription.

subscriptionId (string)

Accounts

Tool

Description

Inputs

get_account

Fetch a customer account by ID.

accountId (string)

find_account_by_email

Look up an account by customer email.

email (string)

get_account_orders

Get all orders for an account.

accountId (string)

ID vs reference — avoiding 400 errors

  • get_order and get_subscription use FastSpring's internal ID in the URL path. Passing a human-readable reference (e.g. VI8201014-6538-11102S) will return 400 Bad Request.

  • Use find_orders_by_reference or get_subscription_by_reference when you have a reference string.

  • Internal IDs are available in the FastSpring dashboard or from list tools (find_orders_by_email, list_subscriptions, etc.) which return objects containing both id and reference.

  • If you get 400 on valid-looking IDs, your account may use a company-scoped base URL. Set FS_BASE_URL=https://api.fastspring.com/company/yourcompany in .env.


Logging

  • Daily rotation: one file per day under FS_LOG_DIR (default logs/), e.g. logs/fastspring-mcp-2026-02-19.log. Files are retained for 14 days.

  • Levels: fatal error warn info debug — set via FS_LOG_LEVEL.

  • DEBUG level: logs every FastSpring API request (method, URL) and response (status, body). Enable with FS_DEBUG=true or FS_LOG_LEVEL=debug.

  • Format: pretty-printed lines with timestamp, level, message, and JSON metadata. Credentials are never logged.

  • Docker: the logs/ directory is mounted as a volume (./logs:/app/logs) so logs persist across container restarts.


Scripts Reference

Development

Script

Description

npm run build

Compile TypeScript → dist/

npm start

Start server in STDIO mode (default)

npm run start:stdio

Start server explicitly in STDIO mode

npm run start:http

Start server in Streamable HTTP mode (port 3000)

npm run typecheck

Type-check without emitting

npm run lint

ESLint on src/

Testing

Script

Description

npm test

Vitest unit tests with coverage

npm run test:watch

Vitest in watch mode

npm run test:smoke

Smoke test over STDIO — no browser required

npm run test:integration

Integration test against real FastSpring API

npm run test:inspector

MCP Inspector UI — STDIO mode

npm run test:inspector:http

MCP Inspector UI — HTTP mode (starts server + opens Inspector)

Docker

Script

Description

npm run docker:start

Start persistent container (detached; restarts on reboot) — recommended

npm run docker:stop

Stop and remove containers (Compose)

npm run docker:build

Build the Docker image only

npm run docker:run

Same as docker:start (Compose up -d)

npm run docker:up

Start in foreground (logs in terminal; Ctrl+C stops container)

npm run docker:down

Same as docker:stop

npm run docker:logs

Tail container logs (Compose v2)

npm run docker:run:env

Plain docker run with .env, persistent (--restart unless-stopped)

npm run docker:up:v1 / docker:down:v1 / docker:logs:v1

Compose v1 (docker-compose)


License

This project is dual-licensed.

  • AGPL v3 — Default. You may use, modify, and distribute the software under the terms of the GNU Affero General Public License v3. If you run a modified version as a service over a network, you must make the corresponding source available to users of that service.

  • Commercial — Use in proprietary products or services without AGPL’s source-availability obligations requires a separate commercial license. See COMMERCIAL_LICENSE.md for details.

Commercial licensing enquiries: help@gotmo.co.uk

Available Tools

11 tools
create_quoteA

Use this tool to create a new quote (formal order document) for one or more FastSpring subscription or product SKUs on behalf of a buyer.

A quote is the correct way to programmatically generate a Custom Order in FastSpring — it is NOT a checkout session and does NOT charge the buyer.

On success the tool returns a quoteUrl — a permanent payment link you can send to the buyer. The buyer opens the link, sees a full B2B quote document with line items, VAT/tax breakdown, and pricing, then pays on the FastSpring storefront at their convenience. The quote appears immediately in the FastSpring dashboard under Quotes and remains open until paid, cancelled, or expired (default 30 days, maximum 90 days).

Required inputs: quote name, at least one product SKU, buyer first name, last name, email, and billing country (2-letter ISO code).

Optional: quantity and price overrides per item, coupon code, currency, expiration days (1–90), fulfilment term, notes, net-terms days, tags (array of {key, value} objects), and buyer VAT/tax ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
tagsNo
itemsYesOne or more products to include in the quote. Each item must reference a valid FastSpring product SKU. Required.
notesNo
taxIdNo
couponNo
currencyNo
recipientYesBuyer contact details. first, last, and email are required.
netTermsDaysNo
fulfillmentTermNo
recipientAddressYesBilling address for the buyer. country (2-letter ISO code) is required.
expirationDateDaysNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the return value (quoteUrl), the lifecycle (open until paid, cancelled, or expired; default 30 days), and that it appears in the dashboard. However, it does not mention permission requirements or failure modes, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the main purpose, then provides key outcome details and input requirements in a structured way. It's longer than minimal, but each section adds necessary context for a complex 12-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For the tool's complexity, the description covers the core concept, outcome, required/optional inputs, and lifecycle. It lacks detailed parameter semantics and doesn't always connect to schema, but overall it gives sufficient context for correct use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 25%, so the description must compensate. It lists all required and optional parameters and clarifies the tags format (array of {key, value} objects), but does not explain semantics for fields like netTermsDays or fulfillmentTerm, leaving gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool creates a new quote (formal order document) for FastSpring SKUs, and distinguishes it from checkout sessions by explicitly saying it does not charge the buyer. It also positions it as the correct way to generate a Custom Order, which differentiates it from the read/update sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit guidance on when to use (to generate a Custom Order/quote) and when not (not a checkout session, does not charge). While it doesn't name an alternative tool, no creation alternative exists among siblings; the exclusion of charging behavior is a clear when-not.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_accountA

Fetch a FastSpring customer account by its account ID. Returns the account details including email, name, company, and billing address.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountIdYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the full burden. It states what the tool returns but does not explicitly disclose that it is read-only, mention error behavior, or side effects. 'Fetch' implies a safe read, providing adequate but not rich transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the action and resource, followed by return details. Every word earns its place, with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple getter with one parameter and no output schema, the description covers the what, how, and return value. It misses explicit differentiation from get_account_by_email and potential error handling, but overall it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It adds semantic meaning by identifying the parameter as the 'account ID', which is the key required. It does not elaborate on format or source, but for a single parameter this is sufficient.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Fetch' and the resource 'FastSpring customer account' with the specific lookup method 'by its account ID'. This distinguishes it from the sibling tool get_account_by_email, which fetches by email.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: users should call this when they have an account ID. However, it does not explicitly mention when not to use it or suggest alternatives like get_account_by_email, so the guidance is only implied, not explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_account_by_emailA

Look up a FastSpring customer account by email address. Returns the account details if found.

ParametersJSON Schema
NameRequiredDescriptionDefault
emailYes

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses that account details are returned 'if found', which hints at conditional behavior, but does not specify what happens when no account exists (e.g., empty response, error). It also omits any side effects or authentication requirements, though reads are likely safe.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that directly states the action and expected result. Every word contributes meaning, with no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter lookup tool, the description covers the essential purpose and return outcome. It would benefit from specifying the not-found behavior and possibly a brief contrast with get_account, but these are minor gaps given the tool's low complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the description merely restates the parameter name ('email address'), adding no extra detail about format, validation, case-sensitivity, or expected input. Since the schema only declares a string type, the description fails to compensate for the low coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Look up') and resource ('FastSpring customer account') with a clear query method ('by email address'). It distinguishes itself from siblings like get_account, which likely uses an account ID, and get_account_orders, which focuses on orders.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when an email is known, but does not explicitly state when to prefer this tool over alternatives such as get_account (likely by ID) or list_orders_by_email. No exclusions or alternative references are provided, so guidance remains implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_account_ordersA

Get all orders placed by a FastSpring customer account. Pass the account ID to retrieve the full order history for that account.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountIdYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose behavior. It states the operation is a read ('Get all orders') and clarifies the required input, but it does not mention response format, pagination, errors, or permissions. This is minimally sufficient but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences, front-loaded with the purpose, and contains no unnecessary words. Every phrase adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the low complexity (single parameter, no output schema, no annotations), the description covers the essential purpose and parameter. It lacks explicit usage exclusions, but for a simple read tool it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains that 'accountId' is the account whose order history is retrieved, but does not provide additional details about the ID format or source. This adds some meaning beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves all orders for a FastSpring customer account, with a specific verb ('Get') and resource ('orders'). It also distinguishes itself from siblings like get_order (single order) and list_orders_by_email (by email).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the use case: when you have a customer account ID and need full order history. It does not explicitly name alternatives or exclusions, but the context is clear enough for an agent to select it over siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_orderA

Fetch a FastSpring order by its ID or reference number (e.g. VI0000000-0000-00000). Accepts any identifier — the system checks both the current and legacy FastSpring platforms automatically. The response includes a 'platform' field ('modern' or 'legacy') telling you which platform holds the record, and a 'data' field with the full order details. Modern platform orders include: id, reference, status, customer, line items, total, and currency. Legacy platform orders include: reference, status, customer, billing address, line items (each with a subscriptionReference if the line item created a subscription), payments, total, tax, shipping, and referrer.

ParametersJSON Schema
NameRequiredDescriptionDefault
referenceYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description fully discloses key behaviors: it checks both current and legacy platforms, returns a 'platform' field indicating the source, and details the exact fields present in modern vs. legacy responses. This goes beyond basic fetch semantics and gives the agent precise expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the core action, followed by useful behavioral and response details. Every sentence adds value, including the breakdown of modern vs. legacy fields, without extraneous information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema, the description effectively explains the return value, including the 'platform' and 'data' fields and their contents. It covers the parameter, platform detection, and field differences, making the tool fully comprehensible for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema only defines 'reference' as a string. The description adds meaning by explaining it accepts ID or reference number and provides an example format. This compensates for the 0% schema description coverage, making the parameter semantics clear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Fetch') and resource ('FastSpring order'). It also specifies the identifier types (ID or reference number) and includes an example format, distinguishing it from sibling tools that list orders or handle subscriptions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: use when you have an order identifier to fetch a single order. It provides context about dual-platform lookup but does not explicitly mention alternatives or when not to use. This is clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_subscriptionA

Fetch a FastSpring subscription by its ID or reference number (e.g. VI8201014-6538-11102S). Accepts any identifier — the system checks both the current and legacy FastSpring platforms automatically. The response includes a 'platform' field ('modern' or 'legacy') that tells you which platform holds the record, and a 'data' field with the subscription details. Modern platform subscriptions include: id, status, product, customer, start/end dates, next charge date, and line items. Legacy platform subscriptions include: reference, status, customer, product name, quantity, next renewal date, and end date.

ParametersJSON Schema
NameRequiredDescriptionDefault
referenceYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the transparency burden. It discloses that the system checks both current and legacy platforms automatically, and describes the response structure including the 'platform' field. It does not mention error cases or permissions, but for a fetch operation this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average but every sentence adds value. It starts with the core purpose, then the platform behavior, then the response fields – structured logically with no fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (1 parameter, no output schema), the description is remarkably complete. It explains the response with platform-specific fields and even distinguishes modern vs legacy formats, giving an agent full expectations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, but the description thoroughly explains the 'reference' parameter as an ID or reference number, provides a concrete example, and clarifies that any identifier is accepted. This fully compensates for the missing schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Fetch a FastSpring subscription by its ID or reference number,' with a concrete example. It distinguishes itself from siblings by focusing on fetching a single subscription by identifier, not listing or line items.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when you have a subscription identifier and need full details. It does not explicitly name alternatives or exclusions, but the context is clear enough for an agent to choose this over list_subscriptions or get_subscription_line_items.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_subscription_line_itemsA

Get the products and quantities on a subscription. Requires the subscription's internal FastSpring ID — the 'id' field from get_subscription results. Returns the list of products, quantities, and SKUs currently on the subscription.

ParametersJSON Schema
NameRequiredDescriptionDefault
subscriptionIdYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It does explain the required input and return value, but it does not explicitly state whether the operation is read-only, mention authorization requirements, or describe error conditions. The 'Get' and 'Returns' phrasing implies a safe read, but this is not as explicit as it could be.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with no fluff. It front-loads the primary purpose and immediately adds the key prerequisite and return information, making every sentence valuable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter getter with no output schema, the description covers the essential aspects: purpose, required input, sourcing instructions, and return values. It lacks only explicit notes on edge cases like empty results or authentication, but these are not critical for basic usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it does. It explains that subscriptionId is the subscription's internal FastSpring ID and tells the agent exactly where to obtain it (the 'id' field from get_subscription results). This provides meaningful semantics beyond the raw schema, though it does not detail the ID format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Get') and clearly identifies the resource ('products and quantities on a subscription'), distinguishing it from sibling tools like get_subscription. It further clarifies the return content as products, quantities, and SKUs, leaving no ambiguity about its purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context by stating it requires the subscription's internal FastSpring ID, referencing the 'id' field from get_subscription results. This implicitly tells the agent to first call get_subscription, but it does not explicitly name alternative tools or exclusions, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_orders_by_emailA

List all orders for a customer by their email address. Returns an array of order objects from the current FastSpring platform. Use get_order to fetch the full detail of any individual order.

ParametersJSON Schema
NameRequiredDescriptionDefault
emailYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It states the return type ('array of order objects') and platform context, which is useful. However, it does not disclose exact-match behavior for email, pagination, or potential side effects, leaving some uncertainty.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Very concise: two sentences, each with a distinct purpose. The first states the tool's function, the second points to a sibling tool. No wasted words and the most important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter tool with no output schema, the description covers the essential purpose, return type, and a useful alternative. It lacks explicit pagination or exact-match details, but these are not critical given the low complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, so the description must compensate. It adds that the email identifies the customer, but it does not provide format details, matching rules, or additional parameter clarifications. Minimal compensation for the missing schema description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'List' with a clear resource ('orders') and a defined scope ('by their email address'), making the tool's function immediately obvious. It also explicitly distinguishes itself from get_order by directing users there for full order details.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description offers a clear usage path: use this to list orders by email, then use get_order for full detail. However, it does not mention other sibling tools like get_account_orders or list_subscriptions, so the guidance is helpful but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_subscriptionsA

Search for FastSpring subscriptions on the current platform. Optionally filter by status (e.g. active, deactivated), product name, or customer email. Returns a list of matching subscriptions. Use get_subscription to fetch the full details of a specific subscription.

ParametersJSON Schema
NameRequiredDescriptionDefault
emailYesFilter by customer email address
statusNo
productNo

TDQS

A3.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description states it searches within the current platform and returns a list, but it contradicts the input schema by saying 'Optionally filter by ... customer email' while email is a required parameter. It also lacks other behavioral disclosures like pagination or return format. The required-email mismatch is misleading and significant.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four concise sentences, each with a distinct purpose: state the action, mention filters, state the return, and provide an alternative. The description is front-loaded with the core purpose and contains no fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no annotations, the description is the only source of behavioral information. It fails to mention that email is required, doesn't describe the list output structure or pagination, and omits any error or permission context. The alternative tool reference adds value but the gaps are significant for a list operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, so the description should compensate. It adds meaning for 'status' (with examples active/deactivated) and clarifies 'product' as product name, but it doesn't explain the unusual email object type or resolve the optional-vs-required contradiction. This is partial compensation, not full.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Search'), resource ('FastSpring subscriptions'), and scope ('current platform'). It also distinguishes itself from the sibling 'get_subscription' by explicitly noting it returns a list and pointing to get_subscription for full details.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: use this tool to search for subscriptions with optional filters, and explicitly names an alternative ('Use get_subscription to fetch the full details of a specific subscription'). This tells the agent when to prefer one tool over the other.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_order_tagsA

Add or replace tags and/or per-product attributes on a FastSpring order. Requires the order's internal FastSpring ID (the 'id' field returned by get_order). Provide 'tags' to set order-level key-value metadata — these REPLACE the full existing tag set. Provide 'items' to set attributes on specific product line items within the order — each entry must include the product path and an attributes map, which also REPLACE the existing attributes for that product. Both 'tags' and 'items' are optional; include whichever you need to update. Active subscriptions created from this order automatically inherit the updated attributes. API: POST /orders

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsNoA flat key-value map where both keys and values are strings.
itemsNo
orderIdYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must disclose behavioral traits, and it does: it explicitly warns that tags and item attributes REPLACE existing sets, which is critical for a mutation tool. It also notes that active subscriptions automatically inherit updated attributes. It omits auth/error details but covers the most consequential behaviors.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average but every sentence earns its place, covering purpose, prerequisite, parameter semantics, and a side-effect. It is front-loaded with the main action and structured logically, though it could be trimmed slightly without losing value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex mutation tool with nested objects, no annotations, and no output schema, the description provides the essential context: prerequisites, replacement behavior, optionality, and inheritance. It does not describe the response format or error cases, but the invocation-relevant information is clear and sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 33%, so the description must compensate. It adds meaning for all three parameters: orderId must be the internal FastSpring ID, tags is a flat key-value map, and items require a product path and an attributes map. It also clarifies that both are optional and highlights the replacement semantics, fully compensating for the schema gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Add or replace tags and/or per-product attributes on a FastSpring order.' This clearly distinguishes it from sibling update_subscription_tags by targeting orders, and it names the API endpoint for precision.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly requires the order's internal FastSpring ID from get_order, directing the agent to a sibling tool for prerequisites. It also explains when to use 'tags' vs 'items' and states both are optional, providing clear context without explicitly naming alternatives like update_subscription_tags.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_subscription_tagsA

Add or replace tags on a FastSpring subscription. Requires the subscription's internal FastSpring SBL ID (the 'id' field returned by get_subscription). Provide a 'tags' map of string key-value pairs — these REPLACE the full existing tag set on the subscription. To remove all tags pass an empty object. API: POST /subscriptions/{subscriptionId}

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsYesKey-value string pairs to set as subscription-level tags. These REPLACE the full existing tag set on the subscription.
subscriptionIdYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Without annotations, the description carries the full burden and excels by disclosing that tags REPLACE the full existing set, not merge. It also warns about the need for the internal SBL ID and gives the removal pattern via empty object. This is critical side-effect information for a mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, each earning its place: purpose, prerequisite, behavioral rule, removal method, and API endpoint. The description is front-loaded with the action and avoids any filler or redundancy. Perfectly sized for quick comprehension.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations and no output schema, the description covers prerequisites, parameter semantics, and the crucial replace behavior thoroughly. The API endpoint adds practical context for debugging. For a mutation tool, this is complete enough for correct selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema only documents the 'tags' parameter's replace behavior, leaving 'subscriptionId' undocumented. The description compensates by identifying 'subscriptionId' as the internal FastSpring SBL ID returned by get_subscription, and for 'tags' reinforces the map structure and full-replacement semantics. This adds significant meaning beyond the schema's 50% coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Add or replace' on the specific resource 'FastSpring subscription', and specifies the exact API endpoint. It differentiates from the sibling 'update_order_tags' by targeting subscriptions and explicitly stating the full-replacement semantic. No ambiguity about the tool's function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides strong contextual guidance by requiring the internal FastSpring SBL ID from get_subscription, which tells users they must first fetch the subscription. It also explains the replacement behavior and how to remove all tags, which covers key usage scenarios. It does not explicitly name alternatives like 'update_order_tags', but the resource-specific focus is clear from the purpose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 11 tool updatesv1.0.0
    • First observedcreate_quote
    • First observedget_account
    • First observedget_account_by_email
    • First observedget_account_orders
    • First observedget_order
    • First observedget_subscription
    • First observedget_subscription_line_items
    • First observedlist_orders_by_email
    • First observedlist_subscriptions
    • First observedupdate_order_tags
    • First observedupdate_subscription_tags

TDQS

A4.2/5.0
Disambiguation5/5

Each tool targets a distinct resource and action. While get_account and get_account_by_email both fetch accounts, they are clearly differentiated by identifier type. The descriptions are explicit about what each tool does.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (get_, list_, update_, create_). The naming clearly distinguishes single-item retrieval from list operations, and actions are aligned with resource types.

Tool Count5/5

With 11 tools covering orders, subscriptions, accounts, and quotes, the server is well-scoped for a commerce platform. Each tool has a clear purpose and the set is neither sparse nor bloated.

Completeness4/5

The tool set covers core read operations for orders, subscriptions, and accounts, plus subscription line items and quote creation. Minor gaps exist (e.g., subscription cancellation, quote management, order updates beyond tags), but agents can work around these for most workflows.

Maintenance

ActivityInactive
ResponsivenessUnresponsive

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nik-net/fastspring-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server