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@0.1.0
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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file d1_mcp_mint-0.1.0.tar.gz.
File metadata
- Download URL: d1_mcp_mint-0.1.0.tar.gz
- Upload date:
- Size: 59.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b6cec71845b26262971e0e73ccb9b66ffbc084bd4809dfbc7e452e47d120ad6
|
|
| MD5 |
af75d15b63f311119e8af51872fc2530
|
|
| BLAKE2b-256 |
c9569aa34a8621a228091f36154dd6e1f33cfff5324b9992221a80f04c7abe9a
|
File details
Details for the file d1_mcp_mint-0.1.0-py3-none-any.whl.
File metadata
- Download URL: d1_mcp_mint-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be0f3c61727865677072f7b0615b2289624ba7448884ce9c6e4f9bbdca6d710f
|
|
| MD5 |
c5573be815b59b3c74ac5f922ce5f740
|
|
| BLAKE2b-256 |
1dd08fc6e8e5015b25c3ca97f6e4b1ae12d679413584b8d77a1006e7f192cd05
|