HERE Location Reasoning integration examples
Beta availability
HERE Location Reasoning is currently available to beta participants. For information about joining the beta, visit HERE Location Reasoning.
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
- Follow Steps 1-2 of Get started with HERE Location Reasoning to create your signing key and generate a HERE bearer token. For the full authentication and session reference, see Connect and authenticate.
- Choose a Python or TypeScript example.
- 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 |
Authentication requires a HERE bearer token. See Steps 1-2 of Get started with HERE Location Reasoning to create one.
The agent examples use AWS Bedrock. HERE Location Reasoning supports any large language model provider that supports tool calling.
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.
mcp-sdk.py
"""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())
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.
langchain-example.py
"""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())
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.
strands-example.py
"""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())
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.
pydantic_ai-example.py
"""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())
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.
mcp-sdk.ts
/**
* 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()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.
strands.ts
/**
* 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()
}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 — Complete list of available location tools with descriptions.
Updated 14 hours ago