Use Today with the Core SDK
The core beliefs package works with the Anthropic SDK right now. Wrap your agent calls with before/after:
1import Anthropic from '@anthropic-ai/sdk'
2import Beliefs from 'beliefs'
3
4const client = new Anthropic()
5const beliefs = new Beliefs({
6 apiKey: process.env.BELIEFS_KEY,
7 agent: 'research-agent',
8 namespace: 'claude-sdk',
9 writeScope: 'space',
10})
11
12async function research(question: string) {
13 const context = await beliefs.before(question)
14
15 const message = await client.messages.create({
16 model: 'claude-sonnet-4-20250514',
17 max_tokens: 4096,
18 system: context.prompt,
19 messages: [{ role: 'user', content: question }],
20 })
21
22 const text = message.content
23 .filter(b => b.type === 'text')
24 .map(b => b.text)
25 .join('')
26
27 const delta = await beliefs.after(text)
28 return { text, delta }
29}With Tool Results
When your agent uses tools, feed each tool result separately so beliefs update mid-turn:
1const context = await beliefs.before(question)
2
3const message = await client.messages.create({
4 model: 'claude-sonnet-4-20250514',
5 max_tokens: 4096,
6 system: context.prompt,
7 messages: [{ role: 'user', content: question }],
8 tools: myTools,
9})
10
11for (const block of message.content) {
12 if (block.type === 'tool_use') {
13 const result = await executeTool(block.name, block.input)
14 await beliefs.after(JSON.stringify(result), { tool: block.name })
15 } else if (block.type === 'text') {
16 await beliefs.after(block.text)
17 }
18}Multi-Turn Loop
Run multiple turns and let clarity drive when to stop:
1async function deepResearch(question: string) {
2 for (let turn = 0; turn < 10; turn++) {
3 const context = await beliefs.before(question)
4
5 if (context.clarity > 0.8) {
6 return context.beliefs
7 }
8
9 const message = await client.messages.create({
10 model: 'claude-sonnet-4-20250514',
11 max_tokens: 4096,
12 system: context.prompt,
13 messages: [{ role: 'user', content: question }],
14 })
15
16 const text = message.content
17 .filter(b => b.type === 'text')
18 .map(b => b.text)
19 .join('')
20
21 await beliefs.after(text)
22 }
23}Hooks Adapter
1npm i beliefsThe adapter integrates with the Claude Agent SDK's hook system. It captures tool results via PostToolUse hooks and injects belief context at SessionStart:
1import { query } from '@anthropic-ai/claude-agent-sdk'
2import Beliefs from 'beliefs'
3import { beliefsHooks } from 'beliefs/claude-agent-sdk'
4
5const beliefs = new Beliefs({
6 apiKey: process.env.BELIEFS_KEY,
7 agent: 'research-agent',
8 namespace: 'claude-sdk',
9 writeScope: 'thread',
10})
11
12// Pass hooks to the Claude Agent SDK query options
13const result = await query({
14 prompt: 'Research the competitive landscape for AI dev tools',
15 options: {
16 hooks: beliefsHooks(beliefs),
17 },
18})beliefsHooks registers:
SessionStart— callsbeliefs.before()and injects context viaadditionalContextPostToolUse— callsbeliefs.after(toolResult, {tool})for each tool invocation
If the client is thread-scoped, beliefsHooks() resolves the thread automatically from Claude's session_id by default.
Capture Modes
1beliefsHooks(beliefs, { capture: 'tools' }) // each tool call result (default)
2beliefsHooks(beliefs, { capture: 'all' }) // tool results + text responsesConfiguration
1beliefsHooks(beliefs, {
2 capture: 'all',
3 includeContext: true,
4 toolFilter: 'search|Read', // regex to filter which tools trigger extraction
5})| Option | Default | Description |
|---|---|---|
capture | 'tools' | What to extract beliefs from |
includeContext | true | Inject belief context at session start |
toolFilter | — | Regex to filter which tools trigger extraction |
resolveThreadId | input.session_id | Override how thread IDs are derived for thread-scoped memory |
Choosing a scope
Use writeScope: 'thread' when each Claude session should keep its own memory. Use writeScope: 'space' when all sessions in a namespace should share one state.