@microsoft/agents-hosting
Overview
The @microsoft/agents-hosting package provides the necessary tools and components to create and host Microsoft Agents. This package includes a compatible API to migrate a bot using botbuilder from the BotFramework SDK.
Installation
To install the package:
npm install @microsoft/agents-hosting
Hosting integration APIs
To make hosting an agent independent of any single web framework, this package
exposes framework-agnostic primitives that the
@microsoft/agents-hosting-express and
@microsoft/agents-hosting-fastify packages build on:
createCloudAdapter(agent, authConfig)— returns{ adapter, headerPropagation }for processing incoming activities. Use this from any web framework.CloudAdapterResult— return type ofcreateCloudAdapter.createAgentResponseHandler(adapter, agent, conversationState)— framework-agnostic handler(req, res, params) => Promise<void>for the authenticated SDK-specific Activity callback route.AgentResponseHandler,AgentResponseHandlerParams,AGENT_RESPONSE_ROUTE_PATH— supporting types and the canonical route path.WebResponse,NextFunction,WebRequestParamsCarrier— minimal structural interfaces (no Express/Fastify imports) used by the cross-framework helpers above.
Most consumers should keep using startServer/createAgentRequestHandler from the
Express or Fastify packages; reach for these APIs when adapting another framework.
This Activity callback flow is used for SDK-specific Activity-protocol delegation.
The Activity callback handler authenticates requests once through the supplied
CloudAdapter. That boundary validates the token for any configured host connection;
the handler then verifies that the caller application matches the delegated agent
recorded for that conversation. Existing route-level authorizeJWT middleware is
redundant but remains compatible. On configured or production hosts, missing,
invalid, expired, or wrong-audience tokens return 401. An authenticated caller
that does not match the delegated agent, or missing, malformed, or pre-upgrade
delegated state, returns 403.
Anonymous callbacks are supported only for unconfigured development hosts
outside production and emit a registration warning because peer ownership cannot
be verified. Pre-upgrade conversations must be restarted.
Example Usage based on the AgentApplication object
import { AgentApplication, MemoryStorage, TurnContext, TurnState } from '@microsoft/agents-hosting'
const echo = new AgentApplication<TurnState>({ storage: new MemoryStorage() })
echo.onConversationUpdate('membersAdded', async (context: TurnContext) => {
await context.sendActivity('Welcome to the Echo sample, send a message to see the echo feature in action.')
})
echo.onActivity('message', async (context: TurnContext, state: TurnState) => {
let counter: number = state.getValue('conversation.counter') || 0
await context.sendActivity(`[${counter++}]You said: ${context.activity.text}`)
state.setValue('conversation.counter', counter)
})
Example Usage based on bot framework Activity Handler
Create an Echo bot using the ActivityHandler
// myHandler.ts
import { ActivityHandler, MessageFactory } from '@microsoft/agents-hosting'
export class MyHandler extends ActivityHandler {
constructor () {
super()
this.onMessage(async (context, next) => {
const replyText = `Agent: ${context.activity.text}`
await context.sendActivity(MessageFactory.text(replyText))
await next()
})
}
}
Host the bot with express
// index.ts
import express, { Response } from 'express'
import { Request, CloudAdapter, authorizeJWT, AuthConfiguration, loadAuthConfigFromEnv } from '@microsoft/agents-hosting'
import { EchoBot } from './myHandler'
const authConfig: AuthConfiguration = loadAuthConfigFromEnv()
const adapter = new CloudAdapter(authConfig)
const myHandler = new MyHandler()
const app = express()
app.use(express.json())
app.use(authorizeJWT(authConfig))
app.post('/api/messages', async (req: Request, res: Response) => {
await adapter.process(req, res, async (context) => await myHandler.run(context))
})
Outbound request host validation
OutboundHostValidator provides an opt-in allowlist for server-side requests made
to activity service URLs and attachment URLs. Enforcement is disabled by default.
It can be configured with environment variables:
OutboundHostValidator__Enabled=true
OutboundHostValidator__IncludeDefaultMicrosoftHosts=true
OutboundHostValidator__Hosts=contoso.com,fabrikam.com
Indexed host variables such as OutboundHostValidator__Hosts__0=contoso.com are
also supported. A host entry matches both the exact host and its subdomains, and
is normalized (scheme/port/path stripped; a leading *. is accepted and ignored).
When enforcement is enabled, CloudAdapter rejects inbound activities whose
serviceUrl host is not allowlisted, and it also rejects serviceurl claim
mismatches (equivalent to CloudAdapterOptions.validateServiceUrl=true).
For explicit configuration, reuse the same immutable policy in the adapter and attachment downloaders:
import {
AgentApplication,
AttachmentDownloader,
CloudAdapter,
OutboundHostValidator
} from '@microsoft/agents-hosting'
const outboundHostValidator = new OutboundHostValidator({
enabled: true,
hosts: ['contoso.com']
})
const adapter = new CloudAdapter(undefined, undefined, undefined, undefined, outboundHostValidator)
const agent = new AgentApplication({
adapter,
fileDownloaders: [new AttachmentDownloader('inputFiles', outboundHostValidator)]
})
The validator checks the URL supplied to the downloader. Redirects retain native
fetch behavior.