Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dsc/locales/en-us.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ resource = "The name of the resource to invoke"
functionAbout = "Operations on DSC functions"
listFunctionAbout = "List or find functions"
version = "The version of the resource to invoke in semver format"
mcpAbout = "Use DSC as a MCP server"
serverAbout = "Use DSC as a server over JSON-RPC (useful as MCP server)"
bicepAbout = "Use DSC as a Bicep server over gRPC"

[main]
Expand All @@ -56,7 +56,7 @@ storeMessage = """DSC.exe is a command-line tool and cannot be run directly from
Visit https://aka.ms/dscv3-docs for more information on how to use DSC.exe.

Press any key to close this window"""
failedToStartMcpServer = "Failed to start MCP server: %{error}"
failedToStartServer = "Failed to start server: %{error}"

[mcp.mod]
failedToInitialize = "Failed to initialize MCP server: %{error}"
Expand Down
4 changes: 2 additions & 2 deletions dsc/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ pub enum SubCommand {
#[clap(subcommand)]
subcommand: FunctionSubCommand,
},
#[clap(name = "mcp", about = t!("args.mcpAbout").to_string())]
Mcp,
#[clap(name = "server", alias = "mcp", about = t!("args.serverAbout").to_string())]
Server,
Comment thread
SteveL-MSFT marked this conversation as resolved.
#[clap(name = "resource", about = t!("args.resourceAbout").to_string())]
Resource {
#[clap(subcommand)]
Expand Down
12 changes: 6 additions & 6 deletions dsc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use args::{Args, SubCommand};
use clap::{CommandFactory, Parser};
use clap_complete::generate;
use dsc_lib::progress::ProgressFormat;
use mcp::start_mcp_server;
use server::start_server;
use rust_i18n::{i18n, t};
use std::{io, process::exit};
use sysinfo::{Process, RefreshKind, System, get_current_pid, ProcessRefreshKind};
Expand All @@ -19,9 +19,9 @@ use crossterm::event;
use std::env;

pub mod args;
pub mod mcp;
pub mod resolve;
pub mod resource_command;
pub mod server;
pub mod subcommand;
pub mod tablewriter;
pub mod util;
Expand Down Expand Up @@ -85,10 +85,10 @@ fn main() {
SubCommand::Function { subcommand } => {
subcommand::function(&subcommand);
},
SubCommand::Mcp => {
if let Err(err) = start_mcp_server() {
error!("{}", t!("main.failedToStartMcpServer", error = err));
exit(util::EXIT_MCP_FAILED);
SubCommand::Server => {
if let Err(err) = start_server() {
error!("{}", t!("main.failedToStartServer", error = err));
exit(util::EXIT_SERVER_FAILED);
}
Comment thread
SteveL-MSFT marked this conversation as resolved.
exit(util::EXIT_SUCCESS);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::mcp::mcp_server::McpServer;
use crate::server::mcp_server::McpServer;
use dsc_lib::{
configure::{
config_doc::Configuration,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::mcp::mcp_server::McpServer;
use crate::server::mcp_server::McpServer;
use dsc_lib::{
DscManager, configure::config_doc::ExecutionKind,
discovery::discovery_trait::DiscoveryFilter,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::mcp::mcp_server::McpServer;
use crate::server::mcp_server::McpServer;
use dsc_lib::functions::{FunctionDispatcher, FunctionDefinition};
use dsc_lib::util::convert_wildcard_to_regex;
use rmcp::{ErrorData as McpError, Json, tool, tool_router, handler::server::wrapper::Parameters};
Expand Down Expand Up @@ -38,22 +38,22 @@ impl McpServer {
let result = task::spawn_blocking(move || {
let function_dispatcher = FunctionDispatcher::new();
let mut functions = function_dispatcher.list();

// apply filtering if function_filter is provided
if let Some(name_pattern) = function_filter {
let regex_str = convert_wildcard_to_regex(&name_pattern);
let mut regex_builder = RegexBuilder::new(&regex_str);
regex_builder.case_insensitive(true);

let regex = regex_builder.build()
.map_err(|_| McpError::invalid_params(
t!("mcp.list_dsc_functions.invalidNamePattern", pattern = name_pattern),
t!("mcp.list_dsc_functions.invalidNamePattern", pattern = name_pattern),
None
))?;

functions.retain(|func| regex.is_match(&func.name));
}

Ok(FunctionListResult { functions })
}).await.map_err(|e| McpError::internal_error(e.to_string(), None))??;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::mcp::mcp_server::McpServer;
use crate::server::mcp_server::McpServer;
use dsc_lib::{
DscManager, discovery::{
command_discovery::ImportedManifest::Resource,
Expand Down
File renamed without changes.
8 changes: 4 additions & 4 deletions dsc/src/mcp/mod.rs → dsc/src/server/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::mcp::mcp_server::McpServer;
use crate::server::mcp_server::McpServer;
use rmcp::{
ErrorData as McpError,
ServiceExt,
Expand All @@ -22,7 +22,7 @@ pub mod show_dsc_schema;
/// # Errors
///
/// This function will return an error if the MCP server fails to start.
pub async fn start_mcp_server_async() -> Result<(), McpError> {
pub async fn start_server_async() -> Result<(), McpError> {
// Initialize the MCP server
let server = McpServer::new();

Expand All @@ -43,11 +43,11 @@ pub async fn start_mcp_server_async() -> Result<(), McpError> {
/// # Errors
///
/// This function will return an error if the MCP server fails to start or if the tokio runtime cannot be created.
pub fn start_mcp_server() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
pub fn start_server() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let rt = tokio::runtime::Runtime::new()
.map_err(|e| McpError::internal_error(t!("mcp.mod.failedToCreateRuntime", error = e.to_string()), None))?;

rt.block_on(start_mcp_server_async())
rt.block_on(start_server_async())
.map_err(|e| McpError::internal_error(t!("mcp.mod.failedToStart", error = e.to_string()), None))?;
Ok(())
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::mcp::mcp_server::McpServer;
use crate::server::mcp_server::McpServer;
use dsc_lib::{
DscManager,
discovery::discovery_trait::DiscoveryFilter,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::{args::SchemaType, mcp::mcp_server::McpServer, util};
use crate::{args::SchemaType, server::mcp_server::McpServer, util};
use rmcp::{ErrorData as McpError, Json, tool, tool_router, handler::server::wrapper::Parameters};
use schemars::{JsonSchema, json_schema};
use serde::{Deserialize, Serialize};
Expand Down
2 changes: 1 addition & 1 deletion dsc/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub const EXIT_VALIDATION_FAILED: i32 = 5;
pub const EXIT_CTRL_C: i32 = 6;
pub const EXIT_DSC_RESOURCE_NOT_FOUND: i32 = 7;
pub const EXIT_DSC_ASSERTION_FAILED: i32 = 8;
pub const EXIT_MCP_FAILED: i32 = 9;
pub const EXIT_SERVER_FAILED: i32 = 9;
pub const EXIT_BICEP_FAILED: i32 = 10;

pub const DSC_CONFIG_ROOT: &str = "DSC_CONFIG_ROOT";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

Describe 'Tests for MCP server' {
Describe 'Tests for DSC server' {
BeforeAll {
$processStartInfo = [System.Diagnostics.ProcessStartInfo]::new()
$processStartInfo.FileName = "dsc"
$processStartInfo.Arguments = "--trace-format plaintext mcp"
$processStartInfo.Arguments = "--trace-format plaintext server"
$processStartInfo.UseShellExecute = $false
$processStartInfo.RedirectStandardError = $true
$processStartInfo.RedirectStandardOutput = $true
Expand Down
Loading