MCP server
There are two ways to create an MCP server:Pro-code with FastMCP
Build a custom MCP server in Python using the FastMCP framework, starting from an OpenAPI spec or handwritten tool functions.
Click-ops with Azure APIM
Expose existing APIs provisioned in Azure APIM as MCP servers directly from the Azure Portal without writing custom code.
Pro-code MCP server with FastMCP
Build a production-ready MCP server using the FastMCP Python framework. Thestarter-mcp-server repository provides a working reference implementation you can clone and extend.
GitHub repository
View source code, releases, and issues
Why FastMCP?
FastMCP is the recommended way to build MCP servers in Python. The official MCP Python SDK provides a low-level protocol implementation that requires manual handler registration, hand-crafted JSON Schema dictionaries, and transport boilerplate. FastMCP removes that complexity.Minimal boilerplate
A working MCP server is 5 lines of code. Register any Python function as a tool with a single decorator.
Automatic schema generation
Type hints become JSON Schema, Python docstrings become tool descriptions, and you don’t maintain schemas manually.
OpenAPI to MCP
Auto-generate an MCP server from any OpenAPI specification, turning every REST endpoint into an MCP tool.
Multiple transports
STDIO, Streamable HTTP, and SSE with a single configuration change.
Prerequisites
Install the following on your workstation:- Python 3.12+: Managed via UV
- UV Package Manager: Modern Python package manager that replaces pip and poetry
Quick start
Run the starter MCP server on your machine:1
Clone and install UV
2
Set up environment
3
Configure environment
Edit
.env with your values:4
Install dependencies and run
http://localhost:8557/mcp.Project structure
Thestarter-mcp-server repository contains the following directories and files:
Create an MCP server
The following sections show patterns from a minimal server through OpenAPI generation, custom tools, routing, and deployment.Minimal example
This example registers one tool and starts the server:Create tools with @mcp.tool
Decorate any Python function to expose it as a tool. FastMCP auto-generates the name, description, and input schema from the function signature.
ToolError messages are always sent to clients. When mask_error_details=True, FastMCP masks other exceptions from clients.
Return structured output
When a tool returns a dataclass or a Pydantic model, FastMCP automatically generatesstructuredContent in the MCP response, giving the calling agent a typed schema to work with instead of free-form text. The starter-mcp-server demonstrates both styles; the examples below are simplified, so see starter_mcp_server.py for the full models.
- Dataclass
- Pydantic model
Request user input with elicitation
Elicitation lets a tool pause mid-execution to ask the user for additional information or confirmation before continuing — useful for confirmation dialogs, collecting missing inputs, or interactive workflows. Thestarter-mcp-server uses this in its order_product tool: it fetches a product, asks the user to confirm via a typed schema, and branches on the response. The example below is simplified — see starter_mcp_server.py for the production handler.
Create from an OpenAPI spec
FastMCP can auto-generate an MCP server from any OpenAPI specification. Every endpoint becomes a tool that forwards requests to the underlying API. Thestarter-mcp-server uses this approach with the Platzi Fake Store API.
Integrate a REST API as a tool
Instead of auto-generating from an OpenAPI spec, wrap any API call as a hand-written tool function:Include and exclude tools
UseRouteMap to control which endpoints your MCP server exposes:
- Exclude routes
- Allowlist (include only)
- Tag-based visibility
Forward client headers
When your MCP server proxies an authenticated API, forward headers from the MCP client request to upstream API calls. Thestarter-mcp-server includes this pattern for forwarding Authorization headers:
Proxy bridge
The Proxy Provider enables transport bridging, server aggregation, and gateway patterns:- Transport bridging
- Multi-server proxy
Run the server
Start the server with transport, host, port, and path options:
Add a health check alongside the MCP endpoint:
Development
Use these commands while you change the server or add tools:Run tests
Execute the test suite with pytest:Build Docker image
Build a local image tag for the service:CI/CD
The.github/workflows directory defines these standard workflows:
- PR checks: Linting, testing, and validation
- Build and publish: Docker image creation on merge
- Release: Automated versioning and release notes
See CI/CD workflows for pipeline details.
Register in APIM via GitOps
After you deploy your FastMCP server, register it in APIM so the API gateway can route to it. This registration uses theagent-mcp-api template — a spec-only Maven project that produces an OpenAPI spec and Helm chart artifact for APIM deployment.
The deployment follows the GitOps pipeline: GitHub PR → ArgoCD → Azure Service Operator (ASO) → APIM.
1
Use the agent-mcp-api template
The
agent-mcp-api project defines a complete MCP Streamable HTTP API spec for APIM (POST /mcp, GET /mcp, DELETE /mcp, GET /health, GET /version) with full JSON-RPC 2.0 envelope schemas and MCP session headers.2
Configure applications-live registration
Register entries across five files in
applications-live (github.com/bb-ecos-<installation>/gc-<installation>-applications-live) under runtimes/<runtime>/apim/:3
Set Helm values
The ArgoCD
Application manifest sets these Helm parameters, and pulls shared values in through valueFiles:apimArmId (the Azure Resource Manager ID of the target APIM instance) is required by the chart, but you don’t set it per API — it’s defined centrally in common.apim.values.yaml and pulled in through valueFiles, so every API in the installation inherits it.The path defaults to info.x-api-domain and info.x-api-service from the OpenAPI spec (joined by a slash), or the Maven artifactId if those fields are absent. Override it with the apim-helm-plugin.path Maven property at build time, or the path Helm value at deploy time — required when another API already uses the resolved path on the target APIM instance.4
Deploy and validate
After ArgoCD picks up the merged PR, it deploys the API to APIM. Validate with a
tools/list call through the APIM gateway:For the complete reference including APIM policy configuration, product setup, and end-to-end validation details, see ADR-MCP - Track 1 - PoC Validation on Confluence.
Expose an API as an MCP server on Azure APIM
Azure APIM exposes your existing APIs as MCP servers without custom MCP server code. You select API operations in the Azure Portal, and APIM handles MCP protocol translation, tool discovery, and invocation. This approach is useful when you already have APIs provisioned in APIM and want to make them available to AI agents without building a separate FastMCP server.Prerequisites
Before you can expose an API as an MCP server on APIM:- Ensure network connectivity. The platform must have network connectivity to the target APIs. If it doesn’t, raise a ticket with the Service Desk to request access.
- Upload your API spec to APIM and register your API in Azure APIM using
applications-live(github.com/bb-ecos-<installation>/gc-<installation>-applications-liveunderruntimes/<runtime>/apim).
High-level steps
Configure MCP in APIM through the portal:- Navigate to APIs → MCP Servers (Preview) in your APIM instance
- Click Create MCP Server → Expose an API as an MCP Server
- Select the API and operations to expose, starting with read-only endpoints
- Configure APIM policies for security, including subscription key validation, rate limiting, and audit logging
- Test with MCP Inspector or
curl
For complete click-ops instructions that cover APIM policies, security configuration, rate limiting, audit logging, external MCP server proxying, and known issues, see the APIM MCP: click-ops guide on Confluence.
MCP client
Connect to an MCP server from different types of clients, including programmatic Python clients, AI-native tools like Cursor and Claude Desktop, and AI agent frameworks like Agno.GitHub repository
View source code, releases, and issues
You need a running MCP server to connect to. See MCP server to create one.
Transport types
Before connecting, determine which transport your MCP server uses:FastMCP client
FastMCP provides a built-inClient class for connecting to any MCP server programmatically. The client infers the transport from what you pass to it.
- Basic usage
- With auth headers
- Multi-server client
Cursor IDE
Cursor has built-in MCP support (v0.40+). Create.cursor/mcp.json in your project root:
- Streamable HTTP (remote)
- STDIO (local)
Claude Desktop
Claude Desktop reads its MCP configuration fromclaude_desktop_config.json:
- STDIO server
- Streamable HTTP (via mcp-remote)
Agno agent
Agno is a Python framework for building AI agents with built-in MCP support through itsMCPTools class.
- Streamable HTTP
- STDIO
- Multiple servers
Pass headers to MCP servers
How you pass authentication headers depends on your client type:- FastMCP client
- Cursor IDE
- Claude Desktop
- Agno
Next steps
From here you can extend agents, teams, knowledge, and pipelines:- Starter Agent: Start with basic agent patterns
- Multi-Agent: Build agent teams
- Knowledge Agent: Add RAG capabilities
- BB AI SDK: AI Gateway and observability
- CI/CD workflows: Pipeline details