d1-mcp-mint
DelhiveryOne MCP Mint — Connect your AI IDE (Kiro, Cursor, Claude Desktop) to DelhiveryOne APIs in 2 steps. No manual token management.
How It Works
This package runs as a local MCP server (stdio) that:
- Takes your Auth
client_idandclient_secret - Auto-mints and caches access tokens (refreshes before expiry)
- Proxies all MCP tool calls to the live D1 MCP Gateway with a fresh Bearer token
You never touch tokens manually. They're minted, cached, and refreshed automatically.
Get your ClientID and Secret from:
curl --location --request POST 'https://<your-auth-domain>/p/api/account/client' \
--header 'Authorization: Bearer <your-auth-token>'
flowchart TD
A[AI IDE - Kiro Cursor Claude] -->|stdio| B[d1-mcp-mint local proxy]
B -->|client_credentials grant| C[Auth]
C -->|access_token| B
B -->|Bearer token + headers| D[D1 MCP Gateway]
D -->|tool results| B
B -->|tool results| A
Repository Structure
d1-mcp-mint/
├── src/
│ └── d1_mcp_mint/
│ ├── __init__.py # Package version
│ ├── server.py # MCP stdio server + D1 gateway proxy
│ └── token_manager.py # Auth token caching & auto-refresh
├── tests/ # Test suite
├── pyproject.toml # Package metadata & dependencies
├── README.md # This file
└── uv.lock # Locked dependencies
Prerequisites
| Requirement | How to get it |
|---|---|
| Python 3.11+ | Bundled with uv |
| uv (Python package runner) | See install instructions below |
| Auth credentials | Provided by Delhivery (client_id + client_secret) |
Install uv (one-time)
# macOS (Homebrew)
brew install uv
# or via pip
pip install uv
# or via curl
curl -LsSf https://astral.sh/uv/install.sh | sh
Verify it works:
uvx --version
Setup (2 Steps)
Step 1: Add MCP Config to Your IDE
Kiro (.kiro/settings/mcp.json):
{
"mcpServers": {
"delhivery-one": {
"command": "uvx",
"args": ["d1-mcp-mint@latest"],
"env": {
"D1_CLIENT_ID": "<your-auth-client-id>",
"D1_CLIENT_SECRET": "<your-auth-client-secret>",
"D1_AUTH_URL": "https://<your-auth-domain>",
"D1_REALM": "<your-realm>",
"D1_CLIENT_CMS": "<your-client-cms-id>",
"D1_MCP_URL": "https://<your-mcp-gateway>/delhivery-one/c/<your-client-path>/mcp"
}
}
}
}
Cursor (.cursor/mcp.json):
{
"mcpServers": {
"delhivery-one": {
"command": "uvx",
"args": ["d1-mcp-mint@latest"],
"env": {
"D1_CLIENT_ID": "<your-auth-client-id>",
"D1_CLIENT_SECRET": "<your-auth-client-secret>",
"D1_AUTH_URL": "https://<your-auth-domain>",
"D1_REALM": "<your-realm>",
"D1_CLIENT_CMS": "<your-client-cms-id>",
"D1_MCP_URL": "https://<your-mcp-gateway>/delhivery-one/c/<your-client-path>/mcp"
}
}
}
}
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"delhivery-one": {
"command": "uvx",
"args": ["d1-mcp-mint@latest"],
"env": {
"D1_CLIENT_ID": "<your-auth-client-id>",
"D1_CLIENT_SECRET": "<your-auth-client-secret>",
"D1_AUTH_URL": "https://<your-auth-domain>",
"D1_REALM": "<your-realm>",
"D1_CLIENT_CMS": "<your-client-cms-id>",
"D1_MCP_URL": "https://<your-mcp-gateway>/delhivery-one/c/<your-client-path>/mcp"
}
}
}
}
Using System Environment Variables (recommended for security)
Instead of hardcoding secrets in JSON, export them in your shell profile (~/.zshrc, ~/.bashrc):
export D1_CLIENT_ID="your-client-id"
export D1_CLIENT_SECRET="your-client-secret"
export D1_AUTH_URL="https://<your-auth-domain>"
export D1_REALM="your-realm"
export D1_CLIENT_CMS="cms::client::your-uuid"
export D1_MCP_URL="https://<your-mcp-gateway>/delhivery-one/c/<your-client-path>/mcp"
Then your MCP config passes them through (no secrets in the file):
{
"mcpServers": {
"delhivery-one": {
"command": "uvx",
"args": ["d1-mcp-mint@latest"],
"env": {
"D1_CLIENT_ID": "${D1_CLIENT_ID}",
"D1_CLIENT_SECRET": "${D1_CLIENT_SECRET}",
"D1_AUTH_URL": "${D1_AUTH_URL}",
"D1_REALM": "${D1_REALM}",
"D1_CLIENT_CMS": "${D1_CLIENT_CMS}",
"D1_MCP_URL": "${D1_MCP_URL}"
}
}
}
}
This way you can safely commit mcp.json to version control — it contains no secrets.
Step 2: Fill In Your Credentials
| Variable | What it is | Example |
|---|---|---|
D1_CLIENT_ID |
Auth confidential client ID | d1-mcp-client-acme |
D1_CLIENT_SECRET |
Auth client secret | aB3x...k9Yz |
D1_AUTH_URL |
Auth server base URL | https://<your-auth-domain> |
D1_REALM |
Auth realm name | <your-realm-id> |
D1_CLIENT_CMS |
Client CMS identifier | cms::client::<your-uuid> |
D1_MCP_URL |
D1 MCP Gateway endpoint | https://<your-mcp-gateway>/delhivery-one/c/<path>/mcp |
Where do I get these? Your Delhivery account manager or engineering contact will provide all six values.
Restart and Verify
Kiro
- Open Command Palette (
Cmd+Shift+P) - Search for "MCP: Restart Server" or "MCP: List Servers"
- You should see
delhivery-onelisted with status running
Cursor
- Open Settings → MCP
- You should see
delhivery-onelisted - Click the refresh icon if it's not connected
- Status should show a green dot (connected)
What You Can Do
Once connected, ask your AI assistant things like:
- "Show me my recent shipments"
- "What's the status of waybill WB12345?"
- "Get my wallet balance"
- "List my support tickets"
- "What does my dashboard look like?"
The available tools depend on what's configured on the D1 MCP Gateway for your account.
How Token Management Works
┌─────────────────────────────────────────────────────────────┐
│ Token Lifecycle │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. First tool call → mint token via client_credentials │
│ 2. Cache token in memory │
│ 3. Subsequent calls → use cached token │
│ 4. 30 seconds before expiry → auto-refresh │
│ 5. Token failure → re-mint immediately │
│ │
│ You never see or manage tokens. It just works. │
│ │
└─────────────────────────────────────────────────────────────┘
The TokenManager class:
- On the first
get_token()call, mints a token viaclient_credentialsgrant - Caches the token + expiry time in memory
- Returns the cached token on subsequent calls if still valid
- Re-mints only when the token is within 30 seconds of expiry
Auth is only hit once per token lifetime (typically every ~5 minutes), not on every API call.
Environment Variables Reference
| Variable | Required | Description |
|---|---|---|
D1_CLIENT_ID |
Yes | Auth confidential client ID |
D1_CLIENT_SECRET |
Yes | Auth client secret |
D1_AUTH_URL |
Yes | Auth base URL |
D1_REALM |
Yes | Auth realm name |
D1_CLIENT_CMS |
Yes | Client CMS identifier for D1 |
D1_MCP_URL |
Yes | D1 MCP Gateway endpoint URL |
D1_USER_EMAIL |
No | User email (defaults to --) |
For Developers: Local Development
Clone and install
git clone <repo-url>
cd d1-mcp-mint
uv sync
Run the server locally
# Set env vars
export D1_CLIENT_ID="your-client-id"
export D1_CLIENT_SECRET="your-client-secret"
export D1_AUTH_URL="https://<your-auth-domain>"
export D1_REALM="<your-realm-id>"
export D1_CLIENT_CMS="cms::client::<your-uuid>"
export D1_MCP_URL="https://<your-mcp-gateway>/delhivery-one/c/<your-client-path>/mcp"
# Run the server (stdio mode — accepts JSON-RPC on stdin)
uv run d1-mcp-mint
Point your IDE at local source (instead of PyPI)
{
"mcpServers": {
"delhivery-one": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/d1-mcp-mint", "d1-mcp-mint"],
"env": {
"D1_CLIENT_ID": "...",
"D1_CLIENT_SECRET": "...",
"D1_AUTH_URL": "https://<your-auth-domain>",
"D1_REALM": "...",
"D1_CLIENT_CMS": "...",
"D1_MCP_URL": "https://<your-mcp-gateway>/delhivery-one/c/<your-client-path>/mcp"
}
}
}
}
Key source files
| File | Purpose |
|---|---|
src/d1_mcp_mint/server.py |
Entry point. Registers MCP handlers, builds proxy, routes tool calls to the D1 gateway. |
src/d1_mcp_mint/token_manager.py |
Handles Auth client_credentials grant. Caches tokens in memory and auto-refreshes 30s before expiry. |
src/d1_mcp_mint/__init__.py |
Package version (__version__). |
pyproject.toml |
Build config (hatchling), dependencies, CLI entry point (d1-mcp-mint → server:main). |
Run tests
uv sync --dev
uv run pytest tests/ -v
Publishing to PyPI
Publishing is automated via GitHub Actions. Push a tag to trigger the workflow:
# Bump version in pyproject.toml and src/d1_mcp_mint/__init__.py
# Then tag and push:
git tag d1-mcp-mint-v0.2.0
git push origin d1-mcp-mint-v0.2.0
The CI pipeline will:
- Run tests across Python 3.11, 3.12, and 3.13
- Build the package
- Publish to PyPI using trusted publishing (OIDC — no API tokens needed)
Manual publish (fallback)
cd d1-mcp-mint
uv build
uv publish --token <your-pypi-api-token>
Publish to TestPyPI first (recommended for new versions)
uv publish --publish-url https://test.pypi.org/legacy/ --token <your-test-pypi-token>
# Verify it works
uvx --index-url https://test.pypi.org/simple/ d1-mcp-mint@1.0.7
Bumping the version
Update the version in two places:
pyproject.toml→version = "X.Y.Z"src/d1_mcp_mint/__init__.py→__version__ = "X.Y.Z"
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
D1_CLIENT_ID is required |
Missing env var | Add to your MCP config env block |
401 Unauthorized from Auth |
Wrong client_id/secret | Verify credentials in Auth admin |
403 Forbidden from D1 Gateway |
Client not authorized | Contact Delhivery to enable access |
Connection refused |
MCP gateway down or wrong URL | Verify D1_MCP_URL is correct |
uvx: command not found |
uv not installed | Install via brew install uv or pip install uv |
| Server shows "disconnected" | Bad credentials | Test token manually (see below) |
| "No tools available" | Tools not configured for client | Contact Delhivery engineering |
Quick credential test
curl -X POST "https://<your-auth-domain>/realms/<your-realm>/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=<your-client-id>&client_secret=<your-client-secret>"
If this returns JSON with access_token, your credentials are correct.
Security Notes
- Client secrets are stored in your local MCP config — never commit secrets to version control
- Tokens are cached in-memory only (not persisted to disk)
- Token lifetime is controlled by your Auth client configuration
- Add to your
.gitignore:.kiro/settings/mcp.json .cursor/mcp.json - If credentials are compromised, disable the Auth client immediately
For Delhivery Admins: Client Setup
To onboard a new customer/developer:
- Create a confidential client in the appropriate Auth realm
- Enable Service Accounts (client_credentials grant)
- Assign required roles/scopes for D1 API access
- Provide the customer with:
client_idclient_secretrealmnameauth_urlclient_cmsmcp_url
FAQ
Q: Do I need Python installed?
A: You need uv (which bundles its own Python). If you have brew install uv, you're good.
Q: Does this work offline? A: No. It needs network access to reach Auth (for tokens) and the D1 MCP Gateway (for API calls).
Q: Can I use this in CI/CD? A: It's designed for local IDE use. For CI/CD, mint tokens directly via the Auth token endpoint.
Q: What APIs can I access? A: Whatever tools are configured on the D1 MCP Gateway for your client. Typically: shipments, orders, wallets, tickets, dashboards, and more.
Q: Can multiple people use the same client_id? A: Yes, but for audit/security reasons, each developer should ideally have their own credentials.
Q: How do I update to the latest version?
A: uvx always pulls @latest by default. Just restart the MCP server. No manual update needed.
License
MIT
Metadata
Release files for d1-mcp-mint 1.0.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| d1_mcp_mint-1.0.7.tar.gz | 62.8 kB | Without provenance | Details for d1_mcp_mint-1.0.7.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| d1_mcp_mint-1.0.7-py3-none-any.whl | Python 3 | none | any | Details for d1_mcp_mint-1.0.7-py3-none-any.whl |
Total release size: 74.4 kB
Release files / d1_mcp_mint-1.0.7.tar.gz
| Download URL | d1_mcp_mint-1.0.7.tar.gz |
|---|---|
| Size | 62.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
45ba791177bae1199bcb1b186d25f99ee32da818d0e3ae9a589fd3e106c57033
|
|
BLAKE2b-256 checksum How to use checksums |
722160c1b5edd4fa3c8523b2c1129d10af10b6d28352f0f0863229bab134a3da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / d1_mcp_mint-1.0.7-py3-none-any.whl
| Download URL | d1_mcp_mint-1.0.7-py3-none-any.whl |
|---|---|
| Size | 11.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
93c12809e1a23d51f1cf1c3611965162345ccf7aedcf7afb39691e567afac36e
|
|
BLAKE2b-256 checksum How to use checksums |
a0f8cea06f8939c329f0e14e1523d3a9dd83fe916c1b2e8beec58e9783c7ec0e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for d1-mcp-mint 1.0.7
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.