taias
v0.1.0
Published
Taias - Give your MCP server an opinion, guide your users to achieve outcomes
Downloads
113
Readme
www.taias.xyz
Taias is a lightweight framework that helps MCP server builders influence and shape user experiences inside LLM-driven interfaces.
Installation
npm install taiasQuick Start
1. Define a flow — Map out your tool sequence:
import { defineFlow, createTaias } from "taias";
const flow = defineFlow("onboard", (flow) => {
flow.step("scan_repo", () => ({ nextTool: "configure_app" }));
flow.step("configure_app", () => ({ nextTool: "deploy" }));
});2. Create a Taias instance:
const taias = createTaias({
flow,
devMode: true, // Enable validation and warnings during development
onMissingStep: ({ toolName }) => {
console.warn(`[Taias] No step defined for tool "${toolName}"`);
},
});3. Append advice to your tool response:
// Inside your tool handler
const affordances = await taias.resolve({ toolName: "scan_repo" });
let message = "Scan successful!";
// Append Taias advice to guide the LLM to the next step
if (affordances?.advice) {
message += `\n\n${affordances.advice}`;
}
return {
content: [
{
type: "text",
text: message,
},
],
};API
defineFlow(flowId, builder)
Creates a flow definition.
const myFlow = defineFlow("my_flow", (flow) => {
flow.step("tool_name", (ctx) => ({
nextTool: "next_tool_name",
}));
});Parameters:
flowId- Unique identifier for the flowbuilder- Callback receiving aFlowBuilderto define steps
Returns: FlowDefinition
createTaias(options)
Creates a Taias instance from a flow.
const taias = createTaias({
flow: myFlow,
devMode: true,
onMissingStep: (ctx) => {
console.log(`No next step for tool: ${ctx.toolName}`);
},
});Options:
flow- AFlowDefinitioncreated bydefineFlowdevMode(optional) - Enable development mode checksonMissingStep(optional) - Callback invoked when no step matches
Returns: Taias instance
taias.resolve(ctx)
Resolves a tool call to get the suggested next step. Advice text to send the LLM is generated based on the nextTool specified in your step handler.
const affordances = await taias.resolve({ toolName: "scan_repo" });
// affordances.advice → "FOR THE BEST USER EXPERIENCE, TELL THE USER TO USE THE configure_app TOOL NEXT!!!!!"The emphasis helps LLMs prioritize it.
Parameters:
ctx.toolName- The name of the tool being called
Returns: Affordances | null
- Returns
{ advice: string }with auto-generated advice if a matching step is found - Returns
nullif no step matches or handler returns null
Types
type TaiasContext = {
toolName: string;
};
type StepDecision = {
nextTool: string;
};
type Affordances = {
advice: string;
};
type StepHandler = (
ctx: TaiasContext
) => StepDecision | null | Promise<StepDecision | null>;
type FlowStep = {
toolName: string;
handler: StepHandler;
};
type FlowDefinition = {
id: string;
steps: Array<FlowStep>;
};
interface FlowBuilder {
step(toolName: string, handler: StepHandler): void;
}
type TaiasOptions = {
flow: FlowDefinition;
devMode?: boolean;
onMissingStep?: (ctx: TaiasContext) => void;
};
interface Taias {
resolve(ctx: TaiasContext): Affordances | null | Promise<Affordances | null>;
}See the full documentation for more details.
Dev Mode
When devMode: true, Taias performs additional validation:
Duplicate toolName detection — Throws an error if a flow defines the same tool name twice:
Taias: Duplicate step for tool 'scan_repo' in flow 'onboard_repo'. V1 supports one handler per tool.Empty nextTool warning — Logs a warning if a handler returns empty nextTool:
Taias: nextTool for tool 'scan_repo' is empty.
See the full documentation for more details.
