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

# Runtime

> ntro.capabilities.config — read tenant-scoped worker config from inside a runbook activity.

<Note>
  This page documents an SDK module that is real production surface — the `ntro-worker` runner uses it — but does not yet have a canonical runbook example. The example below is from the worker code; treat it as "this is how the API is shaped" rather than "this is how a runbook uses it". The page expands when a runbook starts using `config` directly.
</Note>

`ntro.capabilities.config` is for runtime config access *from inside a deployed runbook*. It reads the tenant-scoped configuration the worker holds (data platform credentials, provider settings, SMTP host, anything else config-toml-shaped) and returns it as a structured object the runbook can use.

This is distinct from the [Deploy & Run section](/deploy-and-run/testing-locally) — that section is about *the act of deploying*. This page is about a module called *from inside* a deployed runbook.

## Install

```bash theme={null}
pip install 'ntro[workflow]'
```

The capability is bundled with the workflow extra. Runbooks always have it.

## The API

```python theme={null}
from ntro.capabilities import config

cfg = config.get()
# cfg.email_smtp_host
# cfg.email_from_address
# cfg.data_plane_dsn
# ...etc
```

Returns the worker's loaded config as a typed object. Field set is determined by the worker's startup config — not the SDK. What you can read depends on what the platform team has populated for the tenant.

## Where it lives in the worker

`ntro-worker` itself uses `config.get()` to bootstrap its runtime. Roughly:

```python theme={null}
# From ntro-worker/ntro_worker/runner.py — illustrative
from ntro.capabilities import config

async def start_worker():
    cfg = config.get()

    # Bind to the data plane the tenant binding configured
    db_pool = await asyncpg.create_pool(cfg.data_plane_dsn)

    # Hand the worker the tenant's Temporal namespace
    client = await Client.connect(
        target_host=cfg.temporal_host,
        namespace=cfg.tenant_namespace,
    )
    ...
```

A runbook activity can do the same:

```python theme={null}
from ntro.workflow import activity
from ntro.capabilities import config


@activity.defn(name="example.read_config")
async def read_runtime_config() -> dict:
    cfg = config.get()
    return {
        "from_address": cfg.email_from_address,
        "smtp_host": cfg.email_smtp_host,
    }
```

## When you'd reach for this

Most runbooks shouldn't. The patterns documented elsewhere — [`ntro.data`](/sdk/capabilities/data) for the data plane, [`ai.extract`](/sdk/capabilities/private-ai) for AI calls, [`files.parse`](/sdk/capabilities/collect-files) for documents — already abstract over the credential plumbing. You don't need to reach into `config` to get a database connection; `get_data_plane(tenant_slug)` does it for you.

`config.get()` becomes useful when you're doing something the SDK doesn't already wrap:

* Reading a tenant-specific setting your runbook needs at runtime (regional reporting threshold, currency display preference)
* Calling an external service the SDK has no capability for (your tenant's bank API, a regulator-specific filing endpoint)
* Implementing a custom activity that the platform should provide as a capability one day, but doesn't yet

Treat it as the escape hatch — useful when needed, not the first thing to reach for.

## Disambiguation note

There are *three* "config" things in Ntropii — keep them straight:

| Thing                                        | Where it lives           | What it is                                                         |
| -------------------------------------------- | ------------------------ | ------------------------------------------------------------------ |
| **`~/.ntro/config.toml`**                    | Author's machine         | Local CLI / SDK connection config (host, API key)                  |
| **Skill `config_schema`**                    | `runbook.md` frontmatter | The shape of *workflow run* config — period, GL maps, etc.         |
| **`ntro.capabilities.config`** *(this page)* | Tenant worker            | The runtime config the worker boots with — DB DSN, SMTP host, etc. |

Workflow run config (the second one) flows in via the workflow's `context` — not via this module.

## Related

<CardGroup cols={2}>
  <Card title="Tenant architecture" icon="diagram-project" href="/get-started/tenant-architecture">
    Why the worker has tenant-scoped config in the first place.
  </Card>

  <Card title="Data" icon="database" href="/sdk/capabilities/data">
    For the common case (DB access), use `get_data_plane()` not `config.get()`.
  </Card>
</CardGroup>
