Back to Blog

Creating a Copilot Agent with the Teams CLI - A Quickstart That Actually Works

July 4, 20267 min readMichael Ridland

Most Australian organisations we work with started their Copilot journey the same way: someone in IT built a declarative agent in Copilot Studio, it did roughly what was promised, and then the requests started arriving that Copilot Studio couldn't handle. Call this internal API. Run this multi-step process. Keep state between turns. That's the point where you graduate to writing code, and Microsoft's answer for the code path is the Teams AI Library paired with the Teams CLI.

The good news is the quickstart experience has become genuinely quick. Microsoft's documentation on creating an agent with the Teams CLI walks you from nothing to a running agent in a handful of commands. The less good news is there are a few places where teams get stuck, mostly around tunnelling, tenant permissions and understanding what the scaffold actually gave you. Having taken several clients through this exact path, here's the honest version.

What the Teams CLI gives you

The CLI is a project scaffolder and dev loop for agents built on the Teams AI Library. In TypeScript, the flow looks like this:

npx @microsoft/teams.cli@latest new my-first-agent
cd my-first-agent
npm install
npm run dev

That new command generates a complete project: an app entry point wired up to the Teams AI Library, a manifest for the Teams app package, environment configuration, and the plumbing to receive and respond to messages. You're not starting from a blank folder trying to remember how the Bot Framework activity schema works. That alone saves half a day compared to how this used to go.

The generated agent is deliberately minimal. It echoes activity, handles a message, and shows you the shape of the programming model - handlers that respond to events, a strongly typed context object, and a clean place to plug in an LLM. The library's job is to hide the protocol noise between your code and Teams so you write logic, not envelope parsing. It mostly succeeds at that.

The local dev loop is the best part

Where this setup genuinely shines is the developer tools. Running npm run dev starts your agent locally alongside a DevTools web interface, usually on a localhost port, where you can chat with your agent immediately. No tunnel, no Azure resources, no app registration, no sideloading. You type a message in a browser, your handler fires, you see the response and the full activity payload.

I can't overstate how much friction this removes. The old workflow for testing a Teams bot involved provisioning a bot registration, standing up a tunnel, uploading a manifest, and then debugging through Teams itself, where every code change meant a slow reload cycle. Being able to iterate on conversation logic entirely on your laptop before Teams enters the picture changes the economics of experimentation. Junior developers can build and test agent behaviour on day one without touching an Azure subscription.

The playground isn't a perfect Teams emulator, mind you. Adaptive Card rendering is close but not identical to the Teams client, and anything involving Teams-specific context like channel metadata or meeting state needs real testing in the real client. Treat it like a unit test environment: brilliant for logic, not a substitute for integration testing.

Getting it into Teams, where the friction lives

When you're ready to see the agent inside Teams proper, you need three things: a public endpoint (the CLI integrates with dev tunnels for this), an app registration in your tenant, and the app package uploaded to Teams. The CLI automates a decent chunk of this, but this is also where every client engagement hits the same speed bumps, so let me name them.

First, custom app upload has to be enabled in your tenant. In most Australian enterprises it isn't, because someone locked it down in 2021 and nobody remembers why. You'll need a Teams administrator to either enable sideloading for your account or set up a proper dev tenant. My strong recommendation is the dev tenant. The Microsoft 365 developer program gives you a sandbox tenant where you're a global admin and can iterate freely, and it keeps half-finished agents out of your production environment. We've watched teams lose a full week waiting on an internal ticket to enable sideloading in prod when a dev tenant would have had them running in an hour.

Second, dev tunnels require authentication and occasionally behave differently behind corporate proxies. If your agent responds in the playground but goes silent in Teams, the tunnel is the first suspect. Check that the tunnel is running, anonymous access is configured the way the docs specify, and the messaging endpoint in your bot registration actually matches the current tunnel URL. Tunnel URLs change between sessions unless you configure them not to, and a stale endpoint is the single most common "it worked yesterday" cause we see.

Third, secrets. The scaffold uses environment files for your client ID, secret and model keys. Fine for a quickstart, not fine the moment this repository gets shared or deployed. Move credentials into proper secret management before the prototype becomes the product, because it always becomes the product.

Teams CLI or Copilot Studio? An opinion

Because we run both Copilot Studio engagements and pro-code agent builds, we get asked constantly which path to take. Here's the framework we actually use with clients.

If your agent is instructions plus knowledge plus a few connector-shaped actions, use Copilot Studio or a declarative agent. It's faster, cheaper to maintain, and business users can adjust it. Don't write code you don't need.

The Teams AI Library and CLI path earns its keep when you need real logic: calling internal systems with proper auth, orchestrating multi-step workflows, managing conversation state your way, writing tests, running CI/CD, or controlling exactly which model handles what. It's software development, with everything that implies - version control, code review, deployment pipelines. If your organisation has .NET or TypeScript developers already, the learning curve is shallow. The library's abstractions are sensible and the TypeScript types are genuinely helpful rather than decorative.

The trap is the middle ground. We've seen teams build code-first agents for problems Copilot Studio would have solved in an afternoon, and then own that codebase forever. We've also seen the reverse: Copilot Studio agents bent so far past their design intent, with flows calling flows calling HTTP actions, that a hundred lines of TypeScript would have been dramatically simpler. Picking the right tier up front is most of the value a consultant adds here, honestly. It's a big part of what our Microsoft AI consulting practice does in the first week of an engagement.

A few practical notes from real builds

Some things the quickstart won't tell you but experience will.

Name your agent properly in the manifest from day one. Renaming an app after people have installed it causes confusion, and in one memorable case a client ran two versions of the same agent side by side for a month because the old package was never removed.

Log everything during development. The Teams AI Library surfaces activities cleanly, and dumping the inbound activity JSON to the console while you're learning the model teaches you more about how Teams actually works than any documentation page.

Budget time for the manifest. The code is the easy half. App manifests, icons, permission scopes and publishing through your organisation's app catalogue involve at least one conversation with IT governance, and in larger organisations that conversation takes longer than the development did. Start it early.

And keep the Node and CLI versions pinned. The Teams tooling moves quickly, which is mostly good, but "quickstart worked in June, broken in August" is a real pattern with fast-moving CLIs. A pinned version in your package.json costs nothing and saves the mystery debugging session.

Where this fits

Agents living inside Teams are having a moment for a simple reason: that's where Australian knowledge workers already spend their day. An agent that answers leave policy questions, kicks off an approval, or summarises a project channel doesn't need to win a change management battle to get adopted. It's just there, in the chat list, next to everything else.

The Teams CLI quickstart is the fastest on-ramp to building those agents in code, and it's matured to the point where I'd happily put it in front of any competent developer. Start with the scaffold, live in the local playground until the logic is right, then budget realistic time for the tenant and publishing side. If you want help deciding between the low-code and pro-code paths, or you've got a prototype that needs to become production software, that's exactly the kind of work our AI agent development team does week in, week out. The original quickstart documentation is the right place to start typing.