Back to Copilotkit

Quickstart

showcase/shell-docs/src/content/docs/integrations/langgraph/quickstart.mdx

1.68.225.0 KB
Original Source

<OpsPlatformCTA variant="card" title="Ship LangGraph to production" body="Add persistent threads and the inspector with the Enterprise Intelligence Platform." ctaLabel="Create a free account" surface="docs_langgraph_quickstart" />

Prerequisites

Before you begin, you'll need the following:

  • An OpenAI API key
  • Node.js 20+
  • Your favorite package manager
  • (Optional) A LangSmith API key - only required if using an existing LangGraph agent

Getting started

<Steps> <Step> ### Create a free account
    <SignupLink surface="docs_langgraph_quickstart_step1">Sign up for a free developer account</SignupLink> on our Enterprise Intelligence Platform to get a license key. You'll use it later to enable persistent threads and the inspector.
</Step>

<Step>
    ### Choose your starting point

    You can either start fresh with our starter template or integrate CopilotKit into your existing LangGraph agent.

    <TailoredContent
        className="step"
        id="agent"
    >
    <TailoredContentOption
        id="starter"
        title="Start from scratch"
        description="Get started quickly with our ready-to-go starter application."
    >
        <Step>
            ### Run our CLI

            ```bash
            npx copilotkit@latest create
            ```

            The CLI walks you through:

            - **Project name**
            - **Enterprise Intelligence Platform** — persistent threads and the inspector. Choose **Yes** to scaffold a project pre-wired for the platform (the CLI walks you through sign-up, or you can [create an account](https://dashboard.operations.copilotkit.ai/?utm_source=docs&utm_medium=cta&utm_campaign=intelligence&utm_content=docs_cli_prompt) first), or **No** for a standard LangGraph setup.
            - **Framework** — pick **LangGraph (Python)** or **LangGraph (JavaScript)**.
        </Step>
        <Step>
            ### Install dependencies

            ```npm
            npm install
            ```
        </Step>
        <Step>
            ### Configure your environment

            Create a `.env` file in your agent directory and add your OpenAI API key:

            ```plaintext title=".env"
            OPENAI_API_KEY=your_openai_api_key
            ```

            <Callout type="info" title="What about other models?">
              The starter template is configured to use OpenAI's GPT-4o by default, but you can modify it to use any language model supported by LangGraph.
            </Callout>
        </Step>
        <Step>
            ### Start the development server

            <Tabs groupId="package-manager" items={['npm', 'pnpm', 'yarn', 'bun']}>
                <Tab value="npm">
                    ```bash
                    npm run dev
                    ```
                </Tab>
                <Tab value="pnpm">
                    ```bash
                    pnpm dev
                    ```
                </Tab>
                <Tab value="yarn">
                    ```bash
                    yarn dev
                    ```
                </Tab>
                <Tab value="bun">
                    ```bash
                    bun dev
                    ```
                </Tab>
            </Tabs>

            This will start both the UI and agent servers concurrently.
        </Step>
    </TailoredContentOption>
    <TailoredContentOption
        id="bring-your-own"
        title="Use an existing agent"
        description="I already have a LangGraph agent and want to add CopilotKit."
    >
      <Step>
          ### Initialize your agent project

          If you don't already have a Python project set up, create one using `uv`:

          ```bash
          uv init my-agent
          cd my-agent
          ```
      </Step>
      <Step>
          ### Install LangGraph

          Add the packages the agent code below imports:

          ```bash
          uv add langgraph langchain-openai langchain-core python-dotenv
          ```

          Both tabs below import all four. The **FastAPI** tab installs what
          its own code needs on top of these — `ag-ui-langgraph`, `fastapi`,
          `uvicorn` and `copilotkit` — in its own step; the LangSmith path
          imports none of them, so they are not in this line.

          <Callout type="warn" title="Project with pinned dependencies?">
            `uv add` resolves and rewrites your lockfile. If your project
            pins exact versions (`==`), add these to your dependency file by
            hand instead so the rest of your pins stay put.
          </Callout>
      </Step>
      <Step>
        ### Expose your agent via AG-UI

        If you already have a LangGraph agent written, just reference the following code. In this step
        we create a simple LangGraph agent for the sake of demonstration.
          <Tabs groupId="deployment_method" items={['LangSmith', 'FastAPI']}>
            <Tab value="LangSmith">
              First, we'll create a simple LangGraph agent:

              ```python title="main.py"
              from dotenv import load_dotenv
              from langchain_core.messages import SystemMessage
              from langchain_openai import ChatOpenAI
              from langgraph.graph import END, START, MessagesState, StateGraph
              load_dotenv()

              async def mock_llm(state: MessagesState):
                model = ChatOpenAI(model="gpt-4.1-mini")
                system_message = SystemMessage(content="You are a helpful assistant.")
                response = await model.ainvoke(
                  [
                    system_message,
                    *state["messages"],
                  ]
                )
                return {"messages": response}

              graph = StateGraph(MessagesState)
              graph.add_node(mock_llm)
              graph.add_edge(START, "mock_llm")
              graph.add_edge("mock_llm", END)
              graph = graph.compile()
              ```

              <Callout type="warn" title="Do not add a checkpointer on this path">
                `compile()` is called with no `checkpointer=` on purpose. The
                LangGraph API server owns persistence and injects its own
                checkpointer at run time. If you compile a custom one in,
                `langgraph dev` refuses to load the graph
                (`ValueError: ... includes a custom checkpointer ... persistence is
                handled automatically by the platform`) and a deployed graph
                ignores it. The **FastAPI** tab is the opposite case — see the
                note there.
              </Callout>

              Then to test and deploy with LangSmith, we'll also need a `langgraph.json`

              ```sh
              touch langgraph.json
              ```

              ```json title="langgraph.json"
              {
                "python_version": "3.12",
                "dockerfile_lines": [],
                "dependencies": ["."],
                "package_manager": "uv",
                "graphs": {
                  "sample_agent": "./main.py:graph"
                },
                "env": ".env"
              }
              ```
            </Tab>
            <Tab value="FastAPI">
              First, add the `ag-ui-langgraph` package to your project:

              ```bash
              uv add ag-ui-langgraph fastapi uvicorn copilotkit
              ```

              Then create a simple LangGraph agent, add a FastAPI app, and build attach our agent as an AG-UI endpoint.

              ```python title="main.py" doctest="server"
              import os

              # [!code highlight:2]
              from dotenv import load_dotenv
              from ag_ui_langgraph import add_langgraph_fastapi_endpoint
              from copilotkit import LangGraphAGUIAgent
              from fastapi import FastAPI
              from langgraph.graph import END, START, MessagesState, StateGraph
              from langchain_core.messages import SystemMessage
              from langchain_openai import ChatOpenAI
              from langgraph.checkpoint.memory import MemorySaver
              import uvicorn
              load_dotenv()

              async def mock_llm(state: MessagesState):
                model = ChatOpenAI(model="gpt-4.1-mini")
                system_message = SystemMessage(content="You are a helpful assistant.")
                response = await model.ainvoke(
                  [
                    system_message,
                    *state["messages"],
                  ]
                )
                return {"messages": response}


              graph = StateGraph(MessagesState)
              graph.add_node(mock_llm)
              graph.add_edge(START, "mock_llm")
              graph.add_edge("mock_llm", END)
              graph = graph.compile(
                checkpointer=MemorySaver()
              )

              app = FastAPI()

              # [!code highlight:9]
              add_langgraph_fastapi_endpoint(
                app=app,
                agent=LangGraphAGUIAgent(
                  name="sample_agent",
                  description="An example agent to use as a starting point for your own agent.",
                  graph=graph,
                ),
                path="/",
              )

              def main():
                """Run the uvicorn server."""
                uvicorn.run(
                  "main:app",
                  host="0.0.0.0",
                  port=8123,
                  reload=True,
                )

              if __name__ == "__main__":
                main()
              ```

              <Callout type="info" title="Why this tab compiles with a checkpointer">
                Here you run the graph yourself, so nothing supplies
                persistence. `ag-ui-langgraph` reads thread state via
                `graph.aget_state(...)`, which raises
                `ValueError: No checkpointer set` on a graph compiled without
                one — hence `MemorySaver()`. It keeps state in process memory
                only; swap in a durable saver (e.g. Postgres) for production.
                Do **not** copy this into the LangSmith tab's graph.
              </Callout>

              `main.py` sets uvicorn's port to `8123` above, which is the
              port the runtime route below expects. Change both together if
              you pick a different one.
            </Tab>
          </Tabs>

          <Callout type="info" title="What is AG-UI?">
            AG-UI is an open protocol for frontend-agent communication.
          </Callout>
      </Step>
      <Step>
          ### Configure your environment

          Create a `.env` file in your agent directory and add your OpenAI API key:

          ```plaintext title=".env"
          OPENAI_API_KEY=your_openai_api_key
          ```

          <Callout type="info" title="What about other models?">
            The starter template is configured to use OpenAI's GPT-4o by default, but you can modify it to use any language model supported by LangGraph.
          </Callout>
      </Step>
      <Step>
          ### Create your frontend

          CopilotKit works with any React-based frontend. We'll use Next.js for this example.

          ```bash
          npx create-next-app@latest frontend
          cd frontend
          ```
      </Step>
      <Step>
          ### Install CopilotKit packages

          ```npm
          npm install @copilotkit/react-core @copilotkit/runtime
          ```

          The components used below (`CopilotKit`, `CopilotSidebar`) and the
          stylesheet all come from `@copilotkit/react-core/v2`, so
          `@copilotkit/react-ui` is not needed for this setup.
      </Step>
      <Step>
          ### Setup Copilot Runtime

          Create an API route to connect CopilotKit to your LangGraph agent:

          ```sh
          mkdir -p app/api/copilotkit && touch app/api/copilotkit/route.ts
          ```

          <Callout type="warn" title="This route is enough for chat, not for Threads or the Inspector">
            A single `POST /api/copilotkit` is the *minimum* wiring: it runs
            the runtime in single-route mode, which is all chat needs.
            Persistent Threads and the Inspector's saved-Threads list need the
            multi-route handler instead — a catch-all
            `app/api/copilotkit/[[...slug]]/route.ts` that exports `GET`,
            `POST`, `PATCH` and `DELETE`, so list, rename, archive and delete
            requests can reach the runtime. If the Inspector shows **Finish
            setting up Rich Threads**, this is why. See
            [Runtime HTTP endpoints](/backend/runtime-endpoints#enable-rich-threads-routes)
            for the route and the provider setup that goes with it.
          </Callout>

          <Tabs groupId="deployment_method" items={['LangSmith', 'FastAPI']}>
            <Tab value="LangSmith">
              ```tsx title="app/api/copilotkit/route.ts"
              import {
                CopilotRuntime,
                ExperimentalEmptyAdapter,
                copilotRuntimeNextJSAppRouterEndpoint,
              } from "@copilotkit/runtime";
              // [!code highlight]
              import { LangGraphAgent } from "@copilotkit/runtime/langgraph";
              import { NextRequest } from "next/server";

              const serviceAdapter = new ExperimentalEmptyAdapter();

              const runtime = new CopilotRuntime({
                agents: {
                // [!code highlight:5]
                  sample_agent: new LangGraphAgent({
                    deploymentUrl:  process.env.LANGGRAPH_DEPLOYMENT_URL || "http://localhost:8123",
                    graphId: "sample_agent",
                    langsmithApiKey: process.env.LANGSMITH_API_KEY || "",
                  }),
                }
              });

              export const POST = async (req: NextRequest) => {
                const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
                  runtime,
                  serviceAdapter,
                  endpoint: "/api/copilotkit",
                });

                return handleRequest(req);
              };
            ```
          </Tab>
          <Tab value="FastAPI">
            ```tsx title="app/api/copilotkit/route.ts"
            import {
              CopilotRuntime,
              ExperimentalEmptyAdapter,
              copilotRuntimeNextJSAppRouterEndpoint,
            } from "@copilotkit/runtime";
            // [!code highlight]
            import { LangGraphHttpAgent } from "@copilotkit/runtime/langgraph";
            import { NextRequest } from "next/server";

            const serviceAdapter = new ExperimentalEmptyAdapter();

            const runtime = new CopilotRuntime({
              agents: {
                // [!code highlight:3]
                sample_agent: new LangGraphHttpAgent({
                  url:  process.env.LANGGRAPH_DEPLOYMENT_URL || "http://localhost:8123",
                }),
              }
            });

            export const POST = async (req: NextRequest) => {
              const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
                runtime,
                serviceAdapter,
                endpoint: "/api/copilotkit",
              });

              return handleRequest(req);
            };
          ```
          </Tab>
        </Tabs>
      </Step>
      <Step>
          ### Configure CopilotKit Provider

          Wrap your application with the CopilotKit provider:

          <Callout type="info" title="Which provider goes with which handler?">
            `<CopilotKit>` here is the backward-compatible wrapper: it defaults
            `useSingleEndpoint` to `true`, which is the matching half of the
            single-route `copilotRuntimeNextJSAppRouterEndpoint` above. `<CopilotKitProvider>`
            is the v2 provider from the same package and detects the transport from
            `/info` instead. They are not aliases — see
            [Provider and handler pairs](/backend/runtime-endpoints#provider-and-handler-pairs).
          </Callout>

          ```tsx title="app/layout.tsx"
          // [!code highlight:2]
          import { CopilotKit } from "@copilotkit/react-core/v2";
          import "@copilotkit/react-core/v2/styles.css";
          import './globals.css';

          // ...

          export default function RootLayout({ children }: {children: React.ReactNode}) {
            return (
              <html lang="en">
                <body>
                  <CopilotKit runtimeUrl="/api/copilotkit" agent="sample_agent">
                    {children}
                  </CopilotKit>
                </body>
              </html>
            );
          }
          ```
      </Step>
      <Step>
        ### Add the chat interface

        Add the CopilotSidebar component to your page:

        ```tsx title="app/page.tsx"
        import { CopilotSidebar } from "@copilotkit/react-core/v2"; // [!code highlight:1]

        export default function Page() {
          return (
            <main>
              <h1>Your App</h1>
              <CopilotSidebar />
            </main>
          );
        }
        ```
      </Step>
      <Step>
          ### Start your agent
          From your agent directory, start the agent server:

          <Tabs groupId="deployment_method" items={['LangSmith', 'FastAPI']}>
            <Tab value="LangSmith">
              ```bash
              cd ..
              npx @langchain/langgraph-cli dev --port 8123 --no-browser
              ```

              <Callout type="warn" title="Port 8123 is not the default">
                A bare `langgraph dev` (either the Python `langgraph-cli` or
                `@langchain/langgraph-cli`) serves on **2024**. This guide
                pins **8123** with `--port 8123` to match the
                `http://localhost:8123` fallback in the route above. Keep the
                flag, or drop it and change the route's URL to
                `http://localhost:2024` — but do not mix the two, or the
                runtime will fail to connect with no diagnostic beyond a
                connection error.
              </Callout>
            </Tab>
            <Tab value="FastAPI">
              ```bash
              cd ..
              uv run main.py
              ```

              This serves on **8123**, the port set in `main.py`'s
              `uvicorn.run(...)` call.
            </Tab>
          </Tabs>

          Your agent will be available at `http://localhost:8123` for both
          tabs above.
      </Step>
      <Step>
          ### Start your UI

          In a separate terminal, navigate to your frontend directory and start the development server:

          <Tabs groupId="package-manager" items={['npm', 'pnpm', 'yarn', 'bun']}>
              <Tab value="npm">
                  ```bash
                  cd frontend
                  npm run dev
                  ```
              </Tab>
              <Tab value="pnpm">
                  ```bash
                  cd frontend
                  pnpm dev
                  ```
              </Tab>
              <Tab value="yarn">
                  ```bash
                  cd frontend
                  yarn dev
                  ```
              </Tab>
              <Tab value="bun">
                  ```bash
                  cd frontend
                  bun dev
                  ```
              </Tab>
          </Tabs>
      </Step>
    </TailoredContentOption>
</TailoredContent>
</Step>
<Step>
    ### 🎉 Start chatting!

    Your AI agent is now ready to use! Try asking it some questions:

    ```
    Can you tell me a joke?
    ```

    ```
    Can you help me understand AI?
    ```

    ```
    What do you think about React?
    ```

    <Accordions className="mb-4">
        <Accordion title="Troubleshooting">
            - **Connection issues? Keep `localhost`, don't swap in a literal IP.** Which loopback address reaches the agent depends on the runtime, and `0.0.0.0` is a bind-all address for a server, never a valid target in a client URL.

              <Tabs groupId="language_langgraph_agent" items={['Python', 'TypeScript']} default="Python" persist>
                <Tab value="Python">
                  `langgraph dev` (the Python CLI) defaults to `--host 127.0.0.1`, so both `http://127.0.0.1:8123` and `http://localhost:8123` reach it. `http://[::1]:8123` does not — the server is not listening on IPv6.
                </Tab>
                <Tab value="TypeScript">
                  `@langchain/langgraph-cli` (the `langgraphjs` binary) defaults to `--host localhost`, which Node resolves to IPv6 on a dual-stack machine, binding `::1` **only**. So `http://localhost:8123` and `http://[::1]:8123` reach it, while `http://127.0.0.1:8123` is refused by that same running server — switching to `127.0.0.1` is what breaks it. If you need IPv4, bind it explicitly with `langgraphjs dev --host 127.0.0.1`.
                </Tab>
              </Tabs>
            - Make sure your agent folder contains a `langgraph.json` file
            - In the `langgraph.json` file, reference the path to a `.env` file
            - Check that your OpenAI API key is correctly set in the `.env` file
            - If using an existing agent, ensure your LangSmith API key is also configured
            - Make sure you're in the same folder as your `langgraph.json` file when running the `langgraph dev` command
            - **Connection refused from the runtime?** Check the port. A bare `langgraph dev` listens on `2024`; this guide's start command pins `8123` with `--port 8123`. The runtime's `LANGGRAPH_DEPLOYMENT_URL` (or its fallback) has to name the port the agent actually bound.
            - **"graph is nullish" error (JavaScript starters):** This means the LangGraph CLI couldn't load your graph. Ensure the export name in your `langgraph.json` matches your code (e.g., `"starterAgent": "./src/agent.ts:graph"` requires `export const graph = ...` in `agent.ts`). Also verify all dependencies are installed with `npm install` in your agent directory.
            - Make sure the runtime endpoint path matches the `runtimeUrl` in your CopilotKit provider
        </Accordion>
    </Accordions>

</Step>
</Steps>

Deploying to AWS?

If you're planning to deploy your LangGraph agent to AWS Bedrock AgentCore, see the AgentCore deploy guide.

What's next?

Now that you have your basic agent setup, explore these advanced features:

<Cards> <Card title="Implement Human in the Loop" description="Allow your users and agents to collaborate together on tasks." href="/langgraph/human-in-the-loop" icon={<UserIcon />} /> <Card title="Utilize Shared State" description="Learn how to synchronize your agent's state with your UI's state, and vice versa." href="/langgraph/shared-state" icon={<RepeatIcon />} /> <Card title="Add some generative UI" description="Render your agent's progress and output in the UI." href="/langgraph/generative-ui/tool-rendering" icon={<PaintbrushIcon />} /> <Card title="Setup frontend actions" description="Give your agent the ability to call frontend tools, directly updating your application." href="/langgraph/frontend-tools" icon={<WrenchIcon />} /> </Cards>

<video src="https://cdn.copilotkit.ai/docs/copilotkit/images/coagents/chat-example.mp4" className="rounded-lg shadow-xl" loop playsInline controls autoPlay muted />