> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hexr.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# hexr.gateway

> MCP tool discovery and invocation. Import any OpenAPI spec as MCP tools. Call external APIs with SPIFFE authentication and automatic credential injection from Vault.

## Quick Start

```python theme={null}
import hexr.gateway

# List available tools
tools = hexr.gateway.list_tools()
for tool in tools:
    print(f"{tool.name}: {tool.description}")

# Call a tool
result = hexr.gateway.call_tool("brave_web_search", {"query": "hexr platform"})
print(result.result)
```

***

## GatewayClient

```python theme={null}
from hexr.gateway import GatewayClient

gateway = GatewayClient(
    base_url="http://hexr-gateway.hexr-system:8090",
    tenant="acme-corp",
    timeout=60.0
)
```

### Methods

<ParamField path="list_tools(tags=None, source=None, force_refresh=False)" type="method">
  List available MCP tools. Results are cached.

  ```python theme={null}
  # All tools
  tools = gateway.list_tools()

  # Filter by tag
  search_tools = gateway.list_tools(tags=["search"])

  # Force refresh cache
  tools = gateway.list_tools(force_refresh=True)
  ```

  Returns: `list[Tool]`
</ParamField>

<ParamField path="get_tool(name)" type="method">
  Get a specific tool definition.

  ```python theme={null}
  tool = gateway.get_tool("brave_web_search")
  print(tool.name)        # "brave_web_search"
  print(tool.description) # "Search the web using Brave Search API"
  print(tool.parameters)  # [ToolParameter(...), ...]
  ```

  Returns: `Tool`
</ParamField>

<ParamField path="search_tools(query, limit=10, min_score=0.5)" type="method">
  Semantic search for tools.

  ```python theme={null}
  results = gateway.search_tools("send a message to slack")
  for r in results:
      print(f"{r.tool.name} (score: {r.score})")
  ```

  Returns: `list[SearchResult]`
</ParamField>

<ParamField path="call_tool(name, arguments=None, timeout=None)" type="method">
  Invoke a tool.

  ```python theme={null}
  result = gateway.call_tool(
      "brave_web_search",
      {"query": "latest AI research", "count": 5}
  )
  if result.success:
      print(result.result)
  else:
      print(f"Error: {result.error}")
  ```

  Returns: `ToolResult`
</ParamField>

<ParamField path="call_tool_mcp(name, arguments=None)" type="method">
  Invoke via raw MCP JSON-RPC 2.0 protocol.

  ```python theme={null}
  response = gateway.call_tool_mcp("brave_web_search", {"query": "hexr"})
  ```
</ParamField>

<ParamField path="register_openapi(spec, base_url, prefix='')" type="method">
  Register tools from an OpenAPI specification.

  ```python theme={null}
  # Register from URL
  tools = gateway.register_openapi(
      spec="https://api.example.com/openapi.json",
      base_url="https://api.example.com",
      prefix="example"
  )
  print(f"Registered {len(tools)} tools")
  ```

  Returns: `list[str]` (tool names)
</ParamField>

***

## Decorators

### @mcp\_tool

Route a function call through the MCP Gateway:

```python theme={null}
from hexr.gateway import mcp_tool

@mcp_tool("brave_web_search")
def search(query: str) -> str:
    pass  # Gateway handles the actual call

result = search("hexr platform")
```

### @discover\_tools

Auto-bind gateway tools as class methods:

```python theme={null}
from hexr.gateway import discover_tools

@discover_tools(prefix="brave")
class SearchAgent:
    pass

agent = SearchAgent()
result = agent.brave_web_search(query="hexr")  # Auto-bound method
```

***

## Tool Types

```python theme={null}
from hexr.gateway import Tool, ToolParameter, ToolResult, ToolType

# Tool definition
tool = Tool(
    name="brave_web_search",
    description="Search the web",
    parameters=[
        ToolParameter(name="query", type="string", required=True),
        ToolParameter(name="count", type="integer", default=10)
    ],
    source="openapi",
    tool_type=ToolType.FUNCTION
)

# Convert to LLM-compatible formats
openai_format = tool.to_openai_format()
mcp_format = tool.to_mcp_format()
```

***

## How It Works

<Frame>
  <Steps>
    <Step title="Agent calls call_tool()">
      Your agent calls `call_tool("brave_web_search", {query: "..."})` via the Gateway SDK.
    </Step>

    <Step title="Gateway looks up tool definition">
      The Gateway resolves the tool name to its registered definition and validates the arguments against the parameter schema.
    </Step>

    <Step title="Fetch credentials from Vault">
      The Gateway requests the API key for Brave Search from Hexr Vault (SPIFFE-authenticated).
    </Step>

    <Step title="Proxy request to external API">
      The Gateway sends `GET /search?q=...` to the Brave API with the injected API key header.
    </Step>

    <Step title="Return structured result">
      Search results are returned to the agent as `ToolResult(success=true, result=...)`.
    </Step>
  </Steps>
</Frame>

```
Agent → Gateway (lookup + validate) → Vault (API key) → External API → ToolResult → Agent
```

The Gateway:

1. **Validates** arguments against the tool's parameter schema
2. **Injects credentials** from Hexr Vault (no API keys in your code)
3. **Proxies** the HTTP request to the external API
4. **Returns** the result as a structured `ToolResult`

***

## Pre-Loaded Tools

The Gateway ships with tools from 3 embedded OpenAPI specs:

| Source             | Tools | Examples                                         |
| ------------------ | ----- | ------------------------------------------------ |
| **Brave Search**   | 2     | `brave_web_search`, `brave_local_search`         |
| **Slack**          | 5     | `slack_post_message`, `slack_list_channels`, ... |
| **OpenWeatherMap** | 6     | `weather_current`, `weather_forecast`, ...       |

Register additional tools by importing OpenAPI specs:

```python theme={null}
gateway.register_openapi(
    spec="https://api.github.com/openapi.json",
    base_url="https://api.github.com",
    prefix="github"
)
```
