Skip to main content
Glama
orneryd

M.I.M.I.R - Multi-agent Intelligent Memory & Insight Repository

by orneryd
pctx-tool.ts4.78 kB
/** * PCTX Tool for LangChain Agents * * Allows agents to execute TypeScript code in PCTX sandbox with access to all Mimir tools */ import { DynamicStructuredTool } from '@langchain/core/tools'; import { z } from 'zod'; /** * Create PCTX execution tool * * This tool allows agents to write TypeScript code that executes in PCTX's Deno sandbox. * The code has access to all Mimir functions via the `Mimir` namespace. * * Benefits: * - 90-98% token reduction for multi-step operations * - Type-safe TypeScript execution * - All 13 Mimir tools available * - Batch operations in single call */ export function createPCTXTool(pctxUrl: string) { return new DynamicStructuredTool({ name: 'execute_pctx_code', description: `Execute TypeScript code in PCTX sandbox with access to all Mimir functions. Use this for multi-step operations to save 90-98% tokens. Available Mimir functions: - Mimir.memoryNode({operation, type, properties, ...}) - Create/read/update/delete nodes - Mimir.memoryEdge({operation, source, target, type, ...}) - Create/manage relationships - Mimir.memoryBatch({operation, nodes, updates, ...}) - Batch operations - Mimir.vectorSearchNodes({query, types, limit, ...}) - Semantic search - Mimir.todo({operation, title, status, ...}) - Task management - Mimir.todoList({operation, title, ...}) - Task lists - Mimir.indexFolder({path, ...}) - Index files - Mimir.listFolders() - List indexed folders - Mimir.getEmbeddingStats() - Embedding statistics Example usage: \`\`\`typescript // Search and batch update const results = await Mimir.vectorSearchNodes({ query: "pending tasks", types: ["todo"], limit: 10 }); const pending = results.results.filter(r => r.properties.status === "pending"); await Mimir.memoryBatch({ operation: "update_nodes", updates: pending.map(r => ({ id: r.id, properties: { status: "in_progress" } })) }); return { updated: pending.length }; \`\`\` Use this when you need to: - Perform multiple Mimir operations - Filter/transform data without LLM round-trips - Batch updates - Complex graph traversals`, schema: z.object({ code: z.string().describe('TypeScript code to execute. Must define async function run() that returns a result.'), }), func: async ({ code }) => { try { // Call PCTX to execute the code const response = await fetch(`${pctxUrl}/mcp`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream', 'mcp-session-id': `agent-${Date.now()}`, }, body: JSON.stringify({ jsonrpc: '2.0', method: 'tools/call', params: { name: 'execute', arguments: { code } }, id: Date.now() }) }); if (!response.ok) { throw new Error(`PCTX request failed: ${response.status} ${response.statusText}`); } // Parse SSE response const text = await response.text(); const events = text.split('\n') .filter(line => line.startsWith('data: ')) .map(line => JSON.parse(line.substring(6))); const finalEvent = events[events.length - 1]; if (!finalEvent?.result?.content?.[0]?.text) { throw new Error('No result from PCTX execution'); } const resultText = finalEvent.result.content[0].text; // Parse PCTX response format: "Code Executed Successfully: true\n\n# Return Value\n```json\n{...}\n```" const jsonMatch = resultText.match(/```json\s*\n([\s\S]*?)\n```/); if (jsonMatch) { const result = JSON.parse(jsonMatch[1]); return JSON.stringify(result, null, 2); } // Check for execution failure if (resultText.includes('Code Executed Successfully: false')) { const stderrMatch = resultText.match(/# STDERR\s*\n([\s\S]*?)(\n#|$)/); const stderr = stderrMatch ? stderrMatch[1].trim() : 'Unknown error'; throw new Error(`PCTX execution failed: ${stderr}`); } return resultText; } catch (error: any) { return `Error executing PCTX code: ${error.message}`; } }, }); } /** * Check if PCTX is configured and available */ export async function isPCTXAvailable(pctxUrl?: string): Promise<boolean> { if (!pctxUrl) { return false; } try { const response = await fetch(`${pctxUrl}/mcp`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', method: 'tools/list', id: 1 }) }); return response.ok; } catch { return false; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/orneryd/Mimir'

If you have feedback or need assistance with the MCP directory API, please join our Discord server