npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

n8n-nodes-agents-sdk

v0.5.1

Published

n8n community nodes for the Microsoft 365 Agents SDK. Build Teams, M365 Copilot, WebChat, and Direct Line bots with 10 first-class card resources (Adaptive, Hero, Thumbnail, Animation, Audio, Video, Sign-In, Receipt, O365 Connector, Raw) — JWT validation,

Downloads

145

Readme

n8n-nodes-agents-sdk

npm version npm downloads license node

Build Microsoft Teams, M365 Copilot, WebChat, and Direct Line bots with n8n as your orchestration layer.

This is a community node for self-hosted n8n. It wraps the Microsoft 365 Agents SDK (the supported successor to botbuilder) so you get JWT validation, MSAL token management, Bot Connector routing, and the full CardFactory surface — Adaptive, Hero, Thumbnail, Animation, Audio, Video, Sign-In, Receipt, O365 Connector, and Raw Attachment — as first-class n8n operations. No raw HTTP, no hand-assembled Activity JSON, no OAuth plumbing.

0.4.0 breaking change. The single Card resource was split into ten first-class card resources (Adaptive, Animation, Audio, Hero, O365 Connector, Raw Attachment, Receipt, Sign-In, Thumbnail, Video). Workflows saved on 0.3.x with resource: "card" will fail loudly on load — rebuild them on resource: "adaptiveCard" (for templated Adaptive Cards) or the appropriate new card resource. See CHANGELOG.md for the full list.


What you get

| Without this package | With this package | | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | Webhook → Code node to parse Activity JSON | M365 Agent Trigger — parsed envelope out of the box | | Manual JWT validation (often skipped entirely) | Validated on every POST against Microsoft JWKS | | OAuth2 credential + scope + token-refresh plumbing | M365 Agent API credential — App ID + secret + tenant | | HTTP Request with hand-built /v3/conversations/... URLs | M365 Agent — pick a resource and an operation from dropdowns | | Manual ;messageid= thread suffix for Teams threads | Resource Message, operation Reply in Thread | | Hand-written card JSON for every card type | 10 first-class card resources — builder UI for rich cards, templating for Adaptive, raw JSON for connector/receipt |


Requirements

  • n8n 1.54+ (self-hosted — n8n Cloud's sandbox cannot load this package's runtime dependencies)
  • Node.js 20 or later
  • An Azure Bot registration (free F0 tier is fine) with App ID + client secret + tenant
  • A channel configured in Azure (Teams, M365 Copilot, WebChat, or Direct Line)

Install

From the n8n UI (single-instance self-hosted)

Settings → Community Nodes → Installn8n-nodes-agents-sdk

From npm

npm install n8n-nodes-agents-sdk

Queue mode (separate app + worker)

n8n's UI installer does not work in queue mode — it only installs on the node that handled the UI click, leaving workers out of sync. Install at container start instead:

# In your entrypoint, before exec /docker-entrypoint.sh:
cd /home/node/.n8n/nodes
npm install --no-audit --no-fund --omit=dev --omit=peer --omit=optional \
  n8n-nodes-agents-sdk@<pinned-version>

Both app and worker services need the package available. Use per-service bind mounts to avoid install races on shared volumes.


Nodes

M365 Agent Trigger

Receives POSTs from Azure Bot Service, validates the Bot Framework JWT, and emits a parsed envelope.

  • Validates the inbound JWT against the live Microsoft JWKS on every request
  • Handles Azure's GET endpoint-verification ping automatically
  • Filter by Activity type (message, invoke, conversationUpdate, etc.)
  • Response Mode parameter: Immediate (default — reply 200 right away) or Wait For Response Node (keep the HTTP connection open for a downstream M365 Agent → Invoke Response node — required for Action.Execute invokes and messaging-extension flows)

M365 Agent

Unified action node. Pick a Resource and an Operation; the canvas subtitle renders as <operation> <resource> (for example send heroCard, update adaptiveCard).

The Conversation Source toggle picks between From Envelope (default — read the conversation routing from the inbound item, works for every reply/update/delete flow) and Specify Manually (fill serviceUrl, conversation.id, channelId, and optional activityId yourself — for proactive sends originating outside the bot webhook).

  • Send — post a new message to a conversation
  • Reply — reply to a specific activity (auto-threads on Teams)
  • Update — edit a previously-sent activity
  • Delete — delete a previously-sent activity
  • Reply in Thread — reply inside an existing Teams thread via the ;messageid=<parentActivityId> suffix

All five operations share a Text field (with expression support), a Conversation Source selector, and an Options collection for optional knobs (Workflow Footer, Mentions, Suggested Actions).

