> This page is for Server SDKs.

> Fetch clean Markdown by appending `.md` to any page URL under https://signalwire.com/docs or requesting it with the HTTP header `Accept: text/markdown`. The root index at https://signalwire.com/docs/llms.txt lists the available documentation indexes.

# Helper Functions

> Top-level convenience functions for creating contexts, data map tools, and managing skills.

[context]: /docs/server-sdks/reference/python/agents/context-builder/context

[contextbuilder]: /docs/server-sdks/reference/python/agents/context-builder

[datamap]: /docs/server-sdks/reference/python/agents/data-map

[skillbase]: /docs/server-sdks/reference/python/agents/skill-base

[ref-functionresult]: /docs/server-sdks/reference/python/agents/function-result

The SignalWire SDK exports several helper functions at the top level for common
tasks like creating simple contexts, building server-side API tools, and
managing the skill registry. All are imported directly from `signalwire`.

```python
from signalwire import (
    create_simple_context,
    create_simple_api_tool,
    create_expression_tool,
    list_skills,
    list_skills_with_params,
    register_skill,
    add_skill_directory,
)
```

---

## create_simple_context

**create_simple_context**(`name="default"`) -> [`Context`][context]

Create a standalone [`Context`][context] object
without needing a full [`ContextBuilder`][contextbuilder].
Useful for quick single-context agents.

#### Parameters

**`name`** `str` — default: default

Context name. For single-context agents this must be `"default"`.

---

#### Returns

[`Context`][context] -- A new Context
object ready for adding steps.

#### Example

```python
from signalwire import create_simple_context

ctx = create_simple_context()
ctx.add_step("greet").set_text("Say hello to the caller.")
ctx.add_step("help").set_text("Ask how you can help today.")
```

---

## create_simple_api_tool

**create_simple_api_tool**(`name`, `url`, `response_template`, `parameters=None`, `method="GET"`, `headers=None`, `body=None`, `error_keys=None`) -> [`DataMap`][datamap]

Create a server-side API tool with minimal configuration. Returns a configured
[`DataMap`][datamap] that executes an HTTP
request on the SignalWire server without requiring a webhook endpoint.

#### Parameters

**`name`** `str` — required

Function name for the SWAIG tool.

---

**`url`** `str` — required

API endpoint URL. Supports `${variable}` substitution for injecting parameter
values (e.g., `"https://api.example.com/search?q=${args.query}"`).

---

**`response_template`** `str` — required

Template string for formatting the API response. Uses `${response.field}`
syntax to reference fields from the API response JSON.

---

**`parameters`** `dict[str, dict]`

Parameter definitions. Each key is a parameter name, and each value is a
dictionary with `type`, `description`, and optionally `required`.

---

**`method`** `str` — default: GET

HTTP method for the API call.

---

**`headers`** `dict[str, str]`

Optional HTTP headers to include in the request.

---

**`body`** `dict[str, Any]`

Optional request body for POST/PUT requests.

---

**`error_keys`** `list[str]`

JSON keys whose presence in the response indicates an error.

---

#### Returns

[`DataMap`][datamap] -- A configured DataMap
ready to be added to an agent.

#### Example

```python
from signalwire import create_simple_api_tool

weather_tool = create_simple_api_tool(
    name="get_weather",
    url="https://api.weather.com/v1/current?key=API_KEY&q=${args.location}",
    response_template="Weather in ${args.location}: ${response.current.condition.text}, ${response.current.temp_f}F",
    parameters={
        "location": {
            "type": "string",
            "description": "City name",
            "required": True
        }
    }
)
```

> **Tip**
>
> For more complex API integrations with multiple webhooks, fallback outputs, or
> array processing, use the [`DataMap`][datamap]
> builder directly.

---

## create_expression_tool

**create_expression_tool**(`name`, `patterns`, `parameters=None`) -> [`DataMap`][datamap]

Create a pattern-matching tool that evaluates expressions locally on the
SignalWire server without making any HTTP requests. Useful for command routing
and conditional responses.

#### Parameters

**`name`** `str` — required

Function name for the SWAIG tool.

---

