Skip to main content

StockTrim OpenAPI Client

A production-ready Python client library and MCP server for the StockTrim Inventory Management API.

Python Version License Code style: ruff CI codecov Security pre-commit

Client: PyPI - Version

MCP: PyPI - MCP Server

Features

Client Library

  • 🎯 Domain Helpers: Ergonomic wrapper methods for common operations (15+ convenience functions)
  • 🔄 Transport-Layer Resilience: Automatic retries with exponential backoff built into HTTP transport
  • ⚡ Modern Python: Fully async/await with comprehensive type hints (ty strict)
  • 🔐 Custom Authentication: Automatic handling of StockTrim api-auth-id and api-auth-signature headers
  • 🛡️ Typed Exceptions: Structured error handling (AuthenticationError, ValidationError, ServerError, etc.)
  • 📦 OpenAPI Generated: Always up-to-date with the latest StockTrim API

MCP Server

  • 🤖 AI Integration: Natural language interface for Claude and other AI assistants
  • ⚡ FastMCP: High-performance Model Context Protocol implementation
  • 🔧 Production Ready: 30 tools, 5 workflow prompts, and resource endpoints
  • 🎯 Type-Safe: Full Pydantic validation for all operations
  • 🏗️ Service Architecture: Clean service layer with dependency injection
  • 🛡️ Safety Patterns: User confirmation for destructive operations
  • 📝 Well-Documented: Comprehensive usage examples and troubleshooting

Installation

Client Library

# With UV (recommended)
uv add stocktrim-openapi-client

# With pip
pip install stocktrim-openapi-client

# With Poetry
poetry add stocktrim-openapi-client

MCP Server

# With UV
uv add stocktrim-mcp-server

# With pip
pip install stocktrim-mcp-server

Quick Start

from stocktrim_public_api_client import StockTrimClient

async with StockTrimClient(
    api_auth_id="your_tenant_id",
    api_auth_signature="your_tenant_name"
) as client:
    # Product operations
    product = await client.products.find_by_code("WIDGET-001")
    widgets = await client.products.search("WIDGET")
    exists = await client.products.exists("WIDGET-001")

    # Customer operations
    customer = await client.customers.get("CUST-001")
    customer = await client.customers.find_or_create(
        "CUST-002",
        name="New Customer",
        email="customer@example.com"
    )

    # Inventory operations
    await client.inventory.set_for_product(
        product_id="123",
        stock_on_hand=50.0,
        stock_on_order=100.0,
        location_code="WAREHOUSE-A"
    )

Using Generated API Methods

from stocktrim_public_api_client import StockTrimClient
from stocktrim_public_api_client.generated.api.products import get_api_products
from stocktrim_public_api_client.utils import unwrap

async with StockTrimClient(
    api_auth_id="your_tenant_id",
    api_auth_signature="your_tenant_name"
) as client:
    # Direct API call with automatic retries and auth
    response = await get_api_products.asyncio_detailed(client=client)

    # Unwrap response or raise typed exception
    products = unwrap(response)  # Raises AuthenticationError, ServerError, etc.

MCP Server

# Set environment variables
export STOCKTRIM_API_AUTH_ID=your_tenant_id
export STOCKTRIM_API_AUTH_SIGNATURE=your_tenant_name

# Run server
uvx stocktrim-mcp-server

For Claude Desktop integration, see MCP Server README.

Domain Helpers

The client provides convenient helper classes that wrap the generated API:

Products

  • find_by_code(code) - Get product by exact code
  • search(code_prefix) - Find products starting with prefix
  • exists(code) - Check if product exists
  • get_all() - List all products
  • create(...) - Create new product
  • delete(product_id) - Delete product

Customers

  • get(code) - Get customer by code
  • get_all() - List all customers
  • exists(code) - Check if customer exists
  • find_or_create(code, **defaults) - Get or create customer (idempotent)
  • update(customer) - Update customer

Suppliers

  • find_by_code(code) - Get supplier by code (handles API inconsistencies)
  • create_one(supplier) - Create single supplier
  • exists(code) - Check if supplier exists
  • get_all() - List all suppliers
  • create([suppliers]) - Batch create suppliers
  • delete(code) - Delete supplier

Sales Orders

  • get_for_product(product_id) - Get orders for specific product
  • delete_for_product(product_id) - Delete all orders for product
  • get_all() - List all orders
  • create(...) - Create order
  • delete(...) - Delete orders

Purchase Orders

  • find_by_reference(reference_number) - Get order by reference
  • exists(reference_number) - Check if order exists
  • get_all() - List all orders
  • create(...) - Create order
  • delete(...) - Delete orders

Inventory

  • set_for_product(product_id, stock_on_hand, stock_on_order, ...) - Set inventory levels
  • set(request) - Batch set inventory

