Getting Started

Getting Started

Make your first MCP request in under 5 minutes. This guide walks you through generating a HERE token and calling a location tool.

Prerequisites

  • HERE Access Key ID and HERE Access Key Secret (provided during onboarding)
  • Python 3.12+ with httpx installed (pip install httpx)

Step 1: Generate a HERE Token

Create a HERE OAuth2 bearer token using your Access Key credentials:

import base64
import hashlib
import hmac
import time
import urllib.parse
import uuid

import httpx

TOKEN_URL = "https://account.api.here.com/oauth2/token"
KEY_ID = "<YOUR_ACCESS_KEY_ID>"
KEY_SECRET = "<YOUR_ACCESS_KEY_SECRET>"


def get_here_token() -> str:
    """Generate a HERE OAuth2 token using HMAC-SHA256 signed client credentials."""
    ts = str(int(time.time()))
    nonce = uuid.uuid4().hex

    params = sorted([
        ("grant_type", "client_credentials"),
        ("oauth_consumer_key", KEY_ID),
        ("oauth_nonce", nonce),
        ("oauth_signature_method", "HMAC-SHA256"),
        ("oauth_timestamp", ts),
        ("oauth_version", "1.0"),
    ])

    encoded = urllib.parse.urlencode(params, quote_via=urllib.parse.quote)
    base = "&".join([
        "POST",
        urllib.parse.quote(TOKEN_URL, safe=""),
        urllib.parse.quote(encoded, safe=""),
    ])
    key = urllib.parse.quote(KEY_SECRET, safe="") + "&"
    sig = base64.b64encode(
        hmac.new(key.encode(), base.encode(), hashlib.sha256).digest()
    ).decode()

    auth = (
        f'OAuth realm="",'
        f'oauth_consumer_key="{KEY_ID}",'
        f'oauth_nonce="{nonce}",'
        f'oauth_signature="{urllib.parse.quote(sig, safe="")}",'
        f'oauth_signature_method="HMAC-SHA256",'
        f'oauth_timestamp="{ts}",'
        f'oauth_version="1.0"'
    )

    resp = httpx.post(
        TOKEN_URL,
        content=b"grant_type=client_credentials",
        headers={
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": auth,
        },
        timeout=30,
    )
    resp.raise_for_status()
    return resp.json()["access_token"]


token = get_here_token()
print(f"Token obtained: {token[:20]}...")

This signs a request with your Access Key Secret and exchanges it for a short-lived JWT.

Step 2: Initialize the MCP Session

Establish a session. The response includes a Mcp-Session-Id header you'll need for subsequent requests.

HLR_URL = "https://hlr.ai.here.com/mcp"

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {token}",
}

# Initialize
resp = httpx.post(HLR_URL, json={
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
        "protocolVersion": "2025-03-26",
        "capabilities": {},
        "clientInfo": {"name": "quickstart", "version": "1.0"},
    },
}, headers=headers, timeout=30)
resp.raise_for_status()

session_id = resp.headers.get("mcp-session-id")
headers["Mcp-Session-Id"] = session_id
print(f"Session established: {session_id}")

This establishes your MCP session. The server returns capabilities and a session ID for routing.

Step 3: Send Initialized Notification

Confirm to the server that your client is ready:

httpx.post(HLR_URL, json={
    "jsonrpc": "2.0",
    "method": "notifications/initialized",
    "params": {},
}, headers=headers, timeout=30)

This is a notification (no id field) that signals the handshake is complete.

Step 4: Discover Available Tools

List the available tools:

resp = httpx.post(HLR_URL, json={
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list",
    "params": {},
}, headers=headers, timeout=30)
resp.raise_for_status()

tools = resp.json()["result"]["tools"]
print(f"Available tools: {[t['name'] for t in tools]}")

This returns the full list of tools with their input/output schemas.

Step 5: Call a Tool

Execute a geocoding request — this is where authentication is validated:

resp = httpx.post(HLR_URL, json={
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
        "name": "geocode",
        "arguments": {"q": "Alexanderplatz, Berlin"},
    },
}, headers=headers, timeout=30)
resp.raise_for_status()

result = resp.json()["result"]
print(result)

This calls the geocode tool and returns structured coordinates and address data.

What's Next

  • Connection & Authentication Guide — Comprehensive reference for auth flows, multiple token methods (Python + CLI), session management, and error handling.
  • Examples — Ready-to-run integrations using LangChain, Strands Agents, PydanticAI, and more.
  • Tools Reference — Complete list of available location tools.