Skip to main content

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:

  1. Takes your Auth client_id and client_secret
  2. Auto-mints and caches access tokens (refreshes before expiry)
  3. 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

  1. Open Command Palette (Cmd+Shift+P)
  2. Search for "MCP: Restart Server" or "MCP: List Servers"
  3. You should see delhivery-one listed with status running

Cursor

  1. Open Settings → MCP
  2. You should see delhivery-one listed
  3. Click the refresh icon if it's not connected
  4. 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:

  1. On the first get_token() call, mints a token via client_credentials grant
  2. Caches the token + expiry time in memory
  3. Returns the cached token on subsequent calls if still valid
  4. 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-mintserver: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:

  1. Run tests across Python 3.11, 3.12, and 3.13
  2. Build the package
  3. 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.5

Bumping the version

Update the version in two places:

  1. pyproject.tomlversion = "X.Y.Z"
  2. 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:

  1. Create a confidential client in the appropriate Auth realm
  2. Enable Service Accounts (client_credentials grant)
  3. Assign required roles/scopes for D1 API access
  4. Provide the customer with:
    • client_id
    • client_secret
    • realm name
    • auth_url
    • client_cms
    • mcp_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

d1_mcp_mint-1.0.5.tar.gz (31.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

d1_mcp_mint-1.0.5-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

Details for the file d1_mcp_mint-1.0.5.tar.gz.

File metadata

  • Download URL: d1_mcp_mint-1.0.5.tar.gz
  • Upload date:
  • Size: 31.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.7.12

File hashes

Hashes for d1_mcp_mint-1.0.5.tar.gz
Algorithm Hash digest
SHA256 fee5062a326ac097b6712d46b020357991a91dfc06890ea93a129223a1362b37
MD5 063d56b1356a4cb12c86a64ad1c7fe9a
BLAKE2b-256 17dc9315c22c3489744f5d1c30d725251727d036480a7fe8cc4806df1fd9a42a

See more details on using hashes here.

File details

Details for the file d1_mcp_mint-1.0.5-py3-none-any.whl.

File metadata

File hashes

Hashes for d1_mcp_mint-1.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 22a1e15b9bc6b93e171f6484cc89f8fa41a37e7cddd418c81a235b95c1894843
MD5 fa9c3cb0bca5276b6022ea24245e4094
BLAKE2b-256 67518acb3172bf6b337de1db5ea52ea9dc8299ad83c3657f4a41b94053d206fe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page