Locations

  • get_all() - List all locations
  • create(...) - Create location

See docs/user-guide/helper-methods.md for complete documentation.

Error Handling

The client provides typed exceptions for structured error handling:

from stocktrim_public_api_client.utils import (
    unwrap,
    AuthenticationError,
    ValidationError,
    NotFoundError,
    ServerError
)

try:
    product = unwrap(response)
except AuthenticationError:
    print("Invalid credentials")
except ValidationError as e:
    print(f"Validation failed: {e.validation_errors}")
except NotFoundError:
    print("Product not found")
except ServerError as e:
    print(f"Server error: {e.status_code}")

Configuration

Environment Variables

# Required
STOCKTRIM_API_AUTH_ID=your_tenant_id
STOCKTRIM_API_AUTH_SIGNATURE=your_tenant_name

# Optional
STOCKTRIM_BASE_URL=https://api.stocktrim.com  # Default

Programmatic Configuration

async with StockTrimClient(
    api_auth_id="your_tenant_id",
    api_auth_signature="your_tenant_name",
    base_url="https://api.stocktrim.com",
    timeout=30.0,
    max_retries=5
) as client:
    # Use client
    pass

Architecture

Transport-Layer Resilience

Resilience features are implemented at the HTTP transport level:

  • Automatic retries on 5xx errors for idempotent methods (GET, HEAD, OPTIONS, TRACE)
  • Exponential backoff with jitter to prevent thundering herd
  • Error logging with detailed response parsing
  • Custom authentication injection without modifying generated code

This approach ensures:

  • ✅ All generated API methods automatically get resilience features
  • ✅ No code changes needed when regenerating from OpenAPI spec
  • ✅ Type safety preserved throughout
  • ✅ Optimal performance (resilience at lowest level)

Domain Helpers

Helper classes provide:

  • Clear intent with intuitive method names
  • API inconsistency handling (e.g., single vs list returns)
  • Common patterns for frequent workflows
  • Reduced boilerplate for simple operations
  • Full type safety with comprehensive hints

MCP Server Architecture

The MCP server is built with a clean, maintainable architecture:

  • Service Layer: Business logic separated from tool interfaces with dependency injection
  • Parameter Flattening: MCP-compatible tool signatures while maintaining type safety (ADR 002)
  • User Confirmation Pattern: Destructive operations require explicit confirmation via MCP elicitation (ADR 001)
  • Structured Logging: Observability throughout with detailed operation tracking
  • Template System: Consistent, formatted responses for forecast operations
  • Resource Discovery: Read-only endpoints for context gathering without mutations

See Architecture Decision Records for detailed design rationale.

MCP Server Tools

The MCP server provides 30 tools organized into foundation tools and workflow tools:

Foundation Tools (21 functions)

Direct CRUD operations across all domains:

  • Products: get, search, create, delete
  • Customers: get_customer, list_customers
  • Suppliers: get, list, create, delete
  • Inventory: set
  • Sales Orders: create, get, list, delete
  • Purchase Orders: get, list, create, delete
  • Locations: list, create

Workflow Tools (9 functions)

High-level business operations combining multiple API calls:

  • Forecast Management: update_and_monitor, get_for_products, update_settings, manage_group
  • Urgent Orders: review_requirements, generate_purchase_orders
  • Product Management: configure_lifecycle, configure_product
  • Supplier Management: create_supplier_with_products

MCP Prompts (5 workflow prompts)

Guided workflows for complex operations:

  • purchasing_workflow: Comprehensive purchase order generation workflow
  • forecast_accuracy_review: Analyze and improve forecast accuracy
  • supplier_performance_review: Comprehensive supplier analysis
  • stockout_prevention: Proactive inventory management and reordering
  • product_lifecycle_review: Product performance and lifecycle analysis

MCP Resources

Read-only discovery endpoints for context:

  • Foundation: Products, customers, suppliers, locations, inventory
  • Reports: inventory-status, urgent-orders, supplier-directory

Example conversation with Claude:

You: What products do we have starting with "WID"?
Claude: [uses search_products("WID")]
Found 3 products:
- WIDGET-001: Standard Widget ($10.00)
- WIDGET-002: Premium Widget ($15.00)
- WIDGET-SPECIAL: Custom Widget ($25.00)

You: Run the purchasing workflow to review urgent orders
Claude: [uses purchasing_workflow prompt]
Let me guide you through reviewing urgent orders and generating purchase orders...

See stocktrim_mcp_server/README.md for detailed usage.

Code Quality & Testing

This project maintains high code quality standards with comprehensive tooling:

