index.ts•2.63 kB
import type { AppConfig } from '../mcp/server.js';
import { GitLabAdapter } from '../adapters/gitlab.js';
import { JiraAdapter } from '../adapters/jira.js';
import { AppError } from '../lib/errors.js';
import { ZodError } from 'zod';
import {
GL_ListIssues_In,
GL_ListIssues_Out,
GL_ListMRs_In,
GL_ListMRs_Out,
GL_ListProjects_Out,
Jira_GetIssue_In,
Jira_Search_In,
JiraSearchResult,
} from '../schemas/tools.js';
export type ToolContext = { cfg: AppConfig; gitlab?: GitLabAdapter; jira?: JiraAdapter };
export function createTools(ctx: ToolContext) {
return {
gitlab_list_projects: async () => {
const raw = (await ctx.gitlab?.listProjects()) ?? [];
try {
return GL_ListProjects_Out.parse(raw);
} catch (e) {
if (e instanceof ZodError) throw new AppError('INVALID_INPUT', e.errors?.[0]?.message || 'Invalid output shape');
throw e;
}
},
gitlab_list_merge_requests: async (projectId: string | number, state?: string) => {
try {
const { projectId: pid, state: st } = GL_ListMRs_In.parse({ projectId, state });
const raw = (await ctx.gitlab?.listMergeRequests(pid, st as any)) ?? [];
return GL_ListMRs_Out.parse(raw);
} catch (e) {
if (e instanceof ZodError) throw new AppError('INVALID_INPUT', e.errors?.[0]?.message || 'Invalid input/output');
throw e;
}
},
gitlab_list_issues: async (projectId: string | number) => {
try {
const { projectId: pid } = GL_ListIssues_In.parse({ projectId });
const raw = (await ctx.gitlab?.listIssues(pid)) ?? [];
return GL_ListIssues_Out.parse(raw);
} catch (e) {
if (e instanceof ZodError) throw new AppError('INVALID_INPUT', e.errors?.[0]?.message || 'Invalid input/output');
throw e;
}
},
jira_search_issues: async (jql: string, maxResults?: number) => {
try {
const { jql: q, maxResults: mr } = Jira_Search_In.parse({ jql, maxResults });
const res = (await ctx.jira?.searchIssues(q, mr)) ?? {};
return JiraSearchResult.parse(res);
} catch (e) {
if (e instanceof ZodError) throw new AppError('INVALID_INPUT', e.errors?.[0]?.message || 'Invalid input/output');
throw e;
}
},
jira_get_issue: async (key: string) => {
try {
const { key: k } = Jira_GetIssue_In.parse({ key });
return (await ctx.jira?.getIssue(k)) ?? {};
} catch (e) {
if (e instanceof ZodError) throw new AppError('INVALID_INPUT', e.errors?.[0]?.message || 'Invalid input');
throw e;
}
},
};
}