Options (inside every body-carrying operation — Send / Reply / Update / Reply in Thread):

  • Mentions — add Teams @-mentions. User pings one person (paste the user's Teams/AAD object id and display name from your inbound trigger envelope). Everyone pings the whole team (uses Teams' magic ID internally). The node inserts matching <at>Name</at> tokens into the text and attaches the entities — no hand-assembly needed.
  • Suggested Actions — quick-reply chip buttons under the message. All 11 SDK action types supported (imBack, messageBack, postBack, openUrl, call, downloadFile, openApp, playAudio, playVideo, showImage, signin). Channel support varies — Teams, WebChat, and Direct Line each render a subset.
  • Send — render an Adaptive Card template against a data object and send it as a card attachment
  • Update — re-render the template with new binding data and update a card you already posted (requires activityId on the conversation reference)

Author the card in the Adaptive Cards Designer, paste the JSON into Card Template, and reference fields with ${field} placeholders. Binding Data defaults to the whole inbound item (={{ $json }}). Options → Fallback Text shows on clients that can't render Adaptive Cards (notifications, mobile lockscreens).

All card resources support Send and Update operations and share the same authentication, conversation-source, and fallback-text conventions as the Adaptive Card resource.

  • Hero Card — title / subtitle / text / images / buttons / tap.
  • Thumbnail Card — same shape as Hero, different rendering.
  • Animation Card — GIF / animation card with media URLs + buttons (requires at least one media URL).
  • Audio Card — audio card with media URLs + buttons.
  • Video Card — video card with media URLs + buttons.
  • Sign-In Card — sign-in card with title / URL / body text.
  • Receipt Card — receipt card via JSON content (title / facts / items / total).
  • O365 Connector Card — Teams-specific connector card via JSON content (title / sections / potentialAction).
  • Raw Attachment — power-user escape hatch. Supply Content Type + Content (JSON) directly; used for card families or attachment types not yet first-class here.

Buttons and tap actions across the builder-family resources use a unified CardAction row (Type + Title + Value + optional Channel Data / Value JSON / image / text / displayText), covering all 11 SDK action types.

  • Respond — write a synchronous response to an invoke activity

Required when handling Action.Execute button callbacks, messaging-extension searches, or any other invoke flow where Teams expects a same-request response. Pair with the Trigger's Response Mode: Wait For Response Node. Response Shape offers Simple ({ status, body } for generic invokes) or Advanced ({ statusCode, type, value } for Adaptive Card refreshes and follow-up messages).

Both nodes use the same credential — either M365 Agent API (classic bot) or M365 Agent 365 API (Agent 365). Neither is exposed as an AI-agent tool — side effects (sending to Azure Bot Service) and external webhook triggers aren't safe for autonomous LLM invocation.


Credential

M365 Agent API — your Azure Bot registration's App ID, client secret, and tenant. Three app types:

  • SingleTenant (recommended) — token scoped to a single Entra tenant
  • MultiTenant — kept for legacy registrations; Microsoft deprecated this path for new bots after 2025-07-31
  • UserAssignedMsi — Azure managed identity

The built-in credential test hits login.microsoftonline.com to verify network reachability. Full token-acquisition validation runs inside the Trigger on every inbound webhook.


Agent 365 support

v0.3.0 added first-class support for the Entra Agent Identity Blueprint alongside the classic Azure Bot credential. Register your bot as a Microsoft 365 Agent Identity (preview) and issue tokens through MSAL or an isolated auth sidecar — no changes required for existing classic bot deployments.

authKind parameter

| Value | Credential required | Description | | ------------ | ------------------- | ------------------------------------------------------- | | classicBot | M365AgentApi | Existing Azure Bot Service flow — unchanged from v0.2.1 | | agent365 | M365Agent365Api | Entra Agent Identity Blueprint — inline MSAL or sidecar |

Identity modes (Agent 365 only)

| Mode | When to use | Transport required | | ---------------- | ----------------------------------------------------------- | --------------------------------------------------------------------- | | autonomous | Agent acts as its Blueprint app identity | inline or sidecar | | agentUser | Agent acts as its own M365 user (requires separate license) | sidecar only | | interactiveOBO | Delegated calls to Graph / MCP as the inbound user | sidecar only (router-only; not yet surfaced on any card / message UI) |

Further reading


Quick start — echo bot in 3 nodes

