Skip to main content

github_mcp/prompts/
router.rs

1//! One method per MCP prompt. See docs/mcp-prompts-workflow-plan.md for the
2//! design rationale (agnostic phrasing, whole-sub-workflow delegation,
3//! content-size targets) that every `content/*.md` file must follow.
4
5use rmcp::handler::server::wrapper::Parameters;
6use rmcp::model::{PromptMessage, Role};
7use rmcp::{prompt, prompt_router};
8
9use crate::core::mcp_server::McpifyServer;
10use crate::prompts::{
11    EnvironmentsDeploymentsWorkflowArgs, MasterWorkflowArgs, PullRequestWorkflowArgs,
12    RulesetsWorkflowArgs, render_context_header,
13};
14
15#[prompt_router(vis = "pub(crate)")]
16impl McpifyServer {
17    #[prompt(
18        name = "github-workflow",
19        description = "Start here. Presents the available GitHub management workflows, \
20                        routes to the right guided sub-workflow based on the user's goal, \
21                        and -- where the environment supports it -- delegates that whole \
22                        sub-workflow to an isolated sub-task to spare this conversation's \
23                        context window."
24    )]
25    async fn github_workflow_prompt(
26        &self,
27        Parameters(args): Parameters<MasterWorkflowArgs>,
28    ) -> Vec<PromptMessage> {
29        let header = render_context_header(&[("goal", args.goal.as_deref())]);
30        vec![PromptMessage::new_text(
31            Role::User,
32            format!("{header}\n\n{}", include_str!("content/master.md")),
33        )]
34    }
35
36    #[prompt(
37        name = "github-workflow-pull-request",
38        description = "Guided, multi-step pull request flow: the fork-vs-direct-branch \
39                        decision, branch/commit/push, opening the PR, reviewers, and \
40                        verifying checks/reviews before declaring it ready to merge."
41    )]
42    async fn github_workflow_pull_request_prompt(
43        &self,
44        Parameters(args): Parameters<PullRequestWorkflowArgs>,
45    ) -> Vec<PromptMessage> {
46        let header = render_context_header(&[
47            ("owner", args.owner.as_deref()),
48            ("repo", args.repo.as_deref()),
49            ("base_branch", args.base_branch.as_deref()),
50            ("head_branch", args.head_branch.as_deref()),
51        ]);
52        vec![PromptMessage::new_text(
53            Role::User,
54            format!("{header}\n\n{}", include_str!("content/pull_request.md")),
55        )]
56    }
57
58    #[prompt(
59        name = "github-workflow-rulesets",
60        description = "Guided setup of repository/org/enterprise rulesets -- the mechanism \
61                        that supersedes classic branch protection -- including the \
62                        evaluate-mode dry run before flipping enforcement on."
63    )]
64    async fn github_workflow_rulesets_prompt(
65        &self,
66        Parameters(args): Parameters<RulesetsWorkflowArgs>,
67    ) -> Vec<PromptMessage> {
68        let header = render_context_header(&[
69            ("owner_or_org", args.owner_or_org.as_deref()),
70            ("repo", args.repo.as_deref()),
71            ("ruleset_name", args.ruleset_name.as_deref()),
72            ("target_ref_pattern", args.target_ref_pattern.as_deref()),
73        ]);
74        vec![PromptMessage::new_text(
75            Role::User,
76            format!("{header}\n\n{}", include_str!("content/rulesets.md")),
77        )]
78    }
79
80    #[prompt(
81        name = "github-workflow-environments-deployments",
82        description = "Guided setup of deployment environments (protected or simple) and \
83                        deployments, tracking the deployment status lifecycle and approval \
84                        gates, plus a shorter GitHub Pages setup flow."
85    )]
86    async fn github_workflow_environments_deployments_prompt(
87        &self,
88        Parameters(args): Parameters<EnvironmentsDeploymentsWorkflowArgs>,
89    ) -> Vec<PromptMessage> {
90        let header = render_context_header(&[
91            ("owner", args.owner.as_deref()),
92            ("repo", args.repo.as_deref()),
93            ("environment_name", args.environment_name.as_deref()),
94        ]);
95        vec![PromptMessage::new_text(
96            Role::User,
97            format!(
98                "{header}\n\n{}",
99                include_str!("content/environments_deployments.md")
100            ),
101        )]
102    }
103
104    #[prompt(
105        name = "github-workflow-repos",
106        description = "Repository lifecycle (create, fork, transfer, archive, delete), \
107                        branches and branch protection, tags, commits/git data, releases, \
108                        topics/settings, webhooks."
109    )]
110    async fn github_workflow_repos_prompt(&self) -> Vec<PromptMessage> {
111        vec![PromptMessage::new_text(
112            Role::User,
113            include_str!("content/repos.md"),
114        )]
115    }
116
117    #[prompt(
118        name = "github-workflow-issues",
119        description = "Issue lifecycle, labels, milestones, assignees, comments, reactions."
120    )]
121    async fn github_workflow_issues_prompt(&self) -> Vec<PromptMessage> {
122        vec![PromptMessage::new_text(
123            Role::User,
124            include_str!("content/issues.md"),
125        )]
126    }
127
128    #[prompt(
129        name = "github-workflow-actions-ci",
130        description = "GitHub Actions workflows, runs, artifacts, secrets/variables, \
131                        self-hosted runners, hosted compute, check-runs."
132    )]
133    async fn github_workflow_actions_ci_prompt(&self) -> Vec<PromptMessage> {
134        vec![PromptMessage::new_text(
135            Role::User,
136            include_str!("content/actions_ci.md"),
137        )]
138    }
139
140    #[prompt(
141        name = "github-workflow-orgs-teams",
142        description = "Organizations, teams, enterprise teams/memberships, members, outside \
143                        collaborators."
144    )]
145    async fn github_workflow_orgs_teams_prompt(&self) -> Vec<PromptMessage> {
146        vec![PromptMessage::new_text(
147            Role::User,
148            include_str!("content/orgs_teams.md"),
149        )]
150    }
151
152    #[prompt(
153        name = "github-workflow-security-suite",
154        description = "Code scanning, secret scanning, code security configurations, \
155                        Dependabot, security advisories, dependency graph, private \
156                        registries."
157    )]
158    async fn github_workflow_security_suite_prompt(&self) -> Vec<PromptMessage> {
159        vec![PromptMessage::new_text(
160            Role::User,
161            include_str!("content/security_suite.md"),
162        )]
163    }
164
165    #[prompt(
166        name = "github-workflow-apps-auth-billing",
167        description = "GitHub Apps/installations, OAuth apps, OIDC, billing, credentials, \
168                        API insights."
169    )]
170    async fn github_workflow_apps_auth_billing_prompt(&self) -> Vec<PromptMessage> {
171        vec![PromptMessage::new_text(
172            Role::User,
173            include_str!("content/apps_auth_billing.md"),
174        )]
175    }
176
177    #[prompt(
178        name = "github-workflow-packages-migrations-gists",
179        description = "Packages, import/export migrations, gists."
180    )]
181    async fn github_workflow_packages_migrations_gists_prompt(&self) -> Vec<PromptMessage> {
182        vec![PromptMessage::new_text(
183            Role::User,
184            include_str!("content/packages_migrations_gists.md"),
185        )]
186    }
187
188    #[prompt(
189        name = "github-workflow-codespaces-copilot",
190        description = "Codespaces, Copilot, Copilot Spaces, agents/agent tasks, GitHub \
191                        Classroom."
192    )]
193    async fn github_workflow_codespaces_copilot_prompt(&self) -> Vec<PromptMessage> {
194        vec![PromptMessage::new_text(
195            Role::User,
196            include_str!("content/codespaces_copilot.md"),
197        )]
198    }
199
200    #[prompt(
201        name = "github-workflow-projects",
202        description = "Projects (v2), campaigns."
203    )]
204    async fn github_workflow_projects_prompt(&self) -> Vec<PromptMessage> {
205        vec![PromptMessage::new_text(
206            Role::User,
207            include_str!("content/projects.md"),
208        )]
209    }
210
211    #[prompt(
212        name = "github-workflow-users-activity",
213        description = "User profile/keys/social graph, activity feed, starring/watching, \
214                        notifications."
215    )]
216    async fn github_workflow_users_activity_prompt(&self) -> Vec<PromptMessage> {
217        vec![PromptMessage::new_text(
218            Role::User,
219            include_str!("content/users_activity.md"),
220        )]
221    }
222
223    #[prompt(
224        name = "github-workflow-meta-diagnostics",
225        description = "Thin pointer to read-only utility signals: API meta, rate limits, \
226                        code search, emojis, gitignore templates, licenses, code-of-conduct \
227                        templates, markdown rendering."
228    )]
229    async fn github_workflow_meta_diagnostics_prompt(&self) -> Vec<PromptMessage> {
230        vec![PromptMessage::new_text(
231            Role::User,
232            include_str!("content/meta_diagnostics.md"),
233        )]
234    }
235}