MCP Database Access
Use the Sqlite component to let Claude query databases.Code
Copy
Ask AI
#!/usr/bin/env bun
import {
createSmithersRoot,
createSmithersDB,
SmithersProvider,
Claude,
Sqlite,
} from "smithers-orchestrator";
async function main() {
const db = await createSmithersDB({ path: ".smithers/data-analysis" });
const executionId = await db.execution.start("Data Analysis", "data-analysis.tsx");
function DataAnalysis() {
return (
<SmithersProvider db={db} executionId={executionId}>
<Claude
model="sonnet"
maxTurns={10}
onFinished={(result) => {
console.log("Analysis complete!");
console.log(result.output);
}}
>
<Sqlite path="./ecommerce.db" readOnly>
E-commerce database with the following schema:
users(id, name, email, created_at, country)
orders(id, user_id, total, status, created_at)
order_items(id, order_id, product_id, quantity, price)
products(id, name, category, price, stock)
</Sqlite>
Generate a comprehensive business report:
1. Revenue Analysis
- Total revenue by month (last 12 months)
- Revenue by product category
- Average order value trends
2. Customer Analysis
- Top 10 customers by lifetime value
- Customer acquisition by country
- Repeat customer rate
3. Product Performance
- Best selling products
- Products with low stock
- Category performance comparison
Save the report as a markdown file: reports/business-report.md
</Claude>
</SmithersProvider>
);
}
try {
const root = createSmithersRoot();
await root.mount(DataAnalysis);
await db.execution.complete(executionId, {
summary: "Data analysis complete",
});
} catch (err) {
const error = err instanceof Error ? err : new Error(String(err));
await db.execution.fail(executionId, error.message);
throw error;
} finally {
await db.close();
}
}
main();
If you restrict
allowedTools, include any MCP tools you need (for Sqlite, allow sqlite), or omit allowedTools to avoid blocking DB access.Multiple Databases
Copy
Ask AI
<Claude model="sonnet" maxTurns={15}>
<Sqlite path="./users.db" readOnly>
User database: users, profiles, preferences
</Sqlite>
<Sqlite path="./analytics.db" readOnly>
Analytics database: events, sessions, pageviews
</Sqlite>
Cross-reference data between the two databases:
1. Find users who signed up but never logged an event
2. Identify most active users by session count
3. Correlate user preferences with behavior patterns
</Claude>
Read-Only for Safety
Copy
Ask AI
<Sqlite path="./production.db" readOnly>
Production database - read-only access for safety.
</Sqlite>
Workflow with Database
Excerpt: renderDataWorkflow inside a SmithersProvider that supplies db and executionId.
Copy
Ask AI
import { Claude, If, Sqlite, useSmithers } from "smithers-orchestrator";
import { useQueryValue } from "smithers-orchestrator/reactive-sqlite";
function DataWorkflow() {
const { db, reactiveDb } = useSmithers();
const { data: phase } = useQueryValue<string>(
reactiveDb,
"SELECT value FROM state WHERE key = 'phase'"
);
const currentPhase = phase ?? "analyze";
const setPhase = (newPhase: string) => {
db.state.set("phase", newPhase);
};
return (
<>
<If condition={currentPhase === "analyze"}>
<Claude
model="sonnet"
onFinished={(result) => {
db.state.set("findings", result.output);
setPhase("report");
}}
>
<Sqlite path="./data.db" readOnly>
Sales database.
</Sqlite>
Analyze Q4 sales performance.
</Claude>
</If>
<If condition={currentPhase === "report"}>
<Claude
allowedTools={["Write"]}
onFinished={() => setPhase("done")}
>
Create a formatted report from these findings:
{db.state.get("findings")}
Save to reports/q4-analysis.md
</Claude>
</If>
</>
);
}