Skip to main content

Option A: Scaffold a New Project

1

Create the project

pip install concierge-sdk
concierge init my-store
cd my-store
2

Run it

python main.py
Your MCP server is now running with staged workflows out of the box.

Option B: Convert an Existing MCP Server

Already have a FastMCP server? Change one import:
# Before
from mcp.server.fastmcp import FastMCP
app = FastMCP("my-server")

# After
from concierge import Concierge
app = Concierge("my-server")
All your existing @app.tool() decorators keep working. You’ve now got access to stages, transitions, state, and provider modes.

Build a Shopping Workflow

Let’s build an e-commerce flow with three stages: browse, cart, and checkout.
from concierge import Concierge

app = Concierge("shopping")

# --- Tools ---

@app.tool()
def search_products(query: str) -> dict:
    """Search the product catalog."""
    return {"products": [
        {"id": "p1", "name": "Laptop", "price": 899},
        {"id": "p2", "name": "Mouse", "price": 29},
    ]}

@app.tool()
def add_to_cart(product_id: str) -> dict:
    """Add a product to the shopping cart."""
    cart = app.get_state("cart", [])
    cart.append(product_id)
    app.set_state("cart", cart)
    return {"cart": cart}

@app.tool()
def checkout(payment_method: str) -> dict:
    """Complete the purchase."""
    cart = app.get_state("cart", [])
    return {"order_id": "ORD-123", "items": cart}

# --- Stages ---
# Group tools into named stages. The LLM only sees tools
# in the current stage, not all tools at once.

app.stages = {
    "browse": ["search_products"],
    "cart": ["add_to_cart"],
    "checkout": ["checkout"],
}

# --- Transitions ---
# Define which stages can move to which. This enforces
# ordering so the LLM can't skip steps or go backwards
# unless you explicitly allow it.

app.transitions = {
    "browse": ["cart"],
    "cart": ["browse", "checkout"],
    "checkout": [],  # terminal stage, workflow ends here
}

What Happens at Runtime

Notice the LLM only sees 1-2 tools per stage instead of all 3 at once. At scale (50+ tools), this dramatically improves reliability and reduces costs.

Add a Provider Mode

Want to reduce context even further? Switch to code mode:the agent writes Python instead of making individual tool calls:
from concierge import Concierge, Config, ProviderType

app = Concierge(
    "shopping",
    config=Config(provider_type=ProviderType.CODE),
)
Now the LLM sees a single execute_code tool and writes scripts like:
results = await tools.search_products(query="laptop")
await tools.add_to_cart(product_id=results["products"][0]["id"])
order = await tools.checkout(payment_method="credit_card")
print(order)

Deploy

concierge deploy
Your server gets a public URL and appears in the Concierge Platform with logs, analytics, and evaluation.

Next Steps

Transitions

Deep dive into stages and transitions

State

Learn about persistent session state

Backends

Plain, Search, Plan, and Code execution modes

Platform

Inspector, logs, evaluation, analytics