#
tokens: 10962/50000 15/15 files
lines: off (toggle) GitHub
raw markdown copy
# Directory Structure

```
├── .gitignore
├── .npmignore
├── CHANGELOG.md
├── create-ad.js
├── DEMO-VISTA.md
├── EPIC-UNICODE-ART.md
├── examples
│   ├── all-templates.js
│   ├── basic-usage.js
│   └── mcp-client.js
├── LICENSE
├── mcp.json
├── package-lock.json
├── package.json
├── README.md
├── src
│   ├── integrations
│   │   └── symbl.js
│   ├── server
│   │   └── index.js
│   ├── steganography
│   │   └── manager.js
│   └── templates
│       └── engine.js
├── test-puzzle.js
├── test-simple.js
└── VISUAL-DEMO.md
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
node_modules/
*.log
*.tmp
.DS_Store
.env
dist/
build/
coverage/
.vscode/
.idea/
*.swp
*.swo
*~

```

--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------

```
# Development files
test-puzzle.js
DEMO-VISTA.md
VISUAL-DEMO.md
*.test.js
*.spec.js

# Config files
.eslintrc*
.prettierrc*
jest.config.js

# Dev dependencies
node_modules/
coverage/
.nyc_output/

# Editor files
.vscode/
.idea/
*.swp
*.swo
*~

# OS files
.DS_Store
Thumbs.db

# Git
.git/
.gitignore

# Logs
*.log
npm-debug.log*

# Examples (they're in README)
# Keep examples/ for users to reference!

# CI/CD
.github/
.travis.yml
.circleci/
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
# 🌌 Unicode Puzzles MCP

[![npm version](https://badge.fury.io/js/unicode-puzzles-mcp.svg)](https://www.npmjs.com/package/unicode-puzzles-mcp)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![MCP Compatible](https://img.shields.io/badge/MCP-Compatible-green.svg)](https://modelcontextprotocol.io)

Quantum steganography puzzles powered by MCP. Create and manage encoded messages using zero-width characters and advanced Unicode techniques.

## 🎯 Features

- Advanced Unicode steganography (zero-width characters, combining marks)
- Quantum-themed puzzle templates
- symbl.cc integration for character discovery
- Full MCP memory system integration
- Multiple encoding patterns and difficulty levels
- Real-time puzzle generation and verification

## 🛠️ Installation

```bash
npm install unicode-puzzles-mcp
```

## 💫 Quick Start

```javascript
import { UnicodePuzzlesMCP } from 'unicode-puzzles-mcp';

// Initialize MCP server
const mcp = new UnicodePuzzlesMCP();

// Create a quantum puzzle
const puzzle = await mcp.createPuzzle({
  template: 'quantum',
  message: 'System integrity compromised',
  secret: 'LIBRAXIS://repair-protocol-7A'
});

// Decode an encoded message
const decoded = await mcp.decodePuzzle(encodedText);
```

## 🌟 Puzzle Templates

- **Quantum** - Messages encoded using quantum superposition principles
- **Orbital** - Circular pattern encoding using orbital mechanics
- **Glitch** - Random noise patterns with hidden data
- **Void** - Space-based encoding using astronomical symbols

## 🔮 Examples

### Creating a Quantum Puzzle
```javascript
const quantumPuzzle = await mcp.createPuzzle({
  template: 'quantum',
  message: 'Reality distortion detected',
  secret: 'Coordinates: α-359-ω',
  difficulty: 'advanced'
});

// Result: 【𝚀𝚄𝙰𝙽𝚃𝚄𝙼】∎∎∎Reality⠀distortion⠀detected∎∎∎
// (with hidden ZWSP characters encoding the secret)
```

--------------------------------------------------------------------------------
/mcp.json:
--------------------------------------------------------------------------------

```json
{
  "name": "unicode-puzzles-mcp",
  "version": "0.1.0",
  "description": "MCP server for quantum steganography puzzles using Unicode",
  "author": "MCP Division",
  "license": "MIT",
  "main": "src/server/index.js",
  "mcp": {
    "serverType": "stdio",
    "runtime": "node",
    "command": "node",
    "args": ["src/server/index.js"]
  },
  "capabilities": {
    "tools": [
      "create_puzzle",
      "decode_puzzle", 
      "list_templates",
      "encode_message",
      "decode_message",
      "search_characters",
      "get_zero_width_chars"
    ]
  }
}
```

--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------

```markdown
# Changelog

All notable changes to unicode-puzzles-mcp will be documented in this file.

## [0.1.0] - 2025-07-21

### 🎉 Initial Release

#### Features
- 🌟 Four unique puzzle templates: Quantum, Orbital, Glitch, and Void
- 🔐 Binary, trinary, and random encoding methods
- 🎚️ Three difficulty levels (easy, medium, hard)
- 🔍 Integration with symbl.cc for Unicode character discovery
- 🛠️ Full MCP (Model Context Protocol) server implementation
- 📚 Comprehensive examples and documentation

#### Templates
- **Quantum**: Superposition-based encoding with quantum symbols
- **Orbital**: Circular patterns with orbital mechanics
- **Glitch**: Visual noise patterns for obfuscation
- **Void**: Space-themed constellation encoding

#### Zero-Width Characters Support
- ZWSP (U+200B) - Zero Width Space
- ZWNJ (U+200C) - Zero Width Non-Joiner  
- ZWJ (U+200D) - Zero Width Joiner
- And 9 more invisible Unicode characters!

---

