---
updatedAt: 2026-10-08T11:15:52.000Z
agentTools:
  siteIndex: https://docs.here.com/llms.txt
  projectIndex: https://docs.here.com/location-reasoning/llms.txt
---

# HERE Location Reasoning integration examples

These examples show how you can connect an application or agent to HERE Location Reasoning, discover available tools, and make location-tool requests.

## Before you begin

1. Follow Steps 1-2 of [Get started with HERE Location Reasoning](https://docs.here.com/location-reasoning/docs/hlrgetting-started) to create your signing key and generate a HERE bearer token. For the full authentication and session reference, see [Connect and authenticate](https://docs.here.com/location-reasoning/docs/hlrconnection-guide).
2. Choose a Python or TypeScript example.
3. Set the environment variables required by that example.

## Set environment variables

Set the following environment variables to connect to HERE Location Reasoning. Agent examples also require AWS Bedrock credentials and a model ID.

| Variable                | Required             | Description                            |
| ----------------------- | -------------------- | -------------------------------------- |
| `HLR_SERVER_URL`        | Yes                  | `https://hlr.here.ai/mcp`              |
| `AWS_ACCESS_KEY_ID`     | Yes (agent examples) | AWS credentials for Bedrock LLM access |
| `AWS_SECRET_ACCESS_KEY` | Yes (agent examples) | AWS credentials for Bedrock LLM access |
| `AWS_DEFAULT_REGION`    | Yes (agent examples) | AWS region, e.g. `us-east-1`           |
| `BEDROCK_MODEL_ID`      | Yes (agent examples) | Bedrock model ID                       |

<Callout icon="📘" theme="info">
  Authentication requires a HERE bearer token. See Steps 1-2 of [Get started with HERE Location Reasoning](https://docs.here.com/location-reasoning/docs/hlrgetting-started) to create one.

  The agent examples use AWS Bedrock. HERE Location Reasoning supports any large language model provider that supports tool calling.
</Callout>

Agent examples retrieve a server-provided usage policy and guardrail prompt, then add both to the agent system prompt. Keep this pattern when you adapt an example so that the agent receives the server guidance.

## Python

### Python MCP SDK (Direct)

Demonstrates how to discover available tools and resources, run a geocoding request, and access server-provided guidance without using an LLM.

<Accordion title="mcp-sdk.py" icon="fa-code">

```python
"""Direct MCP server connection using the official Python SDK — no LLM, no framework."""

import asyncio
import os

from dotenv import load_dotenv
import httpx
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client

load_dotenv()

def require_environment_variable(name: str) -> str:
    value = os.getenv(name)
    if not value:
        raise RuntimeError(f"Set {name} before running this example.")
    return value


SERVER_URL = require_environment_variable("HLR_SERVER_URL")

# Create a HERE bearer token. Refer to the get_here_token() function in Step 2
# of the "Get started with HERE Location Reasoning" guide.
JWT_TOKEN = "<YOUR_HERE_BEARER_TOKEN>"


async def main():
    # Auth header with bearer token, required for tool calls
    client = httpx.AsyncClient(headers={"Authorization": f"Bearer {JWT_TOKEN}"})

    async with streamable_http_client(url=SERVER_URL, http_client=client) as (
        read_stream,
        write_stream,
        _,
    ):
        async with ClientSession(read_stream, write_stream) as session:
            await session.initialize()

            # Discover available tools
            tools = await session.list_tools()
            print(f"Available tools: {[tool.name for tool in tools.tools]}", "\n")

            # Call a tool directly
            geocode_result = await session.call_tool(
                "hlr___geocode", {"q": "Alexanderplatz, Berlin"}
            )
            print(geocode_result.structuredContent, "\n")

            # List resources
            resources = await session.list_resources()
            print(
                f"Available resources: {[(resource.name, resource.uri) for resource in resources.resources]}",
                "\n",
            )

            # Read guardrails resource
            policy = await session.read_resource(
                uri="guardrails://location-reasoning-usage-policy"
            )
            print(policy)

    await client.aclose()


if __name__ == "__main__":
    asyncio.run(main())

```

</Accordion>

Use the MCP SDK directly when you need programmatic access to location tools without an agent framework, or when you want to explore available tools and resources.

A successful run prints available tool names, the geocoding result for Alexanderplatz, available resources, and the usage-policy resource.

### Python LangChain

Demonstrates how a LangChain agent uses HERE Location Reasoning tools to interpret a routing request, retrieve location data, calculate a route, and generate a natural-language response.

<Accordion title="langchain-example.py" icon="fa-code">

```python
"""LangChain agent with MCP tools — full agentic loop with tool execution."""

import asyncio
import os
from textwrap import dedent

from dotenv import load_dotenv
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_mcp_adapters.prompts import load_mcp_prompt
from langchain_mcp_adapters.resources import load_mcp_resources
from langchain_mcp_adapters.tools import load_mcp_tools

load_dotenv()

def require_environment_variable(name: str) -> str:
    value = os.getenv(name)
    if not value:
        raise RuntimeError(f"Set {name} before running this example.")
    return value


SERVER_URL = require_environment_variable("HLR_SERVER_URL")
MODEL_ID = require_environment_variable("BEDROCK_MODEL_ID")

# Create a HERE bearer token. Refer to the get_here_token() function in Step 2
# of the "Get started with HERE Location Reasoning" guide.
JWT_TOKEN = "<YOUR_HERE_BEARER_TOKEN>"


async def main():
    client = MultiServerMCPClient(
        {
            "hlr": {
                "transport": "http",
                "url": SERVER_URL,
                # Auth header with bearer token, required for tool calls
                "headers": {"Authorization": f"Bearer {JWT_TOKEN}"},
            }
        }
    )

    async with client.session("hlr") as session:
        tools = await load_mcp_tools(session)
        blobs = await load_mcp_resources(
            session, uris=["guardrails://location-reasoning-usage-policy"]
        )
        guardrail_instruction = await load_mcp_prompt(
            session=session, name="hlr___secure_location_reasoning"
        )

        # Build system prompt with guardrails resource and prompt
        sys_prompt_template = dedent(
            """
            <about>
            You are a precise and accurate assistant.
            </about>

            <instructions>
            {instructions}
            </instructions>

            <usage_policy>
            {policy}
            </usage_policy>
        """
        ).strip()

        sys_prompt = sys_prompt_template.format(
            instructions=guardrail_instruction[0].content, policy=blobs[0].data
        )

        model = init_chat_model(
            model=MODEL_ID,
            model_provider="bedrock_converse",
        )

        agent = create_agent(model=model, tools=tools, system_prompt=sys_prompt)

        # Invoke agent with your prompt
        response = await agent.ainvoke(
            {
                "messages": [
                    {
                        "role": "user",
                        "content": "Plan a route from Paris to Berlin.",
                    }
                ]
            }
        )

        print(response["messages"][-1].content)


if __name__ == "__main__":
    asyncio.run(main())

```

</Accordion>

Use this example when you build with LangChain and want to add HERE Location Reasoning capabilities to an existing agent through AWS Bedrock.

A successful run prints the agent's response to the route request from Paris to Berlin.

### Python Strands Agents

Runs the same routing scenario as the LangChain example. The agent determines which tools to call, executes them through MCP, and synthesizes a response.

<Accordion title="strands-example.py" icon="fa-code">

```python
"""Strands Agents (AWS-native) with MCP tools — full agentic loop with tool execution."""

import asyncio
import os
from textwrap import dedent

from dotenv import load_dotenv
from mcp.client.streamable_http import streamablehttp_client
from strands import Agent
from strands.models.bedrock import BedrockModel
from strands.tools.mcp import MCPClient

load_dotenv()

def require_environment_variable(name: str) -> str:
    value = os.getenv(name)
    if not value:
        raise RuntimeError(f"Set {name} before running this example.")
    return value


SERVER_URL = require_environment_variable("HLR_SERVER_URL")
MODEL_ID = require_environment_variable("BEDROCK_MODEL_ID")

# Create a HERE bearer token. Refer to the get_here_token() function in Step 2
# of the "Get started with HERE Location Reasoning" guide.
JWT_TOKEN = "<YOUR_HERE_BEARER_TOKEN>"

hlr_client = MCPClient(
    lambda: streamablehttp_client(
        url=SERVER_URL,
        # Auth header with bearer token, required for tool calls
        headers={"Authorization": f"Bearer {JWT_TOKEN}"},
    )
)


async def main():
    with hlr_client:
        tools = hlr_client.list_tools_sync()
        blob = hlr_client.read_resource_sync(
            uri="guardrails://location-reasoning-usage-policy"
        )
        guardrail_instruction = hlr_client.get_prompt_sync(
            prompt_id="hlr___secure_location_reasoning", args={}
        )

        # Build system prompt with guardrails resource and prompt
        sys_prompt_template = dedent(
            """
            <about>
            You are a precise and accurate assistant.
            </about>

            <instructions>
            {instructions}
            </instructions>

            <usage_policy>
            {policy}
            </usage_policy>
        """
        ).strip()

        sys_prompt = sys_prompt_template.format(
            instructions=guardrail_instruction.messages[0].content.text,
            policy=blob.contents[0].text,
        )

        # streaming=False because ConverseStream requires additional IAM permissions that may not be provisioned
        model = BedrockModel(model_id=MODEL_ID, streaming=False)

        agent = Agent(
            model=model, tools=tools, system_prompt=sys_prompt, callback_handler=None
        )

        response = agent(prompt="Plan a route from Paris to Berlin.")
        print(response)

        agent.cleanup()


if __name__ == "__main__":
    asyncio.run(main())

```

</Accordion>

Use this example when you build AWS-native applications with the Strands Agents framework and AWS Bedrock.

A successful run prints the agent's response to the route request from Paris to Berlin.

### Python PydanticAI

Demonstrates type-safe tool calling with PydanticAI by using HERE Location Reasoning tools to process a routing request and return a response.

<Accordion title="pydantic_ai-example.py" icon="fa-code">

```python
"""PydanticAI agent with MCP tools — full agentic loop with tool execution."""

import asyncio
import os
from textwrap import dedent

from dotenv import load_dotenv
from fastmcp import Client
from fastmcp.client.auth import BearerAuth
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPToolset


load_dotenv()

def require_environment_variable(name: str) -> str:
    value = os.getenv(name)
    if not value:
        raise RuntimeError(f"Set {name} before running this example.")
    return value


SERVER_URL = require_environment_variable("HLR_SERVER_URL")
MODEL_ID = require_environment_variable("BEDROCK_MODEL_ID")

# Create a HERE bearer token. Refer to the get_here_token() function in Step 2
# of the "Get started with HERE Location Reasoning" guide.
JWT_TOKEN = "<YOUR_HERE_BEARER_TOKEN>"


async def main():

    hlr_client = Client(
        SERVER_URL,
        # Auth with bearer token, required for tool calls
        auth=BearerAuth(JWT_TOKEN),
    )

    hlr_toolset = MCPToolset(hlr_client)

    async with hlr_client:
        guardrail_blob = await hlr_client.read_resource(
            uri="guardrails://location-reasoning-usage-policy"
        )

        guardrail_instruction = await hlr_client.get_prompt(
            name="hlr___secure_location_reasoning"
        )

        # Build system prompt with guardrails resource and prompt
        sys_prompt_template = dedent(
            """
            <about>
            You are a precise and accurate assistant.
            </about>

            <instructions>
            {instructions}
            </instructions>

            <usage_policy>
            {policy}
            </usage_policy>
        """
        ).strip()

        sys_prompt = sys_prompt_template.format(
            instructions=guardrail_instruction.messages[0].content.text,
            policy=guardrail_blob[0].text,
        )

        agent = Agent(
            f"bedrock:{MODEL_ID}",
            toolsets=[hlr_toolset],
            system_prompt=sys_prompt,
        )

        result = await agent.run("Plan a route from Paris to Berlin.")
        print(result.output)


if __name__ == "__main__":
    asyncio.run(main())

```

</Accordion>

Use this example for type-safe agent interactions with HERE Location Reasoning through AWS Bedrock.

A successful run prints the agent's response to the route request from Paris to Berlin.

## TypeScript

### TypeScript MCP SDK (Direct)

Demonstrates how to discover and invoke HERE Location Reasoning tools from a Node.js application and work with the returned structured data.

<Accordion title="mcp-sdk.ts" icon="fa-code">

```typescript
/**
 * Direct MCP SDK client example — no LLM, no agent framework.
 *
 * Shows:
 * - Low-level MCP client setup with streamable HTTP transport
 * - Auth header configuration
 * - Listing available tools
 * - Calling a tool directly (geocode)
 */
import 'dotenv/config'
import { Client } from '@modelcontextprotocol/sdk/client'
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp'

function requireEnvironmentVariable(name: string): string {
  const value = process.env[name]
  if (!value) {
    throw new Error(`Set ${name} before running this example.`)
  }
  return value
}

const SERVER_URL = requireEnvironmentVariable('HLR_SERVER_URL')

// Create a HERE bearer token. Refer to the get_here_token() function in Step 2
// of the "Get started with HERE Location Reasoning" guide.
const JWT_TOKEN = '<YOUR_HERE_BEARER_TOKEN>'

async function main(): Promise<void> {
  let transport: StreamableHTTPClientTransport | null = null

  try {
    const client = new Client(
      { name: 'hlr-client', version: '1.0.0' },
      { capabilities: {} }
    )

    // Client with JWT bearer token auth header
    transport = new StreamableHTTPClientTransport(
      new URL(SERVER_URL),
      {
        requestInit: {
          headers: { 'Authorization': `Bearer ${JWT_TOKEN}` }
        }
      }
    )

    await client.connect(transport)

    const tools = await client.listTools()
    console.log('Available tools:', tools.tools.map(t => t.name))

    // Call geocode tool directly
    const geocodeResult = await client.callTool({
      name: 'hlr___geocode',
      arguments: { q: 'Alexanderplatz, Berlin' }
    })
    console.log('\nGeocode result:')
    console.log(geocodeResult.content)

  } finally {
    if (transport) await transport.close()
  }
}

await main()
```

</Accordion>

Use the MCP SDK directly for programmatic access to HERE Location Reasoning tools from Node.js without an agent framework.

A successful run prints available tool names and the geocoding result for Alexanderplatz.

### TypeScript Strands Agents

Demonstrates how a TypeScript-based Strands agent uses HERE Location Reasoning tools to fulfill a routing request and generate a route description.

<Accordion title="strands.ts" icon="fa-code">

```typescript
/**
 * Strands Agent example — connect to HERE Location Reasoning MCP.
 *
 * Shows:
 * - MCP client setup with auth headers
 * - Loading server-provided resource (usage policy) and prompt (guardrails)
 * - Composing both into the system prompt
 * - Bedrock model configuration
 * - Agent invocation with MCP tools
 */
import 'dotenv/config'

import { Agent, BedrockModel, McpClient } from '@strands-agents/sdk'
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp'

function requireEnvironmentVariable(name: string): string {
  const value = process.env[name]
  if (!value) {
    throw new Error(`Set ${name} before running this example.`)
  }
  return value
}

const SERVER_URL = requireEnvironmentVariable('HLR_SERVER_URL')
const MODEL_ID = requireEnvironmentVariable('BEDROCK_MODEL_ID')

// Create a HERE bearer token. Refer to the get_here_token() function in Step 2
// of the "Get started with HERE Location Reasoning" guide.
const JWT_TOKEN = '<YOUR_HERE_BEARER_TOKEN>'

const client = new McpClient({
  transport: new StreamableHTTPClientTransport(
    new URL(SERVER_URL),
    {
      requestInit: {
        headers: {
          'Authorization': `Bearer ${JWT_TOKEN}`,
        },
      },
    }
  ),
})

await client.connect()

// Load the server's usage policy (resource) and application instructions (prompt).
// These are server-provided guardrails instructions.
const guardrailPolicy = await client.client.readResource({
  uri: 'guardrails://location-reasoning-usage-policy',
})
const guardrailPrompt = await client.client.getPrompt({
  name: 'hlr___secure_location_reasoning',
})

// Extract text from the resource and prompt content
const policyText = guardrailPolicy.contents[0] && 'text' in guardrailPolicy.contents[0] ? guardrailPolicy.contents[0].text : ''
const instructionsContent = guardrailPrompt.messages[0] && 'content' in guardrailPrompt.messages[0] ? guardrailPrompt.messages[0].content : ''
const instructionsText = instructionsContent && 'text' in instructionsContent ? instructionsContent.text : ''

// Build system prompt with guardrails resource and prompt
const systemPrompt = `
<about>
You are a precise and accurate assistant.
</about>

<instructions>
${instructionsText}
</instructions>

<usage_policy>
${policyText}
</usage_policy>
`.trim()

const bedrockModel = new BedrockModel({
  modelId: MODEL_ID,
  stream: false,
})

const agent = new Agent({
  model: bedrockModel,
  tools: [client],
  systemPrompt,
  printer: false
})

try {
  const result = await agent.invoke('Plan a route from Paris to Berlin.')
  console.log(result.toString())
} finally {
  await client.disconnect()
}
```

</Accordion>

Use this example for TypeScript and Node.js applications that use Strands Agents and AWS Bedrock.

A successful run prints the agent's response to the route request from Paris to Berlin.

## Next steps

* **[HERE Location Reasoning tools reference](https://docs.here.com/location-reasoning/docs/hlrtools-reference)** — Complete list of available location tools with descriptions.