> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tai42.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Boot a server and call a tool over MCP.

Boot a working server from the shipped hello-world example, then list and call a
tool over MCP. The example is one local `greet` tool — no agents, no external
services, nothing to configure.

<Steps>
  <Step title="Install the runtime">
    Follow the [installation guide](/getting-started/installation) to clone the
    three packages side by side and run `uv sync` in `tai-skeleton`.
  </Step>

  <Step title="Boot the hello example">
    From the repository root, load the `examples/hello` manifest and serve it:

    ```bash theme={null}
    ACCESS_CONTROL_ENABLE=false \
    PYTHONPATH=examples/hello \
    uv run tai serve --manifest-path examples/hello/manifest.yml --port 8765
    ```

    `ACCESS_CONTROL_ENABLE=false` turns off the request-auth gate, which is on
    by default and checks every request against Redis — this example does not
    use it. `PYTHONPATH=examples/hello` makes the example's `myapp` package
    importable, because the manifest loads tools by import path. The server
    reports startup:

    ```
    INFO:     Application startup complete.
    INFO:     Uvicorn running on http://127.0.0.1:8765 (Press CTRL+C to quit)
    ```
  </Step>

  <Step title="Call the tool">
    The MCP endpoint is `http://127.0.0.1:8765/mcp`. From a second terminal,
    list the tools and call `greet`:

    ```bash theme={null}
    uv run python - <<'EOF'
    import asyncio
    from fastmcp import Client

    async def main():
        async with Client("http://127.0.0.1:8765/mcp") as c:
            print("tools:", [t.name for t in await c.list_tools()])
            result = await c.call_tool("greet", {"name": "World"})
            print("greet ->", result.content[0].text)

    asyncio.run(main())
    EOF
    ```

    Expected output:

    ```
    tools: ['greet']
    greet -> Hello, World!
    ```
  </Step>
</Steps>

## What just happened

The manifest named one tool module, `myapp.tools`. Importing that module ran its
registration decorator, which registered `greet` on the server:

```python theme={null}
from tai42_contract.app import tai42_app


@tai42_app.tools.tool
def greet(name: str) -> str:
    """Greet a person by name."""
    return f"Hello, {name}!"
```

The [manifest](/concepts/manifest) is the only thing that decides what a server
loads. An empty manifest (`{}`) boots a bare server with no tools; adding
sections adds capabilities.

## Next steps

<CardGroup cols={2}>
  <Card title="Mental model" icon="brain" href="/getting-started/mental-model">
    How the runtime fits together in one page.
  </Card>

  <Card title="Concepts" icon="lightbulb" href="/concepts/index">
    One page per pillar of the platform.
  </Card>

  <Card title="Build a tool" icon="wrench" href="/guides/build-a-tool">
    Register your own function as a tool.
  </Card>

  <Card title="Connect an MCP client" icon="plug" href="/integrations/index">
    Point Claude Desktop, Cursor, or any client at your server.
  </Card>
</CardGroup>