**`patterns`** `dict[str, tuple[str, FunctionResult]]` — required

Dictionary mapping test values to `(pattern, [FunctionResult][ref-functionresult])` tuples. The test
value is a template string (e.g., `"${args.command}"`), and the pattern is a
regex string matched against it.

---

**`parameters`** `dict[str, dict]`

Parameter definitions, same format as `create_simple_api_tool`.

---

#### Returns

[`DataMap`][datamap] -- A configured DataMap
with expression-based routing.

#### Example

```python
from signalwire import create_expression_tool
from signalwire import FunctionResult

playback_tool = create_expression_tool(
    name="playback_control",
    patterns={
        "${args.command}": (
            r"play.*",
            FunctionResult().add_action("start_playbook", {"file": "${args.filename}"})
        ),
        "${args.command}": (
            r"stop.*",
            FunctionResult().add_action("stop_playback", True)
        ),
    },
    parameters={
        "command": {"type": "string", "description": "Playback command", "required": True},
        "filename": {"type": "string", "description": "File to play"},
    }
)
```

> **Note**
>
> Since dictionary keys must be unique, use separate `DataMap.expression()` calls
> via the [`DataMap`][datamap] builder if you
> need multiple patterns against the same test value.

---

## list_skills

**list_skills**() -> `list[dict[str, Any]]`

Return one summary dictionary per available skill. The lighter counterpart of
[`list_skills_with_params()`](#list_skills_with_params), drawn from the same
skill registry.

#### Returns

`list[dict[str, Any]]` -- One entry per skill with its name, description,
version, required packages and environment variables, and whether it supports
multiple instances.

#### Example

```python
from signalwire import list_skills

for skill in list_skills():
    print(skill["name"], "-", skill["description"])
```

---

## list_skills_with_params

**list_skills_with_params**() -> `dict[str, dict[str, Any]]`

Return a comprehensive schema for all available skills, including metadata and
parameter definitions. Useful for GUI configuration tools, API documentation,
or programmatic skill discovery.

#### Returns

`dict[str, dict[str, Any]]` -- Dictionary keyed by skill name. Each value
contains the skill's metadata and a `parameters` dictionary describing each
configurable parameter with its `type`, `description`, `required` status,
`hidden` flag, and `env_var` name.

#### Example

```python
from signalwire import list_skills_with_params

schema = list_skills_with_params()
for skill_name, skill_info in schema.items():
    print(f"{skill_name}: {skill_info.get('description', '')}")
    for param, meta in skill_info.get("parameters", {}).items():
        print(f"  {param}: {meta['type']} (required={meta.get('required', False)})")
```

---

## register_skill

**register_skill**(`skill_class`) -> `None`

Register a custom skill class with the global skill registry. This allows
third-party code to make skills available without placing them in a specific
directory structure.

#### Parameters

**`skill_class`** `type` — required

A class that inherits from
[`SkillBase`][skillbase]. Must define
`SKILL_NAME` and `SKILL_DESCRIPTION` class attributes.

---

#### Example

```python
from signalwire import register_skill
from signalwire import AgentBase

class MyWeatherSkill:
    SKILL_NAME = "my_weather"
    SKILL_DESCRIPTION = "Custom weather lookup"

    def setup(self):
        return True

    def register_tools(self):
        self.define_tool(name="get_weather", handler=self._get_weather, description="Get weather")

    def _get_weather(self, args, raw_data):
        return {"response": "Sunny, 72F"}

register_skill(MyWeatherSkill)

agent = AgentBase(name="my-agent")
agent.add_skill("my_weather")
```

---

## add_skill_directory

**add_skill_directory**(`path`) -> `None`

Add a directory to the skill search path. Skills in this directory should follow
the same structure as built-in skills (each skill in its own subdirectory with
an `__init__.py` exporting a `SkillBase` subclass).

#### Parameters

**`path`** `str` — required

Path to a directory containing skill subdirectories.

---

#### Example

```python
from signalwire import add_skill_directory, AgentBase

add_skill_directory("/opt/custom_skills")

agent = AgentBase()
agent.add_skill("my_custom_skill")  # Found in /opt/custom_skills/my_custom_skill/
```