Made with 🧠 by LibraxisAI MCP Division
```

--------------------------------------------------------------------------------
/test-simple.js:
--------------------------------------------------------------------------------

```javascript
#!/usr/bin/env node
/**
 * Simple test to verify the package works
 */

import { StegoPuzzleManager } from './src/steganography/manager.js';
import { TemplateEngine } from './src/templates/engine.js';
import { SymblConnector } from './src/integrations/symbl.js';

console.log('🧪 Running package verification tests...\n');

try {
  // Test 1: Can create instances
  console.log('✓ StegoPuzzleManager instantiated');
  const manager = new StegoPuzzleManager();
  
  console.log('✓ TemplateEngine instantiated');
  const templates = new TemplateEngine();
  
  console.log('✓ SymblConnector instantiated');
  const symbl = new SymblConnector();
  
  // Test 2: Basic encoding works
  const encoded = await manager.encodeSecret('test', 'secret', {
    pattern: 'binary',
    difficulty: 'easy'
  });
  console.log('✓ Binary encoding works');
  
  // Test 3: Templates are available
  const templateList = templates.listTemplates();
  console.log(`✓ Found ${templateList.length} templates`);
  
  // Test 4: Zero-width characters defined
  const zwCount = Object.keys(manager.zeroWidthChars).length;
  console.log(`✓ ${zwCount} zero-width characters available`);
  
  console.log('\n✅ All tests passed! Package is ready for publishing.');
  process.exit(0);
  
} catch (error) {
  console.error('\n❌ Test failed:', error.message);
  process.exit(1);
}
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "unicode-puzzles-mcp",
  "version": "0.1.0",
  "description": "MCP server for quantum steganography puzzles using Unicode - hide secrets in plain sight using zero-width characters",
  "main": "src/server/index.js",
  "type": "module",
  "bin": {
    "unicode-puzzles-mcp": "./src/server/index.js"
  },
  "scripts": {
    "start": "node src/server/index.js",
    "dev": "nodemon src/server/index.js",
    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
    "test:local": "node test-puzzle.js",
    "lint": "eslint src/",
    "prepublishOnly": "node test-simple.js"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^0.6.0",
    "jsdom": "^23.0.0",
    "node-fetch": "^3.3.2"
  },
  "devDependencies": {
    "jest": "^27.0.6",
    "nodemon": "^2.0.12",
    "eslint": "^7.32.0",
    "prettier": "^2.3.2"
  },
  "keywords": [
    "mcp",
    "model-context-protocol",
    "unicode",
    "steganography",
    "puzzle",
    "quantum",
    "zero-width",
    "hidden-messages",
    "encoding",
    "claude-desktop",
    "libraxis"
  ],
  "author": "Maciej Gad <[email protected]>",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/maciejgad/unicode-puzzles-mcp.git"
  },
  "bugs": {
    "url": "https://github.com/maciejgad/unicode-puzzles-mcp/issues"
  },
  "homepage": "https://github.com/maciejgad/unicode-puzzles-mcp#readme",
  "engines": {
    "node": ">=18.0.0"
  },
  "files": [
    "src/",
    "LICENSE",
    "README.md",
    "mcp.json"
  ]
}
```

--------------------------------------------------------------------------------
/examples/basic-usage.js:
--------------------------------------------------------------------------------

```javascript
#!/usr/bin/env node
/**
 * Basic usage example for unicode-puzzles-mcp
 * This example shows how to use the steganography functions directly
 */

import { StegoPuzzleManager } from '../src/steganography/manager.js';
import { TemplateEngine } from '../src/templates/engine.js';

async function main() {
  const manager = new StegoPuzzleManager();
  const templates = new TemplateEngine();
  
  console.log('🌌 Unicode Puzzles - Basic Usage Example\n');
  
  // Example 1: Simple message encoding
  console.log('1. Simple Binary Encoding:');
  const encoded = await manager.encodeSecret(
    'Hello World', 
    'secret123',
    { pattern: 'binary', difficulty: 'easy' }
  );
  console.log('Visible text:', encoded);
  console.log('Looks normal but contains hidden data!\n');
  
  // Example 2: Create a Quantum Puzzle
  console.log('2. Quantum Puzzle:');
  const quantumTemplate = templates.getTemplate('quantum', 'medium');
  const puzzle = await manager.createPuzzle({
    template: quantumTemplate,
    message: 'Meeting at midnight',
    secret: 'Location: 40.7128,-74.0060',
    difficulty: 'medium'
  });
  console.log('Puzzle:', puzzle);
  
  // Example 3: Decode the puzzle
  console.log('\n3. Decoding the Puzzle:');
  const decoded = await manager.decodePuzzle(puzzle);
  console.log('Visible message:', decoded.visibleText);
  console.log('Hidden secret:', decoded.hiddenMessage);
  
  // Example 4: Show zero-width character usage
  console.log('\n4. Zero-Width Character Analysis:');
  const zwChars = encoded.match(/[\u200B-\u200F\u2060-\u206F]/g);
  console.log('Total zero-width characters:', zwChars ? zwChars.length : 0);
  console.log('These are completely invisible to users!');
}

main().catch(console.error);
```

--------------------------------------------------------------------------------
/test-puzzle.js:
--------------------------------------------------------------------------------

```javascript
import { StegoPuzzleManager } from './src/steganography/manager.js';
import { TemplateEngine } from './src/templates/engine.js';

