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

@cuylabs/agent-a365-tooling

v4.4.0

Published

Microsoft Agent 365 tooling adapter for @cuylabs/agent-core turn-scoped MCP tools

Readme

@cuylabs/agent-a365-tooling

Microsoft Agent 365 tooling adapter for @cuylabs/agent-core.

This package exposes a turn-scoped tool provider factory and an optional Agent 365 chat-history middleware. On each chat turn, the provider uses Microsoft's Agent 365 tooling SDK to discover MCP servers for the active Microsoft 365 turn, connects those servers through agent-core's MCP manager, and returns MCP tools for that turn only. The middleware can submit recent agent-core chat history to Microsoft's Agent 365 real-time threat protection registration endpoint.

Use this when your agent is hosted behind Microsoft 365 / Agent 365 and should use the MCP tool servers configured for the current tenant, user, and agent identity. Do not use it for static MCP servers known at startup; use agent-core MCP config for those.

What It Gives You

  • Agent 365 MCP server discovery per Microsoft 365 turn.
  • Microsoft SDK token exchange and per-server bearer headers.
  • Agent 365 platform headers for real Microsoft-hosted MCP servers.
  • Turn-scoped MCP tools that are cleaned up after the turn.
  • Opt-in Agent 365 chat-history submission for Microsoft's real-time threat protection registration API.
  • A Microsoft-specific adapter without importing Microsoft SDK types into agent-core.

Install

pnpm add @cuylabs/agent-a365-tooling @microsoft/agents-a365-tooling

If you use the default ambient TurnContext lookup, also use @cuylabs/agent-channel-m365 and configure @microsoft/agents-hosting in the host app.

Usage

import { createAgent } from "@cuylabs/agent-core";
import { createA365ToolingTurnToolProvider } from "@cuylabs/agent-a365-tooling";

const agent = createAgent({
  model,
  turnToolProviders: [
    createA365ToolingTurnToolProvider({
      authorization,
      authHandlerName: "agentic",
      toolOptions: {
        orchestratorName: "dory",
      },
    }),
  ],
});

By default the provider reads the active TurnContext from currentM365TurnContext() in @cuylabs/agent-channel-m365. For tests or custom hosts, pass getTurnContext.

createA365ToolingTurnToolProvider({
  authorization,
  authHandlerName: "agentic",
  getTurnContext: () => myTurnContext,
});

Chat History Submission

Microsoft's RTP API is developer-invoked; this package does not automatically intercept every conversation. Register the middleware only when the host should submit chat history for Microsoft Agent 365 analysis.

import { createAgent } from "@cuylabs/agent-core";
import {
  createA365ChatHistoryMiddleware,
  createA365ToolingTurnToolProvider,
} from "@cuylabs/agent-a365-tooling";

const agent = createAgent({
  model,
  turnToolProviders: [
    createA365ToolingTurnToolProvider({
      authorization,
      authHandlerName: "agentic",
    }),
  ],
  middleware: [
    createA365ChatHistoryMiddleware({
      toolOptions: {
        orchestratorName: "dory",
      },
    }),
  ],
});

The middleware defaults to timing: "after-turn", limit: 20, and maxContentChars: 32000. It reads history lazily from agent-core's lifecycle context, converts text content to Microsoft's { id, role, content, timestamp } shape, keeps the most recent converted messages within the content budget, and calls sendChatHistory even when the converted history is []. Empty arrays are intentional: Microsoft uses the current TurnContext.activity as the message being registered, with chatHistory as context. On onChatEnd, agent-core resolves this lazy history from the completed turn before any automatic context compaction rewrites the visible session history.

Tool messages are included by default to match Microsoft's standard-message expectation. Set includeTools: false only when the host has a privacy or compliance reason to filter tool outputs; doing so can reduce RTP context.

For non-M365 hosts, missing TurnContext is skipped by default:

createA365ChatHistoryMiddleware({
  onMissingTurnContext: "skip", // "skip" | "warn"
  getTurnContext: () => myTurnContext,
});

If another onChatEnd hook must run after the submission attempt, place it later in the middleware array. The captured history leaf is fixed before automatic compaction and before onChatEnd hooks run. The Microsoft SDK returns transport success/failure only; threat verdicts are not returned inline through sendChatHistory. Submission failures are non-blocking by design; use failureMode: "warn" to log them or failureMode: "ignore" to silence them.

Concept Docs

The package docs are split by concern:

| Doc | What it explains | | --- | --- | | docs/architecture.md | The four-layer split between agent-core, M365 channel ingress, Microsoft's A365 tooling SDK, and this adapter. | | docs/agent-core-mcp.md | How this package uses agent-core turnToolProviders and how that differs from static agent-core MCP config. | | docs/microsoft-a365-tooling.md | What Microsoft's Agent 365 tooling SDK owns: discovery, dev manifest mode, gateway calls, and auth headers. | | docs/lifecycle-and-limits.md | Per-turn lifecycle, cleanup, latency, filtering, connector replacement, and v0 limits. |

Start with docs/README.md if you want the reading order.

Required Host Inputs

| Option | Meaning | Typical source | | --- | --- | --- | | authorization | Microsoft Agents SDK Authorization object used for token exchange | Your M365 host application / @microsoft/agents-hosting setup | | authHandlerName | Name of the auth handler configured for Agent 365 token exchange | Your Microsoft Agents SDK app configuration | | getTurnContext | Optional resolver for the active Microsoft TurnContext | Defaults to @cuylabs/agent-channel-m365 ambient context | | authToken | Optional pre-resolved gateway token | Local development or specialized hosts; normally omitted in production | | toolOptions | Optional metadata such as orchestratorName | Host/application configuration |

In production, prefer omitting authToken so Microsoft's SDK performs token exchange for the active turn. In local dev-manifest mode, examples can pass a fake decoded token because the SDK reads ToolingManifest.json instead of calling the cloud gateway.

Open Microsoft Questions

These do not block the v0 adapter, but they matter for production policy:

  • Does /agents/real-time-threat-protection/chat-message require an Authorization header in production? Microsoft's current SDK call path passes undefined as the auth token.
  • What is the server-side HTTP body size cap for chatHistory, and does Microsoft recommend a client-side history limit?
  • Are retries with the same activity.id / messageId guaranteed idempotent?
  • Should post-turn chatHistory include the current user/assistant/tool messages, or only messages before the current activity?

What This Does Not Do

This package is not a channel, not an LLM provider, and not a replacement for agent-core's MCP engine. It does not implement cross-turn MCP pooling, mid-turn token refresh, or inline threat blocking. sendChatHistory is a submit/register call; hosts should not treat it as a synchronous threat verdict.

Examples

Runnable examples live in the repository under packages/agent-a365-tooling/examples. They are intentionally not included in the npm tarball because the example tsconfig.json and ToolingManifest.json are monorepo-local development harness files.

Start with examples/01-dev-manifest.ts; it uses Microsoft's local ToolingManifest.json path and an in-process MCP fixture, so it verifies the provider without Azure.