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

# The RPC Methods

```bash theme={null}
telnyx-acp invoke support-agent --conversation alice "hi"
telnyx-acp rpc support-agent --conversation alice approve <id>
```

```text {5,13} theme={null}
support-agent/
├── agent.json
├── instructions.md
└── .telnyx/                        written by deploy
    ├── index.ts                                       ◀
    ├── telnyx.toml
    ├── telnyx-env.d.ts
    └── package.json

@telnyx/acp/                      the package
├── managed/
│   ├── index.ts
│   ├── agent.ts                                       ◀
│   ├── model.ts
│   ├── memory.ts
│   ├── tools.ts
│   ├── mcp.ts
│   ├── voice.ts
│   ├── direct-turn.ts
│   └── filler.ts
├── channels/
│   ├── index.ts
│   ├── phone.ts
│   ├── email.ts
│   ├── web.ts
│   └── wire.ts
├── synth/
│   ├── index.ts
│   ├── code-entry.ts
│   └── vendor.ts
└── spec/
    ├── schema.ts
    ├── model.ts
    ├── phone.ts
    ├── project.ts
    └── io.ts
```

A POST to `/agents/<name>/<conversation>/rpc/<method>` calls one method on the conversation's instance. [`mountAgents`](/docs/agent-sdk/internals/mount/mountAgents) resolves the address to the instance and hands the POST to the class's [`fetch()`](/docs/agent-sdk/interface/fetch), and only a method marked [`@rpc`](/docs/agent-sdk/interface/rpc) answers. Who may call is decided by [`authorize()`](/docs/agent-sdk/interface/authorize), which [The Streams](/docs/agent-sdk/inside/request-handling/streams) shows with `fetch`. The class marks five methods.

## receive()

`invoke`, `chat` and `rpc … receive` post `["text"]` to `…/rpc/receive`:

```ts theme={null}
// managed/agent.ts
async receive(text, from, key) {
  return this.admit(text, from, key);
}
```

The reply is not returned from this call. It arrives through the task the harness queues and is read back on the state stream as `lastReply`, which is what `invoke` waits for. It is never sent out on a channel. `key` makes a redelivered message a no-op, answered with `duplicate: true`. [Admit](/docs/agent-sdk/inside/turn-taking/admit) is the next step.

`receive` carries [`@rpc`](/docs/agent-sdk/interface/rpc), as `@rpc({ description: "Deliver one inbound message; the reply is produced off the request path" })`.

* Only a method that carries it dispatches over the mount. Every other method of the class is private there.
* `description` is what [`rpcSurface()`](/docs/agent-sdk/interface/rpcSurface) reports for the method.

## Approvals and Runs

`approve`, `deny`, `inspectApproval`, `pendingApproval` and `run` are reached the same way, and through `telnyx-acp rpc`:

```ts theme={null}
// managed/agent.ts
async approve(approvalId)        { return (await this.ready()).approvals.grant(approvalId); }
async deny(approvalId)           { return (await this.ready()).approvals.deny(approvalId); }
async inspectApproval(approvalId){ return (await this.ready()).approvals.inspect(approvalId); }
async pendingApproval(runId)     { const hit = await this.pendingApprovalFor(runId); return hit ? { id: hit.id, runId, toolName: hit.toolName } : undefined; }
async run(runId)                 { return (await this.ready()).get(runId); }
```

Each reads or writes the harness's own ledger, which holds the pending approvals and the status of every run. A run paused on an `ask` continues on its own task once `approve` grants its approval. `pendingApproval` names the approval a paused run waits on, read from the ledger on that later call; `telnyx-acp invoke` asks for it when the state stream has not named it.

`approvals.grant()`, `approvals.deny()` and `approvals.inspect()` are the harness's [`approvals`](/docs/agent-sdk/harness-sdk/harness/approvals) ledger, and `get(runId)` is the harness's [`get()`](/docs/agent-sdk/harness-sdk/harness/get).

* `approvalId` names an approval, and each of the three returns its [`HarnessApproval`](/docs/agent-sdk/harness-sdk/harness/approvals#harnessapproval).
* `deny()` also continues the run. The call is not executed, and the model is told it was denied.
* Each of the three is checked against the authorization port for its [required action](/docs/agent-sdk/harness-sdk/harness/approvals#required-actions). The constructor registers that port from the host's `authorization`, as [The Harness](/docs/agent-sdk/inside/harness) shows.
* `runId` names a run, and `get()` returns its [`HarnessRun`](/docs/agent-sdk/harness-sdk/harness/get#harnessrun), or `undefined` for an unknown id.
* Each method calls `ready()` first, so the runs a restart interrupted are recovered before anything is read or decided.