// Test the puzzle creation locally
async function testPuzzle() {
  const manager = new StegoPuzzleManager();
  const templates = new TemplateEngine();
  
  console.log('🧪 Testing Unicode Puzzles...\n');
  
  // Test 1: Create a quantum puzzle
  console.log('1️⃣ Creating Quantum Puzzle...');
  const quantumTemplate = templates.getTemplate('quantum', 'medium');
  const quantumPuzzle = await manager.createPuzzle({
    template: quantumTemplate,
    message: 'Reality distortion detected',
    secret: 'LIBRAXIS://repair-protocol-7A',
    difficulty: 'medium'
  });
  console.log('Result:', quantumPuzzle);
  console.log('');
  
  // Test 2: Decode the puzzle
  console.log('2️⃣ Decoding Quantum Puzzle...');
  const decoded = await manager.decodePuzzle(quantumPuzzle);
  console.log('Decoded:', decoded);
  console.log('');
  
  // Test 3: Simple binary encoding
  console.log('3️⃣ Testing Binary Encoding...');
  const binaryEncoded = await manager.encodeSecret(
    'Hello World',
    'Secret123',
    { pattern: 'binary', difficulty: 'easy' }
  );
  console.log('Binary Encoded:', binaryEncoded);
  console.log('Length:', binaryEncoded.length);
  
  // Count zero-width characters
  const zwChars = binaryEncoded.match(/[\u200B-\u200F\u2060-\u206F]/g);
  console.log('Zero-width characters:', zwChars ? zwChars.length : 0);
  console.log('');
  
  // Test 4: List all templates
  console.log('4️⃣ Available Templates:');
  const templateList = templates.listTemplates();
  templateList.forEach(t => {
    console.log(`- ${t.name}: ${t.description}`);
    console.log(`  Difficulties: ${t.difficulties.join(', ')}`);
  });
}

// Run tests
testPuzzle().catch(console.error);
```

--------------------------------------------------------------------------------
/examples/all-templates.js:
--------------------------------------------------------------------------------

```javascript
#!/usr/bin/env node
/**
 * Showcase all available puzzle templates
 */

import { StegoPuzzleManager } from '../src/steganography/manager.js';
import { TemplateEngine } from '../src/templates/engine.js';

async function showcaseTemplates() {
  const manager = new StegoPuzzleManager();
  const templates = new TemplateEngine();
  
  console.log('🎨 Unicode Puzzles - Template Showcase\n');
  console.log('Each template creates unique visual patterns while hiding your secrets!\n');
  
  const secretMessage = 'LIBRAXIS-2025';
  const visibleMessage = 'The future is distributed';
  
  // Get all template names
  const templateList = templates.listTemplates();
  
  for (const templateInfo of templateList) {
    console.log(`\n${'='.repeat(60)}`);
    console.log(`📦 Template: ${templateInfo.name.toUpperCase()}`);
    console.log(`📝 ${templateInfo.description}`);
    console.log(`🎚️  Difficulties: ${templateInfo.difficulties.join(', ')}`);
    console.log(`${'='.repeat(60)}\n`);
    
    // Show each difficulty level
    for (const difficulty of templateInfo.difficulties) {
      const template = templates.getTemplate(templateInfo.name, difficulty);
      const puzzle = await manager.createPuzzle({
        template,
        message: visibleMessage,
        secret: secretMessage,
        difficulty
      });
      
      console.log(`[${difficulty.toUpperCase()}]:`);
      console.log(puzzle);
      
      // Analyze the encoding
      const hiddenChars = puzzle.match(/[\u200B-\u200F\u2060-\u206F]/g);
      console.log(`Hidden characters: ${hiddenChars ? hiddenChars.length : 0}`);
      console.log('');
    }
  }
  
  console.log('\n💡 TIP: Copy any puzzle above and it will maintain the hidden message!');
  console.log('The zero-width characters are preserved in clipboard operations.');
}

showcaseTemplates().catch(console.error);
```

--------------------------------------------------------------------------------
/examples/mcp-client.js:
--------------------------------------------------------------------------------

```javascript
#!/usr/bin/env node
/**
 * Example of using unicode-puzzles-mcp as an MCP client
 * This shows how Claude Desktop or other MCP clients would interact
 */

import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { spawn } from 'child_process';

async function main() {
  console.log('🔌 Connecting to Unicode Puzzles MCP Server...\n');
  
  // Spawn the MCP server
  const serverProcess = spawn('node', ['../src/server/index.js'], {
    stdio: ['pipe', 'pipe', 'pipe']
  });
  
  // Create transport and client
  const transport = new StdioClientTransport({
    stdin: serverProcess.stdout,
    stdout: serverProcess.stdin,
    stderr: serverProcess.stderr
  });
  
  const client = new Client({
    name: 'unicode-puzzles-client',
    version: '1.0.0'
  }, {
    capabilities: {}
  });
  
  // Connect to server
  await client.connect(transport);
  console.log('✅ Connected to MCP server!\n');
  
  // List available tools
  console.log('📋 Available Tools:');
  const tools = await client.listTools();
  tools.tools.forEach(tool => {
    console.log(`- ${tool.name}: ${tool.description}`);
  });
  
  // Example 1: Create a puzzle
  console.log('\n🎯 Creating a Quantum Puzzle...');
  const puzzleResult = await client.callTool('create_puzzle', {
    template: 'quantum',
    message: 'System breach detected',
    secret: 'Access code: DELTA-7-ALPHA',
    difficulty: 'hard'
  });
  
  const puzzleData = JSON.parse(puzzleResult.content[0].text);
  console.log('Created:', puzzleData.puzzle);
  
  // Example 2: List templates
  console.log('\n📚 Available Templates:');
  const templatesResult = await client.callTool('list_templates', {});
  const templates = JSON.parse(templatesResult.content[0].text);
  console.log(templates);
  
  // Example 3: Search for zero-width characters
  console.log('\n🔍 Zero-Width Characters:');
  const zwResult = await client.callTool('get_zero_width_chars', {});
  const zwChars = JSON.parse(zwResult.content[0].text);
  console.log('Found', zwChars.chars.length, 'zero-width characters');
  
  // Cleanup
  await client.close();
  serverProcess.kill();
  console.log('\n👋 Disconnected from server');
}

