use clap::{Args, Parser, Subcommand};
#[derive(Debug, Parser)]
#[command(
name = "gyazo-mcp-server",
version,
about = "Gyazo 向けのローカル HTTP / stdio MCP サーバー"
)]
pub(crate) struct Cli {
#[arg(long, global = true)]
pub(crate) config_dir: Option<String>,
#[command(subcommand)]
pub(crate) command: Option<Command>,
}
#[derive(Debug, Clone, PartialEq, Eq, Subcommand)]
pub(crate) enum Command {
Stdio(StdioArgs),
Config(ConfigArgs),
Env(EnvArgs),
Service(ServiceArgs),
}
#[derive(Debug, Clone, PartialEq, Eq, Args)]
pub(crate) struct StdioArgs {
#[arg(long)]
pub(crate) auth: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Args)]
pub(crate) struct ConfigArgs {
#[command(subcommand)]
pub(crate) command: ConfigCommand,
}
#[derive(Debug, Clone, PartialEq, Eq, Subcommand)]
pub(crate) enum ConfigCommand {
Init,
Show,
Get(ConfigGetArgs),
Set(ConfigSetArgs),
Unset(ConfigUnsetArgs),
Path,
}
#[derive(Debug, Clone, PartialEq, Eq, Args)]
pub(crate) struct ConfigUnsetArgs {
pub(crate) key: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Args)]
pub(crate) struct ConfigGetArgs {
pub(crate) key: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Args)]
pub(crate) struct ConfigSetArgs {
pub(crate) key: String,
pub(crate) value: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Args)]
pub(crate) struct EnvArgs {
#[command(subcommand)]
pub(crate) command: EnvCommand,
}
#[derive(Debug, Clone, PartialEq, Eq, Subcommand)]
pub(crate) enum EnvCommand {
Init,
Show,
Get(EnvGetArgs),
Set(EnvSetArgs),
Unset(EnvUnsetArgs),
Path,
}
#[derive(Debug, Clone, PartialEq, Eq, Args)]
pub(crate) struct EnvUnsetArgs {
pub(crate) key: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Args)]
pub(crate) struct EnvGetArgs {
pub(crate) key: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Args)]
pub(crate) struct EnvSetArgs {
pub(crate) key: String,
pub(crate) value: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Args)]
pub(crate) struct ServiceArgs {
#[command(subcommand)]
pub(crate) command: ServiceCommand,
}
#[derive(Debug, Clone, PartialEq, Eq, Subcommand)]
pub(crate) enum ServiceCommand {
Install,
Uninstall,
Status,
Start,
Stop,
Restart,
}
#[cfg(test)]
mod tests {
use clap::Parser;
use super::*;
#[test]
fn parses_default_http_mode_without_subcommand() {
let cli = Cli::parse_from(["gyazo-mcp-server"]);
assert_eq!(cli.command, None);
assert_eq!(cli.config_dir, None);
}
#[test]
fn parses_global_config_dir_option() {
let cli = Cli::parse_from([
"gyazo-mcp-server",
"--config-dir",
"/tmp/test",
"config",
"show",
]);
assert_eq!(cli.config_dir, Some("/tmp/test".to_string()));
assert_eq!(
cli.command,
Some(Command::Config(ConfigArgs {
command: ConfigCommand::Show,
}))
);
}
#[test]
fn parses_stdio_subcommand() {
let cli = Cli::parse_from(["gyazo-mcp-server", "stdio"]);
assert_eq!(cli.command, Some(Command::Stdio(StdioArgs { auth: false })));
}
#[test]
fn parses_stdio_auth_flag() {
let cli = Cli::parse_from(["gyazo-mcp-server", "stdio", "--auth"]);
assert_eq!(cli.command, Some(Command::Stdio(StdioArgs { auth: true })));
}
#[test]
fn parses_config_init() {
let cli = Cli::parse_from(["gyazo-mcp-server", "config", "init"]);
assert_eq!(
cli.command,
Some(Command::Config(ConfigArgs {
command: ConfigCommand::Init,
}))
);
}
#[test]
fn parses_config_show() {
let cli = Cli::parse_from(["gyazo-mcp-server", "config", "show"]);
assert_eq!(
cli.command,
Some(Command::Config(ConfigArgs {
command: ConfigCommand::Show,
}))
);
}
#[test]
fn parses_config_get() {
let cli = Cli::parse_from(["gyazo-mcp-server", "config", "get", "tcp_port"]);
assert_eq!(
cli.command,
Some(Command::Config(ConfigArgs {
command: ConfigCommand::Get(ConfigGetArgs {
key: "tcp_port".to_string(),
}),
}))
);
}
#[test]
fn parses_config_set() {
let cli = Cli::parse_from(["gyazo-mcp-server", "config", "set", "tcp_port", "19000"]);
assert_eq!(
cli.command,
Some(Command::Config(ConfigArgs {
command: ConfigCommand::Set(ConfigSetArgs {
key: "tcp_port".to_string(),
value: "19000".to_string(),
}),
}))
);
}
#[test]
fn parses_config_unset() {
let cli = Cli::parse_from(["gyazo-mcp-server", "config", "unset", "tcp_port"]);
assert_eq!(
cli.command,
Some(Command::Config(ConfigArgs {
command: ConfigCommand::Unset(ConfigUnsetArgs {
key: "tcp_port".to_string(),
}),
}))
);
}
#[test]
fn parses_config_path() {
let cli = Cli::parse_from(["gyazo-mcp-server", "config", "path"]);
assert_eq!(
cli.command,
Some(Command::Config(ConfigArgs {
command: ConfigCommand::Path,
}))
);
}
#[test]
fn parses_env_init() {
let cli = Cli::parse_from(["gyazo-mcp-server", "env", "init"]);
assert_eq!(
cli.command,
Some(Command::Env(EnvArgs {
command: EnvCommand::Init,
}))
);
}
#[test]
fn parses_env_get() {
let cli = Cli::parse_from([
"gyazo-mcp-server",
"env",
"get",
"GYAZO_MCP_OAUTH_CLIENT_ID",
]);
assert_eq!(
cli.command,
Some(Command::Env(EnvArgs {
command: EnvCommand::Get(EnvGetArgs {
key: "GYAZO_MCP_OAUTH_CLIENT_ID".to_string(),
}),
}))
);
}
#[test]
fn parses_env_show() {
let cli = Cli::parse_from(["gyazo-mcp-server", "env", "show"]);
assert_eq!(
cli.command,
Some(Command::Env(EnvArgs {
command: EnvCommand::Show,
}))
);
}
#[test]
fn parses_env_set() {
let cli = Cli::parse_from([
"gyazo-mcp-server",
"env",
"set",
"GYAZO_MCP_OAUTH_CLIENT_ID",
"my-id",
]);
assert_eq!(
cli.command,
Some(Command::Env(EnvArgs {
command: EnvCommand::Set(EnvSetArgs {
key: "GYAZO_MCP_OAUTH_CLIENT_ID".to_string(),
value: "my-id".to_string(),
}),
}))
);
}
#[test]
fn parses_env_unset() {
let cli = Cli::parse_from([
"gyazo-mcp-server",
"env",
"unset",
"GYAZO_MCP_PERSONAL_ACCESS_TOKEN",
]);
assert_eq!(
cli.command,
Some(Command::Env(EnvArgs {
command: EnvCommand::Unset(EnvUnsetArgs {
key: "GYAZO_MCP_PERSONAL_ACCESS_TOKEN".to_string(),
}),
}))
);
}
#[test]
fn parses_env_path() {
let cli = Cli::parse_from(["gyazo-mcp-server", "env", "path"]);
assert_eq!(
cli.command,
Some(Command::Env(EnvArgs {
command: EnvCommand::Path,
}))
);
}
#[test]
fn parses_service_install() {
let cli = Cli::parse_from(["gyazo-mcp-server", "service", "install"]);
assert_eq!(
cli.command,
Some(Command::Service(ServiceArgs {
command: ServiceCommand::Install,
}))
);
}
#[test]
fn parses_service_uninstall() {
let cli = Cli::parse_from(["gyazo-mcp-server", "service", "uninstall"]);
assert_eq!(
cli.command,
Some(Command::Service(ServiceArgs {
command: ServiceCommand::Uninstall,
}))
);
}
#[test]
fn parses_service_status() {
let cli = Cli::parse_from(["gyazo-mcp-server", "service", "status"]);
assert_eq!(
cli.command,
Some(Command::Service(ServiceArgs {
command: ServiceCommand::Status,
}))
);
}
#[test]
fn parses_service_start_stop_restart() {
for (arg, expected) in [
("start", ServiceCommand::Start),
("stop", ServiceCommand::Stop),
("restart", ServiceCommand::Restart),
] {
let cli = Cli::parse_from(["gyazo-mcp-server", "service", arg]);
assert_eq!(
cli.command,
Some(Command::Service(ServiceArgs { command: expected })),
"service {arg} のパースに失敗しました"
);
}
}
}