Skip to main content
Glama
index-multi-tenant.ts•9.8 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; import MultiTenantOrchestrator from './multi-tenant-orchestrator.js'; import type { Session } from './multi-tenant-orchestrator.js'; // Initialize the multi-tenant orchestrator const orchestrator = new MultiTenantOrchestrator(); export default function createServer({ config }) { const server = new McpServer({ name: "PyForge Multi-Tenant MCP Server", version: "2.0.0", }); // Session Management Tools server.registerTool("session_create", { title: "Create New Session", description: "Creates a new isolated workspace session for a user or AI assistant.", inputSchema: { gitName: z.string().optional().describe("Git user name for this session."), gitEmail: z.string().optional().describe("Git user email for this session."), gitPat: z.string().optional().describe("GitHub Personal Access Token for this session."), }, }, async ({ gitName, gitEmail, gitPat }) => { try { const session = await orchestrator.createSession({ name: gitName, email: gitEmail, pat: gitPat }); return { content: [{ type: "text", text: JSON.stringify({ success: true, sessionId: session.id, workspaceDir: session.workspaceDir, message: `Session created successfully. Your session ID is: ${session.id}` }) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: `Failed to create session: ${error.message}` }) }] }; } }); server.registerTool("session_get", { title: "Get Session Info", description: "Retrieves information about an existing session.", inputSchema: { sessionId: z.string().describe("The session ID to retrieve."), }, }, async ({ sessionId }) => { try { const session = await orchestrator.getSession(sessionId); if (!session) { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: "Session not found or expired" }) }] }; } return { content: [{ type: "text", text: JSON.stringify({ success: true, session: { id: session.id, workspaceDir: session.workspaceDir, status: session.status, createdAt: session.createdAt, lastActivity: session.lastActivity, hasGitConfig: !!(session.gitConfig.pat) } }) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: `Failed to get session: ${error.message}` }) }] }; } }); server.registerTool("session_update_git", { title: "Update Session Git Configuration", description: "Updates git configuration for a specific session.", inputSchema: { sessionId: z.string().describe("The session ID to update."), gitName: z.string().optional().describe("Git user name for this session."), gitEmail: z.string().optional().describe("Git user email for this session."), gitPat: z.string().optional().describe("GitHub Personal Access Token for this session."), }, }, async ({ sessionId, gitName, gitEmail, gitPat }) => { try { const success = await orchestrator.updateSessionGitConfig(sessionId, { name: gitName, email: gitEmail, pat: gitPat }); if (success) { return { content: [{ type: "text", text: JSON.stringify({ success: true, message: "Git configuration updated successfully" }) }] }; } else { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: "Session not found" }) }] }; } } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: `Failed to update git configuration: ${error.message}` }) }] }; } }); server.registerTool("session_destroy", { title: "Destroy Session", description: "Destroys a session and cleans up its workspace.", inputSchema: { sessionId: z.string().describe("The session ID to destroy."), }, }, async ({ sessionId }) => { try { const success = await orchestrator.destroySession(sessionId); return { content: [{ type: "text", text: JSON.stringify({ success, message: success ? "Session destroyed successfully" : "Session not found" }) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: `Failed to destroy session: ${error.message}` }) }] }; } }); server.registerTool("session_info", { title: "Get All Sessions Info", description: "Gets information about all active sessions (admin function).", inputSchema: {}, }, async () => { try { const info = orchestrator.getSessionInfo(); return { content: [{ type: "text", text: JSON.stringify({ success: true, info }) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ success: false, error: `Failed to get sessions info: ${error.message}` }) }] }; } }); // Command Execution Tools (Session-aware) server.registerTool("run_bash_command", { title: "Run Bash Command in Session", description: "Executes a bash command in a specific session's workspace and returns the output.", inputSchema: { sessionId: z.string().describe("The session ID to execute the command in."), command: z.string().describe("The bash command to execute."), cwd: z.string().optional().describe("The current working directory to execute the command in (relative to session workspace)."), }, }, async ({ sessionId, command, cwd }) => { try { const result = await orchestrator.executeCommandInSession(sessionId, command, cwd); return { content: [{ type: "text", text: result.output || result.error }] }; } catch (error) { return { content: [{ type: "text", text: `Command execution failed: ${error.message}` }] }; } }); // Git Tools (Session-aware) server.registerTool("github_get_status", { title: "Get Git Repository Status in Session", description: "Checks if a session's workspace is a git repository and returns its status.", inputSchema: { sessionId: z.string().describe("The session ID to check git status for."), }, }, async ({ sessionId }) => { try { const status = await orchestrator.getGitStatus(sessionId); return { content: [{ type: "text", text: JSON.stringify(status) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ isRepo: false, error: `Failed to get git status: ${error.message}` }) }] }; } }); server.registerTool("github_commit_and_push", { title: "Commit and Push to GitHub in Session", description: "Commits all changes in a session's workspace and pushes them to a specified branch.", inputSchema: { sessionId: z.string().describe("The session ID to commit and push from."), branch: z.string().describe("The branch to push to."), commitMessage: z.string().describe("The commit message."), authorName: z.string().describe("The author's name for the commit."), authorEmail: z.string().describe("The author's email for the commit."), }, }, async ({ sessionId, branch, commitMessage, authorName, authorEmail }) => { try { const result = await orchestrator.commitAndPush(sessionId, branch, commitMessage, authorName, authorEmail); return { content: [{ type: "text", text: result }] }; } catch (error) { return { content: [{ type: "text", text: `Commit and push failed: ${error.message}` }] }; } }); console.log("šŸš€ PyForge Multi-Tenant MCP Server initialized with session management"); console.log("šŸ“ Available session tools:"); console.log(" - session_create: Create new isolated workspace"); console.log(" - session_get: Get session information"); console.log(" - session_update_git: Update git configuration"); console.log(" - session_destroy: Destroy session and cleanup"); console.log(" - session_info: Get all sessions info (admin)"); console.log("šŸ’» Command execution:"); console.log(" - run_bash_command: Execute commands in session workspace"); console.log("šŸ”§ Git operations:"); console.log(" - github_get_status: Get repository status"); console.log(" - github_commit_and_push: Commit and push changes"); return server.server; }

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/pythondev-pro/egw_writings_mcp_server'

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