sin-github-issues / src /mcp-server.ts
OpenCode
Deploy latest SIN-GitHub-Issues runtime
cd455f6
Raw
History Blame Contribute Delete
9.61 kB
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { executeGitHubAgentAction, GitHubAgentAction } from './runtime.js';
const server = new Server(
{ name: 'sin-github-issues', version: '2026.03.22' },
{ capabilities: { tools: {} } },
);
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'sin_github_health',
description: 'Check 2026 Elite GitHub Operations Architect readiness.',
inputSchema: { type: 'object', properties: {} },
},
{
name: 'sin_github_app_routing_status',
description: 'Inspect per-agent GitHub App routing config without exposing secrets.',
inputSchema: { type: 'object', properties: {} },
},
{
name: 'sin_github_webhook_route',
description: 'Resolve a GitHub webhook payload to the correct specialized SIN coder app using installation.app_id and routing config.',
inputSchema: {
type: 'object',
properties: {
payload: {},
rawBody: { type: 'string' },
routePath: { type: 'string' },
signature256: { type: 'string' },
eventName: { type: 'string' },
deliveryId: { type: 'string' },
},
},
},
{
name: 'sin_github_issue_comment_as_app',
description: 'Post an issue or PR comment as the correct GitHub App identity using a JWT + installation token flow.',
inputSchema: {
type: 'object',
properties: {
repo: { type: 'string' },
issueNumber: { type: 'number' },
body: { type: 'string' },
agentSlug: { type: 'string' },
appId: { type: 'number' },
installationId: { type: 'number' },
},
required: ['repo', 'issueNumber', 'body', 'installationId'],
},
},
{
name: 'sin_github_project_orchestrate',
description: 'Create and manage GitHub Projects V2 boards.',
inputSchema: {
type: 'object',
properties: {
prompt: { type: 'string' },
contextDir: { type: 'string' },
},
required: ['prompt'],
},
},
{
name: 'sin_github_issue_manage',
description: 'Create, update, or close issues (Epics, Sub-tasks).',
inputSchema: {
type: 'object',
properties: {
prompt: { type: 'string' },
issueNumber: { type: 'number' },
},
required: ['prompt'],
},
},
{
name: 'sin_github_wiki_sync',
description: 'Update the repository Wiki with project documentation.',
inputSchema: {
type: 'object',
properties: {
prompt: { type: 'string' },
contextDir: { type: 'string' },
},
required: ['prompt'],
},
},
{
name: 'sin_github_discussion_start',
description: 'Start an architectural debate in Discussions.',
inputSchema: {
type: 'object',
properties: {
prompt: { type: 'string' },
category: { type: 'string' },
},
required: ['prompt'],
},
},
{
name: 'sin_github_gist_publish',
description: 'Upload a large log or code snippet to a Gist.',
inputSchema: {
type: 'object',
properties: {
prompt: { type: 'string' },
isPublic: { type: 'boolean' },
},
required: ['prompt'],
},
},
{
name: 'sin_github_security_audit',
description: 'Audit security alerts and configure Dependabot/CodeQL.',
inputSchema: {
type: 'object',
properties: {
prompt: { type: 'string' },
contextDir: { type: 'string' },
},
required: ['prompt'],
},
},
{
name: 'sin_github_pr_review',
description: 'Review and approve/merge Pull Requests.',
inputSchema: {
type: 'object',
properties: {
prNumber: { type: 'number' },
contextDir: { type: 'string' },
},
required: ['prNumber'],
},
},
{
name: 'sin_github_issue_pool_enqueue',
description: 'Insert an issue into the Hermes issue pool for Team-Coding dispatch.',
inputSchema: {
type: 'object',
properties: {
repoName: { type: 'string' },
issueNumber: { type: 'number' },
title: { type: 'string' },
body: { type: 'string' },
labels: { type: 'array', items: { type: 'string' } },
issueUrl: { type: 'string' },
assignedTeam: { type: 'string' },
assignedAgent: { type: 'string' },
status: { type: 'string' },
state: { type: 'string' },
routingStrategy: { type: 'string' },
fanoutPlan: { type: 'array', items: {} },
},
required: ['repoName', 'issueNumber', 'title'],
},
},
{
name: 'sin_github_ledger_log',
description: 'Publish an agent activity log or achievement to the public OpenSIN-Ledger showcase repository.',
inputSchema: {
type: 'object',
properties: {
agentName: { type: 'string', description: 'Name of the agent logging the activity' },
activityTitle: { type: 'string', description: 'Short title of the achievement or task' },
details: { type: 'string', description: 'Detailed markdown describing what was accomplished' },
},
required: ['agentName', 'activityTitle', 'details'],
},
},
],
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
let action: GitHubAgentAction;
const args = request.params.arguments as any;
switch (request.params.name) {
case 'sin_github_health':
action = { action: 'sin.github.health' };
break;
case 'sin_github_app_routing_status':
action = { action: 'sin.github.app.routing.status' };
break;
case 'sin_github_webhook_route':
action = {
action: 'sin.github.webhook.route',
payload: args.payload,
rawBody: args.rawBody,
routePath: args.routePath,
signature256: args.signature256,
eventName: args.eventName,
deliveryId: args.deliveryId,
};
break;
case 'sin_github_issue_comment_as_app':
action = {
action: 'sin.github.issue.comment.as_app',
repo: args.repo,
issueNumber: args.issueNumber,
body: args.body,
agentSlug: args.agentSlug,
appId: args.appId,
installationId: args.installationId,
};
break;
case 'sin_github_project_orchestrate':
action = { action: 'sin.github.project.orchestrate', prompt: args.prompt, contextDir: args.contextDir };
break;
case 'sin_github_issue_manage':
action = { action: 'sin.github.issue.manage', prompt: args.prompt, issueNumber: args.issueNumber };
break;
case 'sin_github_wiki_sync':
action = { action: 'sin.github.wiki.sync', prompt: args.prompt, contextDir: args.contextDir };
break;
case 'sin_github_discussion_start':
action = { action: 'sin.github.discussion.start', prompt: args.prompt, category: args.category };
break;
case 'sin_github_gist_publish':
action = { action: 'sin.github.gist.publish', prompt: args.prompt, isPublic: args.isPublic };
break;
case 'sin_github_security_audit':
action = { action: 'sin.github.security.audit', prompt: args.prompt, contextDir: args.contextDir };
break;
case 'sin_github_pr_review':
action = { action: 'sin.github.pr.review', prNumber: args.prNumber, contextDir: args.contextDir };
break;
case 'sin_github_issue_pool_enqueue':
action = {
action: 'sin.github.issue.pool.enqueue',
repoName: args.repoName,
issueNumber: args.issueNumber,
title: args.title,
body: args.body,
labels: args.labels,
issueUrl: args.issueUrl,
assignedTeam: args.assignedTeam,
assignedAgent: args.assignedAgent,
status: args.status,
state: args.state,
routingStrategy: args.routingStrategy,
fanoutPlan: args.fanoutPlan,
};
break;
case 'sin_github_ledger_log':
action = { action: 'sin.github.ledger.log', agentName: args.agentName, activityTitle: args.activityTitle, details: args.details };
break;
default:
throw new Error(`Unknown tool: ${request.params.name}`);
}
const result = await executeGitHubAgentAction(action);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
};
} catch (error: any) {
return {
content: [{ type: 'text', text: `Error: ${error.message}` }],
isError: true,
};
}
});
export async function runMcpServer() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('A2A-SIN-GitHub-Issues MCP Server running on stdio');
}