As software engineering organizations adopt AI coding agents like Claude Code and Cline, team collaboration becomes a critical layer. Instead of running sandboxed agents strictly on local laptops, modern enterprise engineering platforms are pivoting to ChatOps.
By connecting Microsoft Teams to NanoClaw, developers can summon autonomous AI coding agents directly from shared Teams channels. A developer can drop a git issue link or trigger a task (e.g., @NanoClaw fix layout on checkout page), and the integration orchestrates a sandboxed container workspace, executes the agent, and streams terminal logs and step-by-step diffs right back to the Teams chat thread.
This article details the architecture, request flow, and security validation gates required to integrate Microsoft Teams with the NanoClaw sandbox orchestrator.
๐๏ธ The ChatOps Architecture: Webhooks to Sandboxes
To connect Microsoft Teams (a public enterprise SaaS platform) to the NanoClaw orchestrator (which manages ephemeral Docker containers), we establish a decoupled middleware bridge.
The request-response pipeline runs as follows:
- Webhook Ingestion: Microsoft Teams posts an activity event to our public gateway when the bot is
@mentioned. - Signature & Token Verification: The gateway validates the Microsoft Bot Framework authorization header to ensure requests are authentic.
- Sandbox Spawning: The gateway dispatches a task to the NanoClaw worker, which pulls files and spawns an ephemeral Docker sandbox container containing the Claude Code runtime.
- Standard I/O to SSE Bridge: A local Standard Input/Output bridge captures agent tool invocations, terminal logs, and system modifications in real-time.
- Adaptive Cards Rendering: NanoClaw streams these live updates back to the original Teams conversation thread using Microsoft Adaptive Cards, providing rich, interactive terminal displays directly in chat.
๐ก๏ธ Securing the Webhook Receiver
Before triggering container builds on our servers, we must strictly authorize Teams webhooks. Microsoft Teams signs incoming requests using JSON Web Signature (JWS) tokens distributed via Microsoft's OpenID Connect metadata keys.
We implement early authentication validation. If signature checks fail, we close network streams before Express parses body contents, protecting our CPU and RAM from resource exhaustion attacks.
๐ ๏ธ The Complete Gateway Implementation
Below is the complete Express webhook receiver written in Node.js/TypeScript. It validates Teams tokens, handles @mentioned text content, and spawns the NanoClaw sandbox task asynchronously:
// teams-nanoclaw-bridge.ts (Teams-to-NanoClaw Express Gateway)
import express, { Request, Response } from 'express';
import { BotFrameworkAdapter, TurnContext } from 'botbuilder';
import { spawnSandboxAgent } from './nanoclaw-orchestrator.js';
import { logger } from './logger.js';
const app = express();
// Initialize the Bot Builder SDK Adapter
// Retrieves App ID and Password from environment configurations
const adapter = new BotFrameworkAdapter({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
// Configure Adapter Error Handler
adapter.onTurnError = async (context, error) => {
logger.error({ error }, 'Microsoft Bot Framework Turn Error occurred.');
await context.sendActivity('โ NanoClaw Orchestrator encountered a communication failure.');
};
/**
* Main Webhook POST endpoint hit by Microsoft Teams Bot Channel Registration
*/
app.post('/api/teams/messages', (req: Request, res: Response) => {
// Use BotBuilder SDK adapter to securely parse and validate signature headers
adapter.processActivity(req, res, async (turnContext: TurnContext) => {
// Check if the event is a message activity
if (turnContext.activity.type === 'message') {
const rawText = turnContext.activity.text || '';
// Clean up the @mention markup to extract the raw task command
const cleanCommand = rawText.replace(/<at>.*<\/at>/i, '').trim();
const conversationId = turnContext.activity.conversation.id;
logger.info({ conversationId, command: cleanCommand }, 'Valid command received from Teams thread.');
// Return immediate receipt confirmation back to Teams (HTTP 202)
await turnContext.sendActivity('๐ ๏ธ Initiating container workspace and spawning NanoClaw agent...');
// Asynchronously trigger Docker sandbox build to avoid request blockages
try {
const result = await spawnSandboxAgent({
command: cleanCommand,
teamsConversationReference: TurnContext.getConversationReference(turnContext.activity)
});
logger.info({ result }, 'Sandbox spawned successfully.');
} catch (err: any) {
logger.error({ err }, 'Failed to spawn NanoClaw sandbox container.');
await adapter.continueConversation(
TurnContext.getConversationReference(turnContext.activity),
async (context) => {
await context.sendActivity(`โ Failed to start sandbox: ${err.message}`);
}
);
}
}
});
});
app.listen(8080, () => {
logger.info('Microsoft Teams NanoClaw Gateway listening on port 8080...');
});
๐ Summary of Benefits
Connecting Microsoft Teams to NanoClaw builds a high-performance, developer-focused ChatOps center:
- Shared Workspace Context: Developers collaborate inside the channel, viewing the agentโs execution steps, file creations, and linting checks in real-time.
- Robust Sandbox Isolation: All tasks trigger inside clean, ephemeral Docker environments. Malicious command inputs are trapped, protecting host servers.
- Interactive UI (Adaptive Cards): Adaptive Cards allow developers to click buttons directly in Teams to approve agent modifications, reject operations, or stop container workflows instantly.
By linking enterprise messaging threads with isolated Docker sandboxes, you can build unified ChatOps workflows capable of running high-performance coding agents across entire developer teams.