import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' import { z } from 'zod' const GH_TOKEN = process.env.GH_TOKEN ?? '' const STACK_NAME = process.env.STACK_NAME ?? '' const BASE_URL = process.env.BASE_URL ?? '' // e.g. https://api.github.com/repos/org/repo async function triggerWorkflow(workflow: string, inputs: Record) { const res = await fetch(`${BASE_URL}/actions/workflows/${workflow}/dispatches`, { method: 'POST', headers: { Authorization: `Bearer ${GH_TOKEN}`, Accept: 'application/vnd.github+json', 'Content-Type': 'application/json', 'X-GitHub-Api-Version': '2022-11-28', }, body: JSON.stringify({ ref: 'main', inputs }), }) if (!res.ok) { const text = await res.text() throw new Error(`GitHub API error ${res.status}: ${text}`) } } const server = new McpServer({ name: 'deploy-stg', version: '1.0.0' }) server.tool( 'publish', 'Build & push Docker image ke GHCR untuk environment staging (publish.yml)', { tag: z.string().describe('Image tag, contoh: 1.0.0') }, async ({ tag }) => { await triggerWorkflow('publish.yml', { stack_env: 'stg', tag }) return { content: [{ type: 'text', text: `Workflow publish.yml dipicu untuk stg-${tag}. Cek status di GitHub Actions.` }] } }, ) server.tool( 'repull', 'Re-pull dan redeploy stack staging di Portainer (re-pull.yml)', {}, async () => { await triggerWorkflow('re-pull.yml', { stack_name: STACK_NAME, stack_env: 'stg' }) return { content: [{ type: 'text', text: `Workflow re-pull.yml dipicu untuk stack ${STACK_NAME}-stg. Cek status di GitHub Actions.` }] } }, ) const transport = new StdioServerTransport() await server.connect(transport)