A native OpenClaw plugin that provides the sequential_thinking tool for dynamic and reflective problem-solving — no MCP dependency required.
Inspired by the MCP SequentialThinking server — ported from the MCP protocol to run as a first-class OpenClaw plugin with per-session state isolation and model-targeted prompt injection.
This plugin registers a first-class sequential_thinking tool directly into the OpenClaw runtime via api.registerTool. It ports the original MCP SequentialThinkingServer logic to run natively inside the plugin, maintaining full compatibility with the original behavior:
- Thought history tracking
- Branching support
- Revision support
- Dynamic
totalThoughtsadjustment
index.ts
└─ plugin.ts → registerSequentialThinkingPlugin()
├─ config.ts → resolveConfig()
├─ tool.ts → SequentialThinkingTool class
├─ schema.ts → TOOL_PARAMETER_SCHEMA
├─ state.ts → StateManagement interface and CompositeStateManagement implementation
├─ state-interface.ts → StateManagement and StateOperations interfaces
└─ composite-state-management.ts → CompositeStateManagement class implementation
├─ tool-metadata.ts → TOOL_DESCRIPTION & PREFER_SEQUENTIAL_THINKING_CONTEXT
└─ hooks.ts → createHookHandlers()
├─ state.ts (for session management)
└─ config.ts (for hook-time config resolution)
| Module | Purpose |
|---|---|
index.ts |
Plugin entry point — exports definePluginEntry with registration function |
api.ts |
Re-exports from openclaw/plugin-sdk (OpenClawPluginApi, createSubsystemLogger) |
src/config.ts |
Config type definition and resolveConfig() — parses raw plugin config with defaults |
src/schema.ts |
TypeBox schema for the public sequential_thinking tool input contract |
src/tool-metadata.ts |
Tool description and prompt-injection system context for targeted models |
src/tool.ts |
SequentialThinkingTool class — core thought processing with input validation & no mutation |
src/state.ts |
SessionStateManager class — encapsulated state lifecycle with SDK cleanup integration |
src/hooks.ts |
SDK hook handlers — manages per-session state mapping and lifecycle events |
src/plugin.ts |
Plugin orchestration — resolves config, registers tool, session extension, and SDK hooks |
- Registration Phase:
registerSequentialThinkingPlugin()registers tool and hooks - Tool Execution:
SequentialThinkingToolprocesses thinking steps - State Management:
SessionStateManagertracks thought history and branches - Hooks Processing:
createHookHandlers()handles session lifecycle events
graph TB
subgraph "OpenClaw Runtime"
EntryPoint["index.ts<br/>Plugin Entry"]
subgraph "Plugin Registration (plugin.ts)"
ConfigRes["config.ts<br/>resolveConfig()"]
ToolClass["tool.ts<br/>SequentialThinkingTool"]
subgraph "SDK Hooks Integration"
Hooks["hooks.ts<br/>createHookHandlers()"]
end
SessionExt["Session Extension<br/>registerSessionExtension()"]
end
subgraph "State Management (state.ts)"
StateManager["SessionStateManager<br/>Per-session state isolation"]
end
end
EntryPoint --> PluginReg["registerSequentialThinkingPlugin()"]
PluginReg --> ConfigRes
PluginReg --> ToolClass
PluginReg --> Hooks
PluginReg --> SessionExt
ConfigRes --> Hooks
ToolClass --> Hooks
StateManager --> Hooks
StateManager --> SessionExt
Hooks -.->|"before_prompt_build<br/>before_tool_call<br/>after_tool_call<br/>message_sending<br/>before_agent_reply<br/>agent_end"| OpenClawSDK["OpenClaw SDK Events"]
style EntryPoint fill:#e1f5fe
style ToolClass fill:#f3e5f5
style StateManager fill:#e8f5e8
style OpenClawSDK fill:#fff3e0
| Hook | Purpose |
|---|---|
before_prompt_build |
Uses event.prompt, event.messages, hook-time config, and model context to inject sequential_thinking preference context when needed |
before_tool_call |
Uses event.toolName, event.toolCallId, and ctx.sessionKey to map tool calls to per-session state |
after_tool_call |
Uses event.toolName and event.toolCallId to remove only the tool-call mapping; session history stays available until session cleanup |
message_sending |
Uses message context sessionKey to purge session state without changing outgoing content |
before_agent_reply |
Defensive purge by sessionKey; does not synthesize or replace the reply |
agent_end |
Observation-only run cleanup by sessionKey |
Additionally, the SDK's api.session.state.registerSessionExtension cleanup callback handles delete, reset, disable, and restart lifecycle events automatically.
Unlike the original MCP server which maintains global state, this plugin isolates thought history per OpenClaw session using the SessionStateManager class:
- Encapsulated Maps:
sessionKeyByToolCallIdandstateBySessionKeyare managed internally - SDK Lifecycle Integration: Registered via
api.session.state.registerSessionExtension()with cleanup callbacks fordelete,reset,disable, andrestartevents - Execute Bridge: In-memory state is required for the
executefunction (tool callbacks have noctxaccess), but cleanup is SDK-driven
State lifecycle: mapped on before_tool_call → used during execute → tool-call mapping removed on after_tool_call → session history purged on SDK cleanup or explicit hook calls (message_sending / before_agent_reply / agent_end).
This plugin is built and tested against openclaw@2026.5.28.
- Uses
definePluginEntrybecause the plugin needs tool registration, SDK hooks, prompt injection, and session state lifecycle integration. - Uses the grouped
api.session.state.registerSessionExtension(...)API introduced in the current SDK surface. - Keeps
activation.onStartup: trueso prompt-injection hooks are registered before agents build prompts. - Keeps
after_tool_callscoped to mapping cleanup only; message/run/session cleanup owns thought history purging.
- Tool Registration: On plugin startup,
registerSequentialThinkingPlugincreates aSequentialThinkingToolinstance and registers it as anAgentToolviaapi.registerTool. - Agent Invocation: When the agent decides to use
sequential_thinking, the tool'sexecutemethod receives the thought parameters, resolves the per-session state, and delegates toprocessThought(). - State Management: Per-session
RunStatemaintains thought history and branch registry, isolated bysessionKey. - Result Streaming: The tool returns a JSON result with
thoughtNumber,totalThoughts,nextThoughtNeeded,branches, andthoughtHistoryLength.
In openclaw.json:
{
"plugins": {
"entries": {
"sequential-thinking": {
"enabled": true,
"config": {
"thoughtLogging": false,
"models": [
"anthropic/claude-sonnet-4",
"google/gemini-3-flash-preview",
"openai/gpt-4o"
]
}
}
}
}
}Facilitates a detailed, step-by-step thinking process for problem-solving and analysis.
Inputs:
thought(string): The current thinking step (must be non-empty)nextThoughtNeeded(boolean): Whether another thought step is neededthoughtNumber(integer): Current thought number (must be positive integer)totalThoughts(integer): Estimated total thoughts needed (must be positive integer)isRevision(boolean, optional): Whether this revises previous thinkingrevisesThought(integer, optional): Which thought is being reconsideredbranchFromThought(integer, optional): Branching point thought numberbranchId(string, optional): Branch identifierneedsMoreThoughts(boolean, optional): If more thoughts are needed
Validation: Invalid inputs (NaN, zero, negative, non-integer, empty strings) are rejected with isError: true.
thoughtLogging(boolean, default:false): Log formatted thoughts to consolemodels(string[], default:[]): Model IDs that should receive a prompt injection encouraging preference forsequential_thinkingon complex problems. Empty strings are automatically filtered out.
| Feature | MCP Server | OpenClaw Plugin |
|---|---|---|
| Protocol | MCP (server.request) |
OpenClaw plugin API (api.registerTool) |
| State scope | Global (single instance) | Per-session (isolated by sessionKey) |
| Configuration | Environment variables (DISABLE_THOUGHT_LOGGING) |
Plugin config (thoughtLogging, models) |
| Prompt injection | None | before_prompt_build hook for targeted models |
| Session lifecycle | N/A | SDK session.state.registerSessionExtension cleanup + hooks |
| Response format | { content: [...], isError? } |
{ content: [...], details: parsed } |
| Input validation | None | Validates thoughtNumber, totalThoughts, thought |
| Type safety | N/A | Strict equality, no as any, additionalProperties: false |
pnpm install
pnpm build # tsc compilation
pnpm typecheck # tsc --noEmit
pnpm test # vitest run
pnpm format # prettiersrc/config.test.ts— Config resolution, defaults, model filtering, empty string handlingsrc/tool.test.ts— SequentialThinkingTool: constructor, processThought (history, branches, revisions, validation), formatThoughtsrc/state.test.ts— SessionStateManager: lifecycle methods, session isolation, SDK cleanup callbacksrc/plugin.test.ts— Plugin registration: SDK hooks, grouped session extension, tool schema, execute bridge, prompt injection, session state
MIT
🌸 Powered by Ani, Wan Jiun Wei © 2026