[M365 Agent Trigger]  →  [Set]  →  [M365 Agent — Message: Reply]
  1. Credential. Create an M365 Agent API credential with your Azure Bot App ID, client secret, and tenant.
  2. Trigger. Drop an M365 Agent Trigger, attach the credential. Copy the node's Production webhook URL.
  3. Messaging endpoint. Paste the URL into your Azure Bot registration's Messaging endpoint field.
  4. Compose the reply. Drop a Set node (or just write an expression directly in step 5's Text field): Echo: {{ $json.activity.text }}.
  5. Reply. Drop an M365 Agent node. Set Resource = Message, Operation = Reply. Leave Conversation Source at From Envelope. Fill Text with the expression from step 4.
  6. Activate the workflow, message your bot in Teams, and the echo comes back within a second.

Envelope contract

Every node in this package reads and writes items of this shape:

{
  "conversationReference": {
    "serviceUrl", "conversation": { "id", "conversationType" },
    "activityId", "channelId", "bot", "user", "locale"
  },
  "activity": { "type", "text", "attachments", ... },
  "parsed": {      // Trigger only — convenience fields
    "action", "submitData", "userName", "userId", ...
  },
  "raw": { ... }    // Trigger only — full incoming Activity
}

Contract:

  • The Trigger emits the full envelope on every inbound activity.
  • The M365 Agent node reads conversationReference (via the From Envelope default) to route the outbound call. On output it spreads every input field through unchanged and adds an operation-specific result field (sendResult / replyResult / updateResult / deleteResult / replyInThreadResult / cardSendResult / cardUpdateResult).

Ancillary state you carry through your workflow (correlation IDs, cached state, upstream webhook payloads, etc.) survives the M365 Agent node unchanged.


Cards

Ten card resources cover every shape the Bot Framework / Teams renders. Pick the one that matches your UX — they fall into three authoring styles:

1. Builder cards — fill in a form, no JSON

Hero Card, Thumbnail Card, Animation Card, Audio Card, Video Card, Sign-In Card all expose a form UI. You fill in title, subtitle, text, images, buttons, media URLs — the node assembles the correct SDK shape for you. This is the simplest path for the common case (an order-update card, a "click here to sign in" card, a notification with quick-reply buttons).

The media-family (Animation / Audio / Video) requires at least one media URL and lets you set autoloop / autostart / aspect / duration under Options. Every builder card's Buttons and Tap Action share the same unified CardAction row (Type + Title + Value + optional Channel Data / Value JSON / image / text / displayText) across all 11 SDK action types (openUrl, imBack, messageBack, postBack, call, downloadFile, openApp, playAudio, playVideo, showImage, signin). Channel support varies — Teams, WebChat, and Direct Line each render a subset.

Minimal Hero Card workflow parameters:

resource: heroCard
operation: send
title: 'Order #{{$json.orderId}}'
subtitle: 'Ready for pickup'
text: 'Tap to confirm'
buttons:
  button:
    - type: openUrl
      title: 'View order'
      value: '{{$json.orderUrl}}'
options:
  fallbackText: 'Order ready'
  tapAction:
    type: openUrl
    value: '{{$json.orderUrl}}'

2. Adaptive Card — templated JSON with bindings

Paste a template from the Adaptive Cards Designer into Card Template. Use ${field} for placeholders. ${field} bindings resolve against whatever object you put in Binding Data (defaults to the whole inbound item ={{ $json }}):

{
	"type": "AdaptiveCard",
	"version": "1.6",
	"body": [
		{ "type": "TextBlock", "text": "Order #${orderId}", "weight": "bolder", "size": "large" },
		{ "type": "TextBlock", "text": "${status}" }
	],
	"actions": [
		{
			"type": "Action.Submit",
			"title": "Acknowledge",
			"data": { "action": "ack", "orderId": "${orderId}" }
		}
	]
}

Any [Parsing] Unknown property warnings the designer shows on Action.Submit.data custom keys are false positives — they're part of the Adaptive Cards spec, just not typed in the designer's bundled schema.

State-driven variants. You don't need a separate "pick-a-template-by-state" node. adaptivecards-templating supports this directly:

  1. ${field} — scalar binding. Change a value across the card with one variable: "style": "${statusStyle}", "text": "${statusBadgeText}".
  2. $when — conditional rendering. Show/hide whole sections per state: { "$when": "${status == 'completed'}", "type": "TextBlock", "text": "Done" }.
  3. $data — iterate over an array. Render one button per item in cardButtons.

A single template handles every state (new / accepted / in_progress / paused / completed, etc.) — no picker node needed. See the upstream adaptivecards-templating docs for the full reference.

3. JSON-content cards — paste the whole card

Receipt Card, O365 Connector Card, and Raw Attachment take the full card object as JSON in a single field. Use these when the card shape is fixed (Teams connector cards with their own schema) or when you want an escape hatch for attachment types not yet first-class here.

  • Receipt{ title, facts[], items[], total, tax?, vat?, tap?, buttons[] }.
  • O365 Connector — Teams-specific: { title, summary, themeColor, sections[], potentialAction[] }. See the cards reference.
  • Raw Attachment — you provide contentType + content directly. Useful for card families not yet first-class in this package.

Proactive sends (no inbound activity)

To message a channel from a workflow that wasn't triggered by the Trigger (a schedule, an external webhook, a database row, anything), switch Conversation Source to Specify Manually and fill in the fields. For Teams channels, conversation.id looks like 19:[email protected] and you'll typically have captured it from a prior bot interaction.

[Schedule Trigger]  →  [HTTP Request: fetch data]  →  [M365 Agent — Adaptive Card: Send (manual)]

Issues & contributions

Bug reports, feature requests, and PRs are welcome at github.com/mrkhachaturov/n8n-nodes-agents-sdk. Please include your n8n version, the resource/operation you're using, and the relevant workflow JSON or error message.


Links


License

MIT © Ruben Khachaturov