Testing Infrastructure

  • 30+ test files covering client library and MCP server
  • Test categories: unit, integration, docs markers for selective execution
  • pytest with async support, coverage reporting, and mocking
  • Separate test suites for client (~6 files) and MCP server (~23 files)
  • Code coverage tracking with pytest-cov (terminal, HTML, and XML reports)

Linting & Type Checking

  • Ruff: Fast Python linter and formatter with comprehensive rule sets
  • ty: Astral's strict type checker ensuring full type safety
  • yamllint: YAML validation for configuration files
  • mdformat: Markdown formatting with GFM and tables support

Security Scanning

  • Trivy: Vulnerability scanner (runs weekly and on PRs)
  • Semgrep: Static analysis for security patterns (runs weekly and on PRs)
  • Dependency review: Automated checks on pull requests
  • Results uploaded to GitHub Security tab for tracking

CI/CD Pipeline

  • Matrix testing: Python 3.11, 3.12, 3.13 across all tests
  • Automated releases: release-please in manifest mode (see docs/RELEASE.md)
  • Documentation: Auto-deployed to GitHub Pages on releases
  • Pre-commit hooks: Full lint and test suite runs before commits
  • Codecov integration: Coverage tracking and reporting

Quality Commands

# Run full quality check suite
uv run poe check

# Individual checks
uv run poe format        # Format code with Ruff
uv run poe lint          # Lint with Ruff
uv run poe lint-ty       # Type check with ty
uv run poe test-coverage # Tests with coverage report

Development

Setup

# Clone repository
git clone https://github.com/dougborg/stocktrim-openapi-client.git
cd stocktrim-openapi-client

# Install UV (if needed)
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"

# Install dependencies
uv sync --all-extras

# Install pre-commit hooks
uv run pre-commit install

Common Tasks

# Run tests
uv run poe test

# Run linting
uv run poe lint

# Format code
uv run poe format

# Type check
uv run ty check

# Regenerate client from OpenAPI spec
uv run poe regenerate-client

# Build documentation
uv run poe docs-build

# Run all checks (format + lint + test)
uv run poe check

Testing

# All tests
uv run poe test

# With coverage
uv run poe test-coverage

# Unit tests only
uv run poe test-unit

# Integration tests only
uv run poe test-integration

Project Structure

stocktrim-openapi-client/
├── stocktrim_public_api_client/   # Client library
│   ├── stocktrim_client.py        # Main client with transport layer
│   ├── helpers/                   # Domain helper classes
│   │   ├── products.py
│   │   ├── customers.py
│   │   ├── suppliers.py
│   │   ├── sales_orders.py
│   │   ├── purchase_orders.py
│   │   ├── inventory.py
│   │   └── locations.py
│   ├── utils.py                   # Response unwrapping & exceptions
│   └── generated/                 # OpenAPI-generated code
│       ├── api/                   # API endpoint methods
│       ├── models/                # Data models
│       └── client.py              # Base client
├── stocktrim_mcp_server/          # MCP server package
│   └── src/stocktrim_mcp_server/
│       ├── server.py              # FastMCP server
│       └── tools/                 # MCP tool implementations
├── tests/                         # Test suite
├── scripts/                       # Development scripts
└── docs/                          # Documentation

Documentation

Contributing

Contributions are welcome! Please see:

License

MIT License - see LICENSE for details.

Acknowledgments

Support

Metadata

Release files for stocktrim-openapi-client 0.14.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stocktrim-openapi-client 0.14.0
File Size Uploaded Provenance
stocktrim_openapi_client-0.14.0.tar.gz 623.0 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for stocktrim-openapi-client 0.14.0
File Interpreter ABI Platform
stocktrim_openapi_client-0.14.0-py3-none-any.whl Python 3 none any Details

Total release size: 771.1 kB

Release files / stocktrim_openapi_client-0.14.0.tar.gz

Download URL stocktrim_openapi_client-0.14.0.tar.gz
Size 623.0 kB
Tags Source
SHA-256 checksum
How to use checksums
90cc316be3875eb8d157a55e98f76baf95d3435d31631713057aa5be0c1b7ba1
BLAKE2b-256 checksum
How to use checksums
850971465ea019979148cbde340f2461a927684ad8693fb4cff303c4a2a84e4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / stocktrim_openapi_client-0.14.0-py3-none-any.whl

Download URL stocktrim_openapi_client-0.14.0-py3-none-any.whl
Size 148.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
be526379b6aa77fb4bd051b62edbf8330e46a3204fba96e2718a68a71eec29b3
BLAKE2b-256 checksum
How to use checksums
b4714eb8a420c2235248c22410e4bd15ffbbfe2f2f81111564636e37d01e8226
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Security for stocktrim-openapi-client 0.14.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for stocktrim_openapi_client-0.14.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page