
Connects Claude to Nova Poshta's shipping API through the Model Context Protocol. Exposes tools for tracking packages, searching addresses and warehouses, managing waybills, and pulling reference data like cargo types and delivery services. Built on a plugin-based TypeScript client that separates transport from business logic, so you can swap fetch for axios or mock the whole thing in tests. Supports both stdio and HTTP transports. Reach for this when you're building e-commerce automation in Ukraine or need an AI assistant to handle logistics queries without writing custom integrations. The underlying client library is transport-agnostic and tree-shakeable, which means you can use parts of it outside the MCP context if needed.
Modern type-safe API clients for shipping carriers
Features • Packages • Quick Start • Documentation • Contributing
A production-ready monorepo containing enterprise-grade TypeScript API clients for shipping carriers. Built with modern architecture patterns, each client features plugin-based design, full type safety, and transport-agnostic implementation.
Nova Poshta API client with plugin architecture and complete type safety.
Features:
client.address.*, client.reference.*, client.tracking.*, client.waybill.*npm i @shopana/novaposhta-api-client @shopana/novaposhta-transport-fetch
Model Context Protocol (MCP) server for integrating Nova Poshta with AI assistants like Claude.
Features:
npx @shopana/novaposhta-mcp-server
Fetch-based HTTP transport for Nova Poshta API client.
Features:
npm i @shopana/novaposhta-transport-fetch
import { createClient, AddressService, ReferenceService, TrackingService } from '@shopana/novaposhta-api-client';
import { createFetchHttpTransport } from '@shopana/novaposhta-transport-fetch';
// Create client with plugins
const client = createClient({
transport: createFetchHttpTransport(),
baseUrl: 'https://api.novaposhta.ua/v2.0/json/',
apiKey: process.env.NOVA_POSHTA_API_KEY,
})
.use(new AddressService())
.use(new ReferenceService())
.use(new TrackingService());
// Use the namespaced API
const cities = await client.address.searchCities({ FindByString: 'Київ', Limit: 10 });
const cargoTypes = await client.reference.getCargoTypes();
const tracking = await client.tracking.trackDocument({ Documents: ['20450123456789'] });
console.log('Found cities:', cities.data.length);
console.log('Package status:', tracking.data[0].Status);
Add to your .mcp.json or Claude Desktop config:
{
"mcpServers": {
"novaposhta": {
"command": "npx",
"args": ["-y", "-p", "@shopana/novaposhta-mcp-server", "novaposhta-mcp"],
"env": {
"NOVA_POSHTA_API_KEY": "your_api_key_here"
}
}
}
}
Then ask Claude:
All carrier clients in this monorepo follow a consistent, battle-tested design pattern:
┌─────────────────────────────────────────┐
│ Your Application │
└──────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Plugin-based API Client │
│ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│ │ Address │ │Reference │ │Tracking │ │
│ │ Service │ │ Service │ │ Service │ │
│ └──────────┘ └──────────┘ └─────────┘ │
└──────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Transport Layer (Injectable) │
│ fetch / axios / custom │
└─────────────────────────────────────────┘
# Clone the repository
git clone https://github.com/shopanaio/carrier-api.git
cd carrier-api
# Install dependencies
yarn install
# Build all packages
yarn build
# Development
yarn dev # Watch mode for API client
yarn dev:mcp:stdio # Run MCP server in stdio mode
yarn dev:mcp:http # Run MCP server in HTTP mode
# Building
yarn build # Build API client
yarn build:mcp # Build MCP server
# Testing
yarn test # Run all tests
yarn test:watch # Run tests in watch mode
yarn test:coverage # Generate coverage report
yarn test:mcp # Run MCP server tests
# Code Quality
yarn lint # Lint TypeScript files
yarn lint:fix # Fix linting issues
yarn format # Format code with Prettier
yarn format:check # Check code formatting
yarn type-check # Run TypeScript type checking
carrier-api/
├── packages/
│ ├── novaposhta-api-client/ # Core API client
│ │ ├── src/
│ │ │ ├── core/ # Client core logic
│ │ │ ├── services/ # Service plugins
│ │ │ ├── types/ # TypeScript types
│ │ │ └── index.ts
│ │ └── package.json
│ │
│ ├── novaposhta-mcp-server/ # MCP server for AI
│ │ ├── src/
│ │ │ ├── cli/ # CLI entry points
│ │ │ ├── tools/ # MCP tools
│ │ │ ├── server.ts # Server implementation
│ │ │ └── config.ts
│ │ └── package.json
│ │
│ └── novaposhta-transport-fetch/ # Fetch transport
│ ├── src/
│ └── package.json
│
├── e2e/ # End-to-end tests
├── postman/ # Postman collections
├── .mcp.json # MCP server config
└── package.json # Root package.json
We welcome contributions from the community! Whether it's bug fixes, new features, documentation improvements, or examples - all contributions are appreciated.
git checkout -b feature/amazing-featureyarn test - make sure everything passesgit commit -m 'feat: add amazing feature'git push origin feature/amazing-featurePackage releases are automated with GitHub Actions and Changesets. Changes to package source files, package scripts, or package manifests must include a user-facing Changeset generated with:
yarn changeset
Select every affected public package and use patch for backwards-compatible
fixes or minor for backwards-compatible features. Major Changesets and
placeholder release notes are rejected automatically. Documentation-only,
test-only, and repository maintenance changes do not need a Changeset.
The Changeset Required workflow checks pull requests before release automation
can run.
Releases use the main branch:
.changeset/*.md file into main.Release workflow opens a chore: version packages pull request.latest tag and creates GitHub releases.Manual release packaging checks are:
yarn build
yarn pack:dry-run
npm publishing uses Trusted Publishing/OIDC. Configure every public npm package
to trust the shopanaio/carrier-api repository and
.github/workflows/release.yml. Packages that do not exist on npm yet require a
repository NPM_TOKEN secret for their first publication; it can be removed
after Trusted Publishing is configured. A CHANGESETS_TOKEN secret is optional
and is only needed when the default GITHUB_TOKEN cannot manage release pull
requests.
Found a bug or have a feature request? Please open an issue with:
Eastern Europe:
International:
Want to help implement these? Contributions welcome!
| Package | Version | Build | Coverage | Downloads |
|---|---|---|---|---|
| @shopana/novaposhta-api-client | ||||
| @shopana/novaposhta-mcp-server | ||||
| @shopana/novaposhta-transport-fetch |
Apache License 2.0 - see LICENSE for details.
This project is licensed under the Apache License 2.0, which means:
NOVA_POSHTA_API_KEY*secretYour Nova Poshta API key
NOVA_POSHTA_SYSTEMSystem identifier (e.g., 'DevCentre' for development/testing)
LOG_LEVELLogging level (debug, info, warn, error)