Azure AI Travel Agents: Three Orchestrators, Four MCP Server Languages, One Sample
A robust enterprise application sample (deployed on ACA) that leverages MCP and multiple AI agents orchestrated by Langchain.js, Llamaindex.TS and Microsoft Agent Framework.
At a glance
- What is it?
- Microsoft's Azure-Samples repository packages a travel-agency reference app with LangChain.js, LlamaIndex.TS, and Microsoft Agent Framework orchestration over Python, Node.js, Java, and .NET MCP servers. The value is the comparison surface, not the travel domain.
- Who is it for?
- Adopt this if you need a working reference for MCP client and server wiring across languages, or if you are choosing between LangChain.js, LlamaIndex.TS, and Microsoft Agent Framework and want all three in one tree. Do not adopt it as a travel product; the agents are named for a demo domain and the README does not describe production concerns such as persistence, auth, or evaluation.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The travel domain is the excuse, the MCP wiring is the point
Strip away the itinerary framing and this repository is a comparison harness. It exists so an engineer can see the same agent workflow expressed three ways: LangChain.js and LlamaIndex.TS in TypeScript, Microsoft Agent Framework in Python. The README lists four agents by name and purpose: Customer Query Understanding extracts preferences from an inquiry, Destination Recommendation suggests places, Itinerary Planning builds a plan, and Echo Ping returns whatever it receives as an MCP server example. That last one is the tell. Echo Ping is not a travel feature. It is a minimal MCP server kept in the sample so you can watch the protocol round-trip without any model behaviour in the way. If you are evaluating MCP as a tool-calling transport, that trivial server is more instructive than the three domain agents. The audience is developers at companies already committed to Azure, who want a containerized multi-service layout rather than a single-file agent demo. Anyone looking for a travel booking backend should stop reading here.
How the pieces connect: MCP servers as the tool boundary
The architecture section describes a consistent pattern. Agent tools are exposed as MCP servers, and MCP clients call them. The servers are deliberately polyglot: the README states they are implemented independently in Python, Node.js, Java, and .NET. Each orchestrator service coordinates between the agents and the MCP clients. That separation is the design decision worth noting. The model-facing orchestration logic and the tool implementations do not share a process, a runtime, or a language. You can replace a Java MCP server with a Python one without touching the orchestrator, provided the tool contract holds. It also means the operational surface is larger than a monolith: every MCP server is its own deployable unit with its own base image and dependency tree. The README says all components are containerized with Docker and managed by Azure Container Apps, which fits that shape. Container Apps scales each service independently, so the polyglot split does not force you to scale Java alongside Node. The Aspire Dashboard appears as the monitoring surface, fed by OpenTelemetry instrumentation, which the README lists both as a feature and as the mechanism for insight into agent performance and behaviour.
Getting it running: Codespaces, Docker, and the Node floor
The README leads with two entry points. There is a Codespaces badge pointing at codespaces.new for the repository on main with quickstart enabled, and a repeated call to preview the application locally for free, marked with a Docker logo. The local path is the one the README frames as the no-cost option, which is a reasonable default: the full deployment targets Azure Container Apps and therefore incurs Azure spend, and the README carries a separate cost estimation section for that. The only hard version constraint stated anywhere in the supplied material is the Node badge, which reads Node.js >=22. Treat that as a floor for the TypeScript orchestrators and any Node-based MCP server. The README does not enumerate the individual build or run commands for each service, so the practical starting point is the Codespaces quickstart or the Docker path, then the per-service documentation. Two auxiliary files are worth opening early. There is an llms.txt file, which the README says provides information to help LLMs use the project at inference time, and an adventure.config.json file described as a learning aid tied to an external repo-adventures project. Neither is required to run the app, but llms.txt is the more useful of the two if you plan to point a coding assistant at this tree.
Three orchestrators is a comparison, not a feature
The README presents LangChain.js, LlamaIndex.TS, and Microsoft Agent Framework as three orchestration options available as standalone services. Read that as a menu, not a stack. You pick one to run; the other two are there so you can read their implementations side by side and judge which abstraction fits your team. This is the most useful thing the repository does, and also the most likely source of confusion. A reader skimming the feature list may assume all three are active in a deployment, which would triple the orchestration surface for no benefit. The language split matters too. Two orchestrators are TypeScript, one is Python, so a team that is TypeScript-only has two candidates and a team that is Python-only has one. The README does not state that the three produce equivalent behaviour, and it does not publish a comparison of their output quality. That gap is real. If your decision hinges on which orchestrator handles multi-step tool calls better, this repository gives you the code to run that experiment yourself, but it does not give you the answer.
Where the sample stops short of production
The README is honest about scope in one word: reference. It demonstrates orchestration and MCP plumbing. It does not describe how conversations are persisted, how the services authenticate to each other, how MCP server endpoints are secured, or how agent output is evaluated. For a sample that is fine, and for a reader who mistakes the polish for a product it is a trap. The polyglot MCP layout compounds the operational load: four language runtimes mean four sets of base images, dependency updates, and vulnerability scans. The OpenTelemetry and Aspire Dashboard integration gives you traces, which is a genuine starting point for debugging agent behaviour, but tracing is not evaluation. You can see that an MCP call happened and how long it took without learning whether the itinerary it produced was any good. There is also no release history in the supplied material, so there is no changelog to read for breaking changes. The repository is not archived and the last push date is recent, which suggests active maintenance, but the absence of tagged releases means upgrade risk has to be assessed by diffing the tree.
What you would use instead, and why the difference matters
The obvious alternative is the official MCP quickstart servers plus a single orchestrator of your choice, wired together by hand. That path gives you one language, one container, and no travel-domain code to delete. The difference in approach is scope: this repository hands you a multi-service topology with four MCP server implementations already written in Python, Node.js, Java, and .NET, so you can see how each language binds to the protocol and copy the one that matches your stack. The hand-rolled path gives you nothing to copy but far less to remove. If your goal is to learn MCP server implementation across languages, the breadth here is the reason to use it. If your goal is to ship one agent service next quarter, the extra runtimes are dead weight you will spend a week deleting. A second alternative is to run the sample purely locally through the Docker preview and never deploy to Azure Container Apps at all, using it as a reading exercise rather than a deployment. That is a legitimate use and the README explicitly supports the free local preview.
Licence, maintenance, and what an upgrade actually costs
The licence is MIT, stated in the README badge and in the LICENSE.md file. MIT permits commercial use, modification, and redistribution with the copyright notice and permission notice retained. This is not legal advice; read LICENSE.md yourself and involve counsel if you plan to ship derived code. The maintenance picture is shaped by the dependency count rather than the licence. Three orchestrators means three framework dependency trees, two of them TypeScript and one Python, and each MCP server carries its own runtime dependencies. A framework upgrade in any one of them is a separate pull request against a separate lockfile. The README gives no version pins for the orchestrator frameworks and no release tags exist in the supplied material, so you cannot read upgrade guidance from a changelog. Expect to track upstream releases of LangChain.js, LlamaIndex.TS, and Microsoft Agent Framework yourself and to test each bump against the sample's own agent flow. The Aspire Dashboard and OpenTelemetry instrumentation are the practical safety net here: after an upgrade you can compare traces to see whether the MCP call pattern changed.
Editorial conclusion
Adopt this if you need a working reference for MCP client and server wiring across languages, or if you are choosing between LangChain.js, LlamaIndex.TS, and Microsoft Agent Framework and want all three in one tree. Do not adopt it as a travel product; the agents are named for a demo domain and the README does not describe production concerns such as persistence, auth, or evaluation. Verify two things first: that your Node runtime meets the badge's >=22 requirement, and that the orchestration service you intend to run has a Dockerfile and MCP client configuration present in the tree, since the README presents the three orchestrators as separate services rather than a single switchable one.
Community notes