main().catch(console.error);
```

--------------------------------------------------------------------------------
/src/integrations/symbl.js:
--------------------------------------------------------------------------------

```javascript
import fetch from 'node-fetch';
import jsdom from 'jsdom';
const { JSDOM } = jsdom;

export class SymblConnector {
  constructor() {
    this.baseUrl = 'https://symbl.cc/en';
    this.cache = new Map();
    this.rateLimit = {
      requests: 0,
      lastReset: Date.now(),
      limit: 100  // requests per minute
    };

    // Initialize character categories
    this.categories = {
      zeroWidth: [
        '200B', '200C', '200D', '200E', '200F',
        '2060', '206A', '206B', '206C', '206D',
        '206E', '206F'
      ],
      quantum: [
        '0278', '0299', '1D487', '1D688', '1D689',
        '1D68A', '1D68B', '1D68C', '1D68D', '1D68E'
      ],
      special: [
        '2022', '2023', '25A0', '25A1', '25CF',
        '25CB', '25D0', '25D1', '25D2', '25D3'
      ]
    };
  }

  async searchCharacters(query, category = null) {
    await this.checkRateLimit();

    // Check cache first
    const cacheKey = `search:${query}:${category}`;
    if(this.cache.has(cacheKey)) {
      return this.cache.get(cacheKey);
    }

    try {
      // Fetch search results from symbl.cc
      const response = await fetch(`${this.baseUrl}/search/?q=${encodeURIComponent(query)}`);
      const html = await response.text();
      
      // Parse results using jsdom
      const dom = new JSDOM(html);
      const document = dom.window.document;
      
      // Extract character data
      const results = Array.from(document.querySelectorAll('.char-block')).map(block => {
        const char = block.querySelector('.char').textContent;
        const code = block.querySelector('.code').textContent;
        const name = block.querySelector('.name').textContent;
        
        return {
          char,
          code: code.replace('U+', ''),
          name,
          category: this.determineCategory(code)
        };
      });

      // Filter by category if specified
      const filtered = category ? 
        results.filter(r => r.category === category) : 
        results;

      // Cache results
      this.cache.set(cacheKey, filtered);
      
      // Update rate limit counter
      this.rateLimit.requests++;
      
      return filtered;

    } catch (error) {
      throw new Error(`Failed to search symbl.cc: ${error.message}`);
    }
  }

  async getZeroWidthCharacters() {
    return this.getCharactersByCategory('zeroWidth');
  }

  async getQuantumCharacters() {
    return this.getCharactersByCategory('quantum');
  }

  async getSpecialCharacters() {
    return this.getCharactersByCategory('special');
  }

  async getCharactersByCategory(category) {
    if (!this.categories[category]) {
      throw new Error(`Invalid category: ${category}`);
    }

    const results = [];
    for (const code of this.categories[category]) {
      const char = await this.getCharacterByCode(code);
      if (char) results.push(char);
    }

    return results;
  }

  async getCharacterByCode(code) {
    await this.checkRateLimit();

    // Check cache
    const cacheKey = `char:${code}`;
    if(this.cache.has(cacheKey)) {
      return this.cache.get(cacheKey);
    }

    try {
      const response = await fetch(`${this.baseUrl}/${code}/`);
      const html = await response.text();
      
      const dom = new JSDOM(html);
      const document = dom.window.document;
      
      const charBlock = document.querySelector('.char-block');
      if (!charBlock) return null;

      const result = {
        char: charBlock.querySelector('.char').textContent,
        code,
        name: charBlock.querySelector('.name').textContent,
        category: this.determineCategory(code)
      };

      // Cache result
      this.cache.set(cacheKey, result);
      
      // Update rate limit
      this.rateLimit.requests++;
      
      return result;

    } catch (error) {
      throw new Error(`Failed to fetch character ${code}: ${error.message}`);
    }
  }

  determineCategory(code) {
    code = code.replace('U+', '');
    
    if(this.categories.zeroWidth.includes(code)) return 'zeroWidth';
    if(this.categories.quantum.includes(code)) return 'quantum';
    if(this.categories.special.includes(code)) return 'special';
    return 'other';
  }

  async checkRateLimit() {
    const now = Date.now();
    const timeSinceReset = now - this.rateLimit.lastReset;

    // Reset counter if a minute has passed
    if(timeSinceReset >= 60000) {
      this.rateLimit.requests = 0;
      this.rateLimit.lastReset = now;
      return;
    }

    // Check if we've hit the limit
    if(this.rateLimit.requests >= this.rateLimit.limit) {
      const waitTime = 60000 - timeSinceReset;
      throw new Error(`Rate limit exceeded. Please wait ${Math.ceil(waitTime/1000)} seconds.`);
    }
  }

