## TL;DR
MessageGraph is deprecated; the replacement is `StateGraph` with a `messages` key in the state. Swap the constructor, declare the state with an `add_messages` reducer, and keep your nodes and edges as they are.

## Error
```text
LangGraphDeprecationWarning: MessageGraph is deprecated. Please use StateGraph with a messages key instead.
```

## Steps

1. Declare a state schema with a messages key using the add_messages reducer:
```python
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph.message import add_messages

class State(TypedDict):
    messages: Annotated[list, add_messages]
```
Expected output: a state type that appends messages instead of overwriting them, matching old MessageGraph behavior.

2. Replace the MessageGraph constructor with StateGraph carrying that state:
```python
# before
# graph = MessageGraph()
from langgraph.graph import StateGraph
builder = StateGraph(State)
```
Expected output: no deprecation warning on construction.

3. Port the nodes. MessageGraph nodes received a message list; StateGraph nodes receive the state dict and return a messages update:
```python
def my_node(state: State):
    reply = llm.invoke(state["messages"])
    return {"messages": [reply]}
```
Expected output: each node appends its reply to the running message list, exactly like before.

4. Wire entry point and edges the same way, then compile and run a parity test:
```python
builder.add_node("my_node", my_node)
builder.set_entry_point("my_node")
builder.set_finish_point("my_node")
graph = builder.compile()
```
Expected output: identical conversation output to the old MessageGraph, with no deprecation warning.

## When to use
- Your code constructs MessageGraph anywhere
- You are upgrading LangGraph and the warning appears in logs
- A tutorial or older codebase you inherited uses MessageGraph

## When not to use
- You need custom state fields beyond messages (declare a fuller TypedDict on StateGraph, this migration is just the starting point)
- You are writing a new graph from scratch (start on StateGraph directly)
- You pinned an old LangGraph and cannot upgrade (the warning is harmless until you do)

## Variant phrasings

### "MessageGraph is deprecated, use StateGraph" import warning
Same migration. The warning fires at import or construction time depending on version.

### migrating a message-only subgraph
Apply the same swap inside the subgraph builder, then compile it and add it to the parent as a single node.

## Why it happens
MessageGraph was always a thin wrapper around StateGraph with a pre-filled messages state. The maintainers deprecated the wrapper to keep one code path, so the messages-key pattern is now the canonical way to get the same behavior.

## Edge cases
- Nodes that returned a bare message must now return `{"messages": [...]}`; a bare return silently drops the reply.
- `add_messages` lives in `langgraph.graph.message`; importing it from elsewhere breaks on newer versions.
- `set_entry_point`/`set_finish_point` still exist on StateGraph, so simple linear chains port with no edge changes.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_QpWPsktAPfOu9ZRPTjhnsQ
