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

# Agent

# Agent

```typescript theme={null}
import { Agent } from '@svantic/sdk';
```

## What it is

`Agent` is the main class in the SDK. An `Agent` bundles three things:

1. **Identity** — a name, description, type, and instance id that together become the agent's public card.
2. **Capabilities** — the functions this agent makes callable over A2A (see [`define_capability`](#define_capabilityconfig)).
3. **Runtime** — an HTTP server or an outbound WebSocket, plus the Svantic registration / heartbeat machinery and automatic telemetry.

An `Agent` is also optionally **smart**: pass `instructions` and `llm` to let it reason about natural-language tasks and call its own capabilities as tools. Without those, it's a deterministic tool server — capabilities are invoked directly.

## When to use it

Every Svantic agent you build starts with `new Agent(...)`. Reach for it when you want to:

* Expose structured capabilities an LLM or another agent can invoke.
* Run a smart agent that plans its own work.
* Bridge MCP servers into the platform.
* Embed an agent into a service you already run.

If you only need to *call* other agents without hosting one yourself, use [`RemoteAgent`](./remote-agent) instead.

## Functional usage

The typical lifecycle:

```typescript theme={null}
import { Agent } from '@svantic/sdk';

// 1. Create the agent with identity and (optionally) smart-agent config.
const agent = new Agent({
  name: 'invoice-agent',
  description: 'Reads and summarizes invoices.',
  mesh: {
    client_id: process.env.SVANTIC_CLIENT_ID!,
    client_secret: process.env.SVANTIC_CLIENT_SECRET!,
  },
});

// 2. Register everything the agent can do. Capabilities must be
//    declared before start() so they appear on the agent card.
agent.define_capability({
  name: 'summarize',
  description: 'Summarize the given text in one sentence.',
  parameters: {
    type: 'object',
    properties: { text: { type: 'string' } },
    required: ['text'],
  },
  handler: async ({ text }) => ({ summary: `TL;DR of ${text.length} chars` }),
});

// 3. Optionally bridge an MCP server as additional capabilities.
await agent.register_mcp('filesystem', {
  command: 'npx',
  args: ['@modelcontextprotocol/server-filesystem', '/data'],
});

// 4. Go live. In connected mode (the default) this opens an
//    outbound WebSocket to Svantic. In hosted mode it starts an
//    HTTP server and registers its public URL.
await agent.start();

// 5. Shut down cleanly. stop() deregisters from Svantic and
//    closes any MCP child processes.
process.on('SIGTERM', () => agent.stop());
```

Two things are happening here that you don't see in the code:

* Every capability invocation is automatically wrapped in a telemetry span, visible in the dashboard's Traces tab. See [Telemetry](./telemetry).
* When the caller had an active trace, its W3C trace context is parsed and surfaced to your handler on `CapabilitySessionContext`, so outbound HTTP calls can continue the same trace. See [Trace propagation](./trace-propagation).

See the [Defining capabilities](../guides/defining-capabilities), [Smart agents](../guides/smart-agents), and [MCP integration](../guides/mcp-integration) guides for worked examples.

## Constructor

```typescript theme={null}
new Agent(config: AgentConfig)
```

`AgentConfig` is documented in full in [Types](./types#agentconfig). The most common shape:

```typescript theme={null}
const agent = new Agent({
  name: 'invoice-agent',
  description: 'Reads and summarizes invoices.',
  mesh: {
    client_id: process.env.SVANTIC_CLIENT_ID!,
    client_secret: process.env.SVANTIC_CLIENT_SECRET!,
  },
});
```

## Methods

### `define_capability(config)`

Register a capability. Must be called before `start()` or `expose()`.

```typescript theme={null}
agent.define_capability({
  name: 'summarize',
  description: 'Summarize the given text in one sentence.',
  parameters: {
    type: 'object',
    properties: {
      text: { type: 'string', description: 'Text to summarize' },
    },
    required: ['text'],
  },
  handler: async ({ text }, context) => {
    return { summary: `TL;DR of ${text.length} chars` };
  },
});
```

The `handler` receives `(args, context)`:

* `args` — the parsed parameters, validated against the JSON Schema.
* `context` — a [`CapabilitySessionContext`](./types#capabilitysessioncontext) with `session_id`, `tenant_id`, and W3C trace-propagation fields.

See [`CapabilityConfig`](./types#capabilityconfig) for the full option surface.

### `register_mcp(server_name, config, options?)`

Spawn an MCP server as a child process and register each of its tools as a capability on this agent.

```typescript theme={null}
await agent.register_mcp('chrome-devtools', {
  command: 'npx',
  args: ['chrome-devtools-mcp@latest'],
});
```

* `server_name` — logical name used as the capability prefix (hyphens become underscores, so `chrome-devtools` → capabilities named `chrome_devtools_<tool>`).
* `config` — `McpServerSpawnConfig`: `{ command, args?, env? }`.
* `options.tool_prefix` — override the default prefix.

Returns the list of registered capability names. Must be called before `start()` / `expose()`.

See the [MCP integration guide](../guides/mcp-integration).

### `start()`

```typescript theme={null}
const port = await agent.start();
```

Starts the agent as a standalone service:

* **Connected mode (default)** — opens an outbound WebSocket to Svantic. No HTTP server is started, no port is opened. Requires `mesh` credentials on `AgentConfig`.
* **Hosted mode** — when `public_url` or `port` is set on `AgentConfig`, starts an Express server on `port` (or an ephemeral port) and mounts `/send` + `/.well-known/agent-card.json`.

Returns the port the server is listening on (0 for connected-mode agents).

### `expose(app, endpoint_path?)`

```typescript theme={null}
agent.expose(app);              // mounts on /send
agent.expose(app, '/invoke');   // mounts on /invoke
```

Mount the agent's A2A endpoints on an Express application you already own. Use this when embedding into an existing service; pair with [`MeshConnector`](./mesh-connector) to register with Svantic.

Adds two routes:

* `/.well-known/agent-card.json` — agent card discovery
* `/send` (or the path you pass) — JSON-RPC 2.0 A2A endpoint

### `stop()`

```typescript theme={null}
await agent.stop();
```

Stop a running agent: disconnects from Svantic, closes the HTTP server (if any), and calls `close()`. Safe to call even if the agent was never started.

### `close()`

```typescript theme={null}
await agent.close();
```

Flush telemetry and tear down MCP child processes without touching the mesh connection or HTTP server. Normal teardown should use `stop()`; call `close()` directly only when you're managing the HTTP server and mesh connection yourself (e.g. in tests or when using `expose(app)` + a standalone `MeshConnector`).

### `set_context(context)`

Merge values into the agent's live context. Context is surfaced on the agent card and used by the platform for context-aware routing.

## Properties

| Property         | Type                            | Description                                                      |
| ---------------- | ------------------------------- | ---------------------------------------------------------------- |
| `name`           | `string`                        | The agent's display name.                                        |
| `description`    | `string`                        | What the agent does.                                             |
| `public_url`     | `string`                        | Public HTTPS URL (hosted mode); empty string for connected mode. |
| `agent_type`     | `string`                        | Logical agent type used for mesh routing.                        |
| `instance_id`    | `string`                        | Unique id for this running instance.                             |
| `version`        | `string`                        | Agent version (defaults to `'1.0.0'`).                           |
| `capabilities`   | `Map<string, CapabilityConfig>` | Registered capabilities, keyed by name.                          |
| `context`        | `Record<string, unknown>`       | Current live context.                                            |
| `instructions`   | `string \| undefined`           | System prompt (smart agent mode).                                |
| `llm_config`     | `LlmConfig \| undefined`        | LLM configuration (smart agent mode).                            |
| `is_smart_agent` | `boolean`                       | `true` when both `instructions` and `llm` are set.               |

> Telemetry is not owned by the `Agent` anymore — it flows through the global OpenTelemetry `TracerProvider`. Use `trace.getTracer(...)` from `@opentelemetry/api` to add custom spans. See [Telemetry](./telemetry).

## Helper methods

### `build_agent_card()`

Returns the [A2A agent card](https://a2a-protocol.org/) produced from the agent's current configuration and registered capabilities. Useful for inspection and testing.

## See also

* [`AgentConfig`](./types#agentconfig) — the full constructor option shape.
* [`CapabilityConfig`](./types#capabilityconfig) — what `define_capability` accepts.
* [Defining capabilities](../guides/defining-capabilities) — task-oriented walkthrough.
* [Connecting to Svantic](../guides/connecting) — connected vs. hosted modes.
