lotus-wisdom-mcp
Version:
A Model Context Protocol server implementing the Lotus Wisdom framework
284 lines (278 loc) ⢠10.5 kB
JavaScript
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
// Fixed chalk import for ESM
import chalk from 'chalk';
// Lotus Sutra framework tags
const CORE_TAGS = [
// Skillful Means
'upaya', 'expedient', 'direct', 'gradual', 'sudden',
// Non-Dual Recognition
'recognize', 'transform', 'integrate', 'transcend', 'embody',
// Meta-Cognitive
'examine', 'reflect', 'verify', 'refine', 'complete',
// Process Steps
'open', 'engage', 'transform', 'express', 'meditate',
// Output
'OUTPUT'
];
class LotusWisdomServer {
thoughtProcess = [];
finalOutput = '';
validateThoughtData(input) {
const data = input;
if (!data.tag || typeof data.tag !== 'string') {
throw new Error('Invalid tag: must be a string');
}
if (!CORE_TAGS.includes(data.tag)) {
throw new Error(`Invalid tag: ${data.tag}. Must be one of: ${CORE_TAGS.join(', ')}`);
}
if (!data.content || typeof data.content !== 'string') {
throw new Error('Invalid content: must be a string');
}
if (!data.stepNumber || typeof data.stepNumber !== 'number') {
throw new Error('Invalid stepNumber: must be a number');
}
if (!data.totalSteps || typeof data.totalSteps !== 'number') {
throw new Error('Invalid totalSteps: must be a number');
}
if (typeof data.nextStepNeeded !== 'boolean') {
throw new Error('Invalid nextStepNeeded: must be a boolean');
}
// If this is a final output, store it
if (data.tag === 'OUTPUT') {
this.finalOutput = data.content;
}
return {
tag: data.tag,
content: data.content,
stepNumber: data.stepNumber,
totalSteps: data.totalSteps,
nextStepNeeded: data.nextStepNeeded,
isMeditation: data.isMeditation,
meditationDuration: data.meditationDuration,
};
}
formatThought(thoughtData) {
const { tag, stepNumber, totalSteps, content, isMeditation } = thoughtData;
// Color coding for different tag types
let tagColor;
let tagSymbol;
// Skillful Means
if (['upaya', 'expedient', 'direct', 'gradual', 'sudden'].includes(tag)) {
tagColor = chalk.yellow;
tagSymbol = 'š';
}
// Non-Dual Recognition
else if (['recognize', 'transform', 'integrate', 'transcend', 'embody'].includes(tag)) {
tagColor = chalk.green;
tagSymbol = 'āÆļø';
}
// Meta-Cognitive
else if (['examine', 'reflect', 'verify', 'refine', 'complete'].includes(tag)) {
tagColor = chalk.blue;
tagSymbol = 'š§ ';
}
// Process Steps
else if (['open', 'engage', 'express'].includes(tag)) {
tagColor = chalk.magenta;
tagSymbol = 'š';
}
// Meditation
else if (tag === 'meditate') {
tagColor = chalk.cyan;
tagSymbol = 'š§';
}
// Output
else if (tag === 'OUTPUT') {
tagColor = chalk.white.bold;
tagSymbol = 'šø';
}
// Transform (special case since it appears in multiple categories)
else if (tag === 'transform') {
tagColor = chalk.green;
tagSymbol = 'š';
}
else {
tagColor = chalk.white;
tagSymbol = 'š';
}
const header = `${tagSymbol} <${tag}> Step ${stepNumber}/${totalSteps}`;
const formattedHeader = tagColor(header);
let formattedContent;
// Special formatting for meditation
if (isMeditation) {
formattedContent = chalk.cyan(`..........................
[letting thoughts settle into clarity]
..........................
[wisdom naturally emerging]
..........................`);
}
else {
formattedContent = content;
}
// Special formatting for output
if (tag === 'OUTPUT') {
const border = 'ā'.repeat(Math.max(header.length, content.length) + 4);
return `
ā${border}ā
ā ${formattedHeader} ā
ā ${border}ā£
ā ${content.padEnd(border.length - 2)} ā
ā${border}ā
<<<END>>>`;
}
const border = 'ā'.repeat(Math.max(header.length, content.length) + 4);
return `
ā${border}ā
ā ${formattedHeader} ā
ā${border}ā¤
ā ${formattedContent.padEnd(border.length - 2)} ā
ā${border}ā`;
}
processThought(input) {
try {
const validatedInput = this.validateThoughtData(input);
if (validatedInput.stepNumber > validatedInput.totalSteps) {
validatedInput.totalSteps = validatedInput.stepNumber;
}
this.thoughtProcess.push(validatedInput);
const formattedThought = this.formatThought(validatedInput);
console.error(formattedThought);
// Include final output in the response if we're at the end
const includeOutput = !validatedInput.nextStepNeeded && validatedInput.tag === 'OUTPUT';
return {
content: [{
type: "text",
text: JSON.stringify({
stepNumber: validatedInput.stepNumber,
totalSteps: validatedInput.totalSteps,
nextStepNeeded: validatedInput.nextStepNeeded,
tag: validatedInput.tag,
processLength: this.thoughtProcess.length,
finalOutput: includeOutput ? this.finalOutput : undefined
}, null, 2)
}]
};
}
catch (error) {
return {
content: [{
type: "text",
text: JSON.stringify({
error: error instanceof Error ? error.message : String(error),
status: 'failed'
}, null, 2)
}],
isError: true
};
}
}
}
const LOTUS_WISDOM_TOOL = {
name: "lotuswisdom",
description: `A tool for problem-solving using the Lotus Sutra's wisdom framework.
This tool helps analyze problems through multiple approaches while recognizing inherent wisdom.
Each step can utilize different techniques for understanding and expression.
When to use this tool:
- Breaking down complex problems requiring multi-faceted understanding
- Questions that benefit from both direct and gradual approaches
- Problems where apparent contradictions need integration
- Situations requiring both analytical and intuitive understanding
- Tasks that benefit from meditative pauses to allow insight
- Questions containing their own inherent wisdom
Key features:
- Multiple approaches through Skillful Means (upaya, expedient, direct, gradual, sudden)
- Non-Dual Recognition (recognize, transform, integrate, transcend, embody)
- Meta-Cognitive Awareness (examine, reflect, verify, refine, complete)
- Process Steps (open, engage, transform, express)
- Meditative Space (meditate)
- Final Output (OUTPUT)
Process methodology:
1. Initial Opening <open> - Recognize the question's nature
2. Skillful Engagement <engage> - Choose appropriate methods
3. Transformation <transform> - Convert confusion to clarity
4. Natural Expression <express> - Allow understanding to flow
5. Final Integration <OUTPUT> - Present clear, beneficial response
Parameters explained:
- tag: The current processing technique (must be one of the core tags)
- content: The content of the current processing step
- stepNumber: Current number in sequence
- totalSteps: Current estimate of steps needed
- nextStepNeeded: Whether another step is needed
- isMeditation: Whether this step is a meditative pause
- meditationDuration: Optional duration for meditation
Every inquiry concludes with a final <OUTPUT> tag containing the complete response.`,
inputSchema: {
type: "object",
properties: {
tag: {
type: "string",
description: "Current processing technique",
enum: CORE_TAGS
},
content: {
type: "string",
description: "Content of the current processing step"
},
stepNumber: {
type: "integer",
description: "Current step number",
minimum: 1
},
totalSteps: {
type: "integer",
description: "Estimated total steps needed",
minimum: 1
},
nextStepNeeded: {
type: "boolean",
description: "Whether another step is needed"
},
isMeditation: {
type: "boolean",
description: "Whether this step is a meditative pause"
},
meditationDuration: {
type: "integer",
description: "Duration for meditation in seconds",
minimum: 1
}
},
required: ["tag", "content", "stepNumber", "totalSteps", "nextStepNeeded"]
}
};
const server = new Server({
name: "lotus-wisdom-server",
version: "0.1.0",
}, {
capabilities: {
tools: {},
},
});
const wisdomServer = new LotusWisdomServer();
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [LOTUS_WISDOM_TOOL],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "lotuswisdom") {
return wisdomServer.processThought(request.params.arguments);
}
return {
content: [{
type: "text",
text: `Unknown tool: ${request.params.name}`
}],
isError: true
};
});
async function runServer() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Lotus Wisdom MCP Server running on stdio");
}
runServer().catch((error) => {
console.error("Fatal error running server:", error);
process.exit(1);
});