The Adaptive Card surfaces Apus sends to Teams, the Graph-backed roster lookup, and the target formats that address them.

Member info action

Apus exposes a Graph-backed member-info action for Microsoft Teams so agents and automations can resolve verified roster details for a configured conversation.

Requirements:

The action is available whenever Graph credentials are configured; there is no separate channels.msteams.actions.memberInfo toggle. Standard-channel lookups return the matching team-roster identity, display name, email, and roles. In the current DM or group chat, the action can return the trusted sender's stable user ID. Private/shared-channel and non-current chat member lookups require additional roster permissions and are rejected by the default permission baseline.

For member-info and search in the message tool, use channelId to select the conversation. The Graph <team-id>/<channel-id> form identifies a Teams channel:

{
  action: "member-info",
  channel: "msteams",
  channelId: "<team-id>/<channel-id>",
  userId: "<user-id>",
}

search uses the same channelId filter with a query instead of userId. Omitting the filter uses the current conversation when its Graph route is available. For the current channel, its bare 19:...@thread.tacv2 ID and conversation:19:...@thread.tacv2 form reuse that same Graph route. Use the full Graph form to select another channel. The selected conversation must still satisfy the configured access policy and the action's membership requirements.

Native approval cards

Microsoft Teams can deliver exec and plugin approval requests as Adaptive Cards in the originating conversation. Each card describes the requested command or plugin action and provides only the decisions allowed for that request, such as Approve once, Always allow, and Deny. After a decision or expiration, Apus updates the original card with its final status.

Enable the existing top-level approval forwarding settings for each approval type you want to receive:

{
  approvals: {
    exec: { enabled: true, mode: "session" },
    plugin: { enabled: true, mode: "session" },
  },
  channels: {
    msteams: {
      allowFrom: ["00000000-0000-0000-0000-000000000000"],
    },
  },
}

approvals.exec and approvals.plugin are independent; enabling one does not enable the other. Native card delivery also requires a configured Teams bot and at least one approver resolved from channels.msteams.allowFrom or channels.msteams.defaultTo. Approvers must be stable AAD object IDs; display names, email addresses, group entries, and conversation IDs do not grant approval access. Apus checks the clicking user's AAD object ID before resolving the request.

No Teams-specific approval configuration is required. The existing /approve <id> <decision> command remains available as a text fallback when native delivery is unavailable. For forwarding modes and supported decisions, see Approval forwarding to chat channels.

Polls (Adaptive Cards)

Apus sends Teams polls as Adaptive Cards (there is no native Teams poll API).

Revoking a scheduled job's message permission stops a poll that has not yet been submitted. A poll already submitted to Teams retains its accepted ID and normal vote tracking while the run finishes.

Presentation cards

Send semantic presentation payloads to Teams users or conversations using the message tool, CLI, or normal reply delivery. Apus renders them as Teams Adaptive Cards from the generic presentation contract.

The presentation parameter accepts semantic blocks. When presentation is provided, the message text is optional. Buttons render as Adaptive Card submit or URL actions. Select menus are not native in the Teams renderer, so Apus downgrades them to readable text before delivery.

Agent tool:

{
  action: "send",
  channel: "msteams",
  target: "user:<id>",
  presentation: {
    title: "Hello",
    blocks: [{ type: "text", text: "Hello!" }],
  },
}

CLI:

apus message send --channel msteams \
  --target "conversation:19:abc...@thread.tacv2" \
  --presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello!"}]}'

For target format details, see Target formats below.

Target formats

MSTeams targets use prefixes to distinguish between users and conversations:

Target type Format Example
User (by ID) user:<aad-object-id> user:40a1a0ed-4ff2-4164-a219-55518990c197
User (by name) user:<display-name> user:John Smith (requires Graph API)
Group/channel conversation:<conversation-id> conversation:19:abc123...@thread.tacv2
Group/channel (raw) <conversation-id> 19:abc123...@thread.tacv2, 19:...@unq.gbl.spaces, or a bare a:/8:orgid:/29: Bot Framework id

CLI examples:

# Send to a user by ID
apus message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"

# Send to a user by display name (triggers Graph API lookup)
apus message send --channel msteams --target "user:John Smith" --message "Hello"

# Send to a group chat or channel
apus message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "Hello"

# Send a presentation card to a conversation
apus message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \
  --presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello"}]}'

Agent tool examples:

{
  action: "send",
  channel: "msteams",
  target: "user:John Smith",
  message: "Hello!",
}
{
  action: "send",
  channel: "msteams",
  target: "conversation:19:abc...@thread.tacv2",
  presentation: {
    title: "Hello",
    blocks: [{ type: "text", text: "Hello" }],
  },
}

Without the user: prefix, names default to group or team resolution. Always use user: when targeting people by display name.

Proactive messaging