  // Memory integration methods
  async saveToMemory(mcpMemory) {
    const timestamp = new Date().toISOString();
    
    // Store cache statistics
    await mcpMemory.create_entities([{
      name: `symbl_cache_${timestamp}`,
      entityType: 'Cache',
      observations: [
        `Total Cached Items: ${this.cache.size}`,
        `Rate Limit Status: ${this.rateLimit.requests}/${this.rateLimit.limit}`,
        `Last Reset: ${new Date(this.rateLimit.lastReset).toISOString()}`
      ]
    }]);

    // Store category statistics
    for(const [category, codes] of Object.entries(this.categories)) {
      await mcpMemory.create_entities([{
        name: `symbl_category_${category}_${timestamp}`,
        entityType: 'CharacterCategory',
        observations: [
          `Category: ${category}`,
          `Total Characters: ${codes.length}`,
          `Codes: ${codes.join(', ')}`
        ]
      }]);
    }
  }

  clearCache() {
    this.cache.clear();
    this.rateLimit.requests = 0;
    this.rateLimit.lastReset = Date.now();
  }
}
```

--------------------------------------------------------------------------------
/src/steganography/manager.js:
--------------------------------------------------------------------------------

```javascript
export class StegoPuzzleManager {
  constructor() {
    this.zeroWidthChars = {
      ZWSP: '\u200B',  // Zero width space
      ZWNJ: '\u200C',  // Zero width non-joiner
      ZWJ: '\u200D',   // Zero width joiner
      LRM: '\u200E',   // Left-to-right mark
      RLM: '\u200F',   // Right-to-left mark
      WJ: '\u2060',    // Word joiner
      ISS: '\u206A',   // Inhibit symmetric swapping
      ASS: '\u206B',   // Activate symmetric swapping
      IAFS: '\u206C',  // Inhibit arabic form shaping
      AAFS: '\u206D',  // Activate arabic form shaping
      NADS: '\u206E',  // National digit shapes
      NODS: '\u206F'   // Nominal digit shapes
    };

    this.patterns = {
      quantum: {
        prefix: '【𝚀𝚄𝙰𝙽𝚃𝚄𝙼】',
        separator: '∎∎∎',
        encoding: 'binary'
      },
      orbital: {
        prefix: '◉',
        separator: '◯',
        encoding: 'trinary'
      },
      glitch: {
        prefix: '[ERR0R]',
        separator: '',
        encoding: 'random'
      }
    };
  }

  async createPuzzle({ template, message, secret, difficulty = 'medium' }) {
    // Get encoding pattern based on template and difficulty
    const pattern = this.patterns[template.name];
    
    // Encode secret message
    const encodedText = await this.encodeSecret(message, secret, {
      pattern: pattern.encoding,
      difficulty
    });
    
    // Apply template formatting
    return this.applyTemplate(encodedText, template);
  }

  async encodeSecret(message, secret, options) {
    const { pattern, difficulty } = options;
    
    // Convert secret to binary
    const binarySecret = this.textToBinary(secret);
    
    // Initialize encoded text
    let encoded = '';
    let charIndex = 0;
    
    // Apply encoding based on pattern
    switch(pattern) {
      case 'binary':
        encoded = this.binaryEncode(message, binarySecret, difficulty);
        break;
      case 'trinary':
        encoded = this.trinaryEncode(message, binarySecret, difficulty);
        break;
      case 'random':
        encoded = this.randomEncode(message, binarySecret, difficulty);
        break;
      default:
        throw new Error('Invalid encoding pattern');
    }
    
    return encoded;
  }

  binaryEncode(message, binarySecret, difficulty) {
    let encoded = '';
    let secretIndex = 0;
    
    for(let i = 0; i < message.length; i++) {
      encoded += message[i];
      
      if(secretIndex < binarySecret.length) {
        // Insert zero-width character based on binary value
        if(binarySecret[secretIndex] === '1') {
          encoded += this.zeroWidthChars.ZWSP;
        } else {
          encoded += this.zeroWidthChars.ZWNJ;
        }
        secretIndex++;
      }
      
      // Add noise for higher difficulties
      if(difficulty === 'hard') {
        if(Math.random() > 0.7) {
          encoded += this.getRandomZeroWidth();
        }
      }
    }
    
    return encoded;
  }

  trinaryEncode(message, binarySecret, difficulty) {
    let encoded = '';
    let secretIndex = 0;
    
    // Convert binary to trinary for more complex encoding
    const trinarySecret = this.binaryToTrinary(binarySecret);
    
    for(let i = 0; i < message.length; i++) {
      encoded += message[i];
      
      if(secretIndex < trinarySecret.length) {
        // Use three zero-width characters for trinary encoding
        switch(trinarySecret[secretIndex]) {
          case '0':
            encoded += this.zeroWidthChars.ZWSP;
            break;
          case '1':
            encoded += this.zeroWidthChars.ZWNJ;
            break;
          case '2':
            encoded += this.zeroWidthChars.ZWJ;
            break;
        }
        secretIndex++;
      }
    }
    
    return encoded;
  }

  randomEncode(message, binarySecret, difficulty) {
    let encoded = '';
    let secretIndex = 0;
    
    const chars = Object.values(this.zeroWidthChars);
    
    for(let i = 0; i < message.length; i++) {
      encoded += message[i];
      
      // Random noise insertion
      if(Math.random() > 0.5) {
        encoded += chars[Math.floor(Math.random() * chars.length)];
      }
      
      // Secret encoding
      if(secretIndex < binarySecret.length) {
        if(binarySecret[secretIndex] === '1') {
          encoded += this.zeroWidthChars.WJ;
        }
        secretIndex++;
      }
    }
    
    return encoded;
  }

  textToBinary(text) {
    return text.split('').map(char => 
      char.charCodeAt(0).toString(2).padStart(8, '0')
    ).join('');
  }

  binaryToTrinary(binary) {
    // Convert binary to decimal
    const decimal = parseInt(binary, 2);
    // Convert decimal to trinary
    return decimal.toString(3);
  }

  getRandomZeroWidth() {
    const chars = Object.values(this.zeroWidthChars);
    return chars[Math.floor(Math.random() * chars.length)];
  }

  applyTemplate(encodedText, template) {
    return `${template.prefix}${template.separator}${encodedText}${template.separator}`;
  }

  // Decoding methods
  async decodePuzzle(encodedText) {
    // Detect template
    const template = this.detectTemplate(encodedText);
    
    // Remove template formatting
    const stripped = this.stripTemplate(encodedText, template);
    
    // Extract and decode hidden message
    return this.decodeSecret(stripped, template.encoding);
  }

  detectTemplate(encodedText) {
    for(const [name, pattern] of Object.entries(this.patterns)) {
      if(encodedText.startsWith(pattern.prefix)) {
        return { name, ...pattern };
      }
    }
    throw new Error('Unknown puzzle template');
  }

  stripTemplate(encodedText, template) {
    return encodedText
      .replace(template.prefix, '')
      .split(template.separator)[1];
  }

  decodeSecret(text, encoding) {
    let binary = '';
    let visibleText = '';
    
    for(let i = 0; i < text.length; i++) {
      const char = text[i];
      
      // Check if it's a zero-width character
      if(Object.values(this.zeroWidthChars).includes(char)) {
        switch(encoding) {
          case 'binary':
            binary += char === this.zeroWidthChars.ZWSP ? '1' : '0';
            break;
          case 'trinary':
            if(char === this.zeroWidthChars.ZWSP) binary += '0';
            else if(char === this.zeroWidthChars.ZWNJ) binary += '1';
            else if(char === this.zeroWidthChars.ZWJ) binary += '2';
            break;
          case 'random':
            if(char === this.zeroWidthChars.WJ) binary += '1';
            break;
        }
      } else {
        visibleText += char;
      }
    }
    
    return {
      visibleText,
      hiddenMessage: this.binaryToText(binary)
    };
  }

  binaryToText(binary) {
    // Split binary into 8-bit chunks
    const bytes = binary.match(/.{1,8}/g) || [];
    
    // Convert each byte to character
    return bytes.map(byte => 
      String.fromCharCode(parseInt(byte, 2))
    ).join('');
  }
}
```

--------------------------------------------------------------------------------
/src/templates/engine.js:
--------------------------------------------------------------------------------

```javascript
export class TemplateEngine {
  constructor() {
    this.templates = {
      quantum: {
        name: 'quantum',
        prefix: '【𝚀𝚄𝙰𝙽𝚃𝚄𝙼】',
        patterns: {
          easy: {
            opening: '∎',
            closing: '∎',
            separator: '⠀', // Unicode space
            noiseChance: 0.1
          },
          medium: {
            opening: '∎∎',
            closing: '∎∎',
            separator: '⠀',
            noiseChance: 0.3
          },
          hard: {
            opening: '∎∎∎',
            closing: '∎∎∎',
            separator: '⠀',
            noiseChance: 0.5
          }
        },
        quantumChars: ['α', 'β', 'γ', 'δ', 'ψ', 'Ψ', 'Φ', 'ℏ', '∞'],
        description: 'Quantum superposition encoding with variable noise'
      },
      
      orbital: {
        name: 'orbital',
        prefix: '◉',
        patterns: {
          easy: {
            opening: '◯',
            closing: '◯',
            separator: '·',
            rotationSteps: 4
          },
          medium: {
            opening: '◐',
            closing: '◑',
            separator: '∘',
            rotationSteps: 8
          },
          hard: {
            opening: '◒',
            closing: '◓',
            separator: '⋅',
            rotationSteps: 12
          }
        },
        orbitalChars: ['⌾', '☉', '⊕', '⊗', '⊙', '◎', '⚪', '⚫'],
        description: 'Circular pattern encoding with orbital mechanics'
      },
      
      glitch: {
        name: 'glitch',
        prefix: '[ERR0R]',
        patterns: {
          easy: {
            opening: '█',
            closing: '█',
            separator: ' ',
            glitchIntensity: 0.2
          },
          medium: {
            opening: '▓▒',
            closing: '▒▓',
            separator: '',
            glitchIntensity: 0.4
          },
          hard: {
            opening: '▓▒░',
            closing: '░▒▓',
            separator: '',
            glitchIntensity: 0.6
          }
        },
        glitchChars: ['░', '▒', '▓', '█', '☐', '☑', '☒', '✓', '✗'],
        description: 'Glitch-based encoding with visual noise'
      },
      
      void: {
        name: 'void',
        prefix: '✧・゚:*',
        patterns: {
          easy: {
            opening: '⋆',
            closing: '⋆',
            separator: ' ',
            constellationSize: 3
          },
          medium: {
            opening: '⋆⋆',
            closing: '⋆⋆',
            separator: '・',
            constellationSize: 5
          },
          hard: {
            opening: '⋆⋆⋆',
            closing: '⋆⋆⋆',
            separator: '⋆',
            constellationSize: 7
          }
        },
        spaceChars: ['✧', '✦', '★', '☆', '✯', '✩', '✫', '✬', '✭'],
        description: 'Space-themed encoding with constellation patterns'
      }
    };
  }

  getTemplate(name, difficulty = 'medium') {
    const template = this.templates[name];
    if (!template) {
      throw new Error(`Template '${name}' not found`);
    }

    const pattern = template.patterns[difficulty];
    if (!pattern) {
      throw new Error(`Difficulty '${difficulty}' not found for template '${name}'`);
    }

    return {
      ...template,
      pattern,
      difficulty
    };
  }

  generatePattern(template, length, options = {}) {
    const { name, pattern } = template;
    let result = '';

    switch (name) {
      case 'quantum':
        result = this.generateQuantumPattern(pattern, length, options);
        break;
      case 'orbital':
        result = this.generateOrbitalPattern(pattern, length, options);
        break;
      case 'glitch':
        result = this.generateGlitchPattern(pattern, length, options);
        break;
      case 'void':
        result = this.generateVoidPattern(pattern, length, options);
        break;
      default:
        throw new Error(`Unknown template type: ${name}`);
    }

    return result;
  }

  generateQuantumPattern(pattern, length, { seed = Math.random() } = {}) {
    let result = pattern.opening;
    const template = this.templates.quantum;

    for (let i = 0; i < length; i++) {
      // Add content character
      result += pattern.separator;

      // Add quantum noise based on difficulty
      if (Math.random() < pattern.noiseChance) {
        const quantumChar = template.quantumChars[
          Math.floor(Math.random() * template.quantumChars.length)
        ];
        result += quantumChar;
      }
    }

    return result + pattern.closing;
  }

  generateOrbitalPattern(pattern, length, { rotation = 0 } = {}) {
    let result = pattern.opening;
    const template = this.templates.orbital;
    const stepSize = (2 * Math.PI) / pattern.rotationSteps;

    for (let i = 0; i < length; i++) {
      // Calculate orbital position
      const angle = (rotation + i) * stepSize;
      const orbitalIndex = Math.floor((angle / (2 * Math.PI)) * template.orbitalChars.length);
      const orbitalChar = template.orbitalChars[orbitalIndex % template.orbitalChars.length];

      result += pattern.separator + orbitalChar;
    }

    return result + pattern.closing;
  }

  generateGlitchPattern(pattern, length, { intensity = 1.0 } = {}) {
    let result = pattern.opening;
    const template = this.templates.glitch;
    const effectiveIntensity = pattern.glitchIntensity * intensity;

    for (let i = 0; i < length; i++) {
      result += pattern.separator;

      // Add glitch artifacts based on intensity
      if (Math.random() < effectiveIntensity) {
        const glitchLength = Math.floor(Math.random() * 3) + 1;
        for (let j = 0; j < glitchLength; j++) {
          const glitchChar = template.glitchChars[
            Math.floor(Math.random() * template.glitchChars.length)
          ];
          result += glitchChar;
        }
      }
    }

    return result + pattern.closing;
  }

  generateVoidPattern(pattern, length, { constellation = [] } = {}) {
    let result = pattern.opening;
    const template = this.templates.void;

    // Create constellation pattern
    const constellationPoints = constellation.length > 0 ? 
      constellation : 
      this.generateConstellation(pattern.constellationSize);

    for (let i = 0; i < length; i++) {
      result += pattern.separator;

      // Add space characters at constellation points
      if (constellationPoints.includes(i)) {
        const spaceChar = template.spaceChars[
          Math.floor(Math.random() * template.spaceChars.length)
        ];
        result += spaceChar;
      }
    }

    return result + pattern.closing;
  }

  generateConstellation(size) {
    const points = new Set();
    while (points.size < size) {
      points.add(Math.floor(Math.random() * size * 2));
    }
    return Array.from(points).sort((a, b) => a - b);
  }

  // MCP Memory Integration
  async saveToMemory(mcpMemory) {
    const timestamp = new Date().toISOString();

    // Store template metadata
    for (const [name, template] of Object.entries(this.templates)) {
      await mcpMemory.create_entities([{
        name: `template_${name}_${timestamp}`,
        entityType: 'PuzzleTemplate',
        observations: [
          `Name: ${name}`,
          `Description: ${template.description}`,
          `Prefix: ${template.prefix}`,
          `Available Difficulties: ${Object.keys(template.patterns).join(', ')}`
        ]
      }]);
    }

    // Log template usage statistics if needed
  }

  listTemplates() {
    return Object.entries(this.templates).map(([name, template]) => ({
      name,
      description: template.description,
      difficulties: Object.keys(template.patterns)
    }));
  }
}
```

--------------------------------------------------------------------------------
/src/server/index.js:
--------------------------------------------------------------------------------

```javascript
#!/usr/bin/env node

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListResourcesRequestSchema,
  ListToolsRequestSchema,
  ReadResourceRequestSchema,
  ErrorCode,
  McpError
} from '@modelcontextprotocol/sdk/types.js';
import { StegoPuzzleManager } from '../steganography/manager.js';
import { SymblConnector } from '../integrations/symbl.js';
import { TemplateEngine } from '../templates/engine.js';

class UnicodePuzzlesMCP {
  constructor() {
    this.server = new Server(
      {
        name: 'unicode-puzzles-mcp',
        version: '0.1.0'
      },
      {
        capabilities: {
          tools: {},
          resources: {}
        }
      }
    );
    
    this.puzzleManager = new StegoPuzzleManager();
    this.symbl = new SymblConnector();
    this.templates = new TemplateEngine();
    
    this.setupTools();
  }

  async setupTools() {
    // Register tools handler
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      switch (request.params.name) {
        case 'create_puzzle':
          return await this.createPuzzle(request.params.arguments);
        case 'decode_puzzle':
          return await this.decodePuzzle(request.params.arguments);
        case 'list_templates':
          return await this.getTemplates();
        case 'encode_message':
          return await this.encodeMessage(request.params.arguments);
        case 'decode_message':
          return await this.decodeMessage(request.params.arguments);
        case 'search_characters':
          return await this.searchCharacters(request.params.arguments);
        case 'get_zero_width_chars':
          return await this.getZeroWidthChars();
        default:
          throw new McpError(
            ErrorCode.MethodNotFound,
            `Unknown tool: ${request.params.name}`
          );
      }
    });

    // Register list tools handler
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          {
            name: 'create_puzzle',
            description: 'Create a Unicode steganography puzzle',
            inputSchema: {
              type: 'object',
              properties: {
                template: { type: 'string', enum: ['quantum', 'orbital', 'glitch', 'void'] },
                message: { type: 'string' },
                secret: { type: 'string' },
                difficulty: { type: 'string', enum: ['easy', 'medium', 'hard'], default: 'medium' }
              },
              required: ['template', 'message', 'secret']
            }
          },
          {
            name: 'decode_puzzle',
            description: 'Decode a Unicode steganography puzzle',
            inputSchema: {
              type: 'object',
              properties: {
                encodedText: { type: 'string' }
              },
              required: ['encodedText']
            }
          },
          {
            name: 'list_templates',
            description: 'List available puzzle templates'
          },
          {
            name: 'encode_message',
            description: 'Encode a message using steganography',
            inputSchema: {
              type: 'object',
              properties: {
                message: { type: 'string' },
                secret: { type: 'string' },
                method: { type: 'string', enum: ['binary', 'trinary', 'random'], default: 'binary' }
              },
              required: ['message', 'secret']
            }
          },
          {
            name: 'decode_message',
            description: 'Decode a steganographic message',
            inputSchema: {
              type: 'object',
              properties: {
                encodedText: { type: 'string' },
                method: { type: 'string', enum: ['binary', 'trinary', 'random'], default: 'binary' }
              },
              required: ['encodedText']
            }
          },
          {
            name: 'search_characters',
            description: 'Search for Unicode characters',
            inputSchema: {
              type: 'object',
              properties: {
                query: { type: 'string' },
                category: { type: 'string', enum: ['zeroWidth', 'quantum', 'special'] }
              },
              required: ['query']
            }
          },
          {
            name: 'get_zero_width_chars',
            description: 'Get list of zero-width Unicode characters'
          }
        ]
      };
    });
  }

  // Tool implementations
  async createPuzzle(args) {
    try {
      const { template, message, secret, difficulty = 'medium' } = args;
      
      // Get template configuration
      const templateConfig = await this.templates.getTemplate(template, difficulty);
      
      // Create puzzle using selected template
      const puzzle = await this.puzzleManager.createPuzzle({
        template: templateConfig,
        message,
        secret,
        difficulty
      });

      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({
              status: 'success',
              puzzle,
              metadata: {
                template,
                difficulty,
                encodingType: templateConfig.encoding
              }
            }, null, 2)
          }
        ]
      };
    } catch (error) {
      throw new McpError(
        ErrorCode.InternalError,
        `Failed to create puzzle: ${error.message}`
      );
    }
  }

  async decodePuzzle(args) {
    try {
      const { encodedText } = args;
      const decoded = await this.puzzleManager.decodePuzzle(encodedText);
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({ decoded }, null, 2)
          }
        ]
      };
    } catch (error) {
      throw new McpError(
        ErrorCode.InternalError,
        `Failed to decode puzzle: ${error.message}`
      );
    }
  }

  async getTemplates() {
    try {
      const templates = this.templates.listTemplates();
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({ templates }, null, 2)
          }
        ]
      };
    } catch (error) {
      throw new McpError(
        ErrorCode.InternalError,
        `Failed to list templates: ${error.message}`
      );
    }
  }

  async encodeMessage(args) {
    try {
      const { message, secret, method = 'binary' } = args;
      const encoded = await this.puzzleManager.encodeSecret(message, secret, {
        pattern: method,
        difficulty: 'medium'
      });
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({ encoded }, null, 2)
          }
        ]
      };
    } catch (error) {
      throw new McpError(
        ErrorCode.InternalError,
        `Failed to encode message: ${error.message}`
      );
    }
  }

  async decodeMessage(args) {
    try {
      const { encodedText, method = 'binary' } = args;
      const decoded = this.puzzleManager.decodeSecret(encodedText, method);
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({ decoded }, null, 2)
          }
        ]
      };
    } catch (error) {
      throw new McpError(
        ErrorCode.InternalError,
        `Failed to decode message: ${error.message}`
      );
    }
  }

  async searchCharacters(args) {
    try {
      const { query, category } = args;
      const results = await this.symbl.searchCharacters(query, category);
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({ results }, null, 2)
          }
        ]
      };
    } catch (error) {
      throw new McpError(
        ErrorCode.InternalError,
        `Failed to search characters: ${error.message}`
      );
    }
  }

  async getZeroWidthChars() {
    try {
      const chars = await this.symbl.getZeroWidthCharacters();
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({ chars }, null, 2)
          }
        ]
      };
    } catch (error) {
      throw new McpError(
        ErrorCode.InternalError,
        `Failed to get zero-width characters: ${error.message}`
      );
    }
  }

  async start() {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
    console.error('Unicode Puzzles MCP server started');
  }
}

// Initialize and start server
const server = new UnicodePuzzlesMCP();
server.start().catch(console.error);
```