feat: add MCP server as .NET global tool with URL allowlist security#225
feat: add MCP server as .NET global tool with URL allowlist security#225Copilot wants to merge 20 commits into
Conversation
|
@copilot Add actions to get list of cmdlets with a summary of what they do (from help) and another to return the full help content for a cmdlet. The default connection should be set as part of the MCP startup referencing a named connection that Get-DataverseConnection has saved. If no name is provided startup should fail with good instructions on how to save the required connection. |
Implemented in commit 2d55d70: New MCP Tools:
Default Connection:
Example usage: dotnet run --project McpServer.csproj MyConnectionOr with environment variable: export DATAVERSE_CONNECTION_NAME=MyConnection
dotnet run --project McpServer.csproj |
|
@copilot default to PowerShell restricted language mode, but provide a cmd line option to disable it. Also allow the filesystem provider and other restrictions to be turned off. Also, it would be good to allow a session to be started and then for multiple scripts to be run in the same session one after the other if needed. An end session would be good too. So run script will need to track if the supplied script has exited, not the whole runspace. |
|
@copilot set up CI so that the MCP provider is packaged and pushed as .net global tool. It should bundle the module with it. |
Implemented in commit 16ba421: PowerShell Restricted Language Mode
Provider Control
Persistent Sessions
Command-Line Library
Example usage: # Restricted mode (default)
dotnet run -- -c MyConnection
# Full access
dotnet run -- -c MyConnection --unrestricted-mode --enable-providers |
Implemented in commit ee0d35d: . NET Global Tool Configuration
CI/CD Workflow
Usage # Install
dotnet tool install --global Rnwood.Dataverse.Data.PowerShell.McpServer
# Run
dataverse-mcp --connection MyConnection
# Update
dotnet tool update --global Rnwood.Dataverse.Data.PowerShell.McpServerModule is automatically included in the tool package - no separate installation needed. |
|
@copilot prefix the dotnet tool name with rnwood- |
Updated in commit 3d27407: Tool command name changed from Installation: dotnet tool install --global Rnwood.Dataverse.Data.PowerShell.McpServerUsage: rnwood-dataverse-mcp --connection MyConnectionUpdated README and Claude Desktop configuration examples. |
|
@copilot in the MCP session, the named connection should be -setasdefault add an e2e test for the MCP server as part of the existing e2e tests. It should create and save a connectioj, launch the mcp server and test that it can run and monitor a script that uses the connection |
Implemented in commit 9c36b68: Connection SetAsDefault:
E2E Test:
|
|
@copilot please split the test into another file and make sure the tests run all in parallel like the main non e2e tests |
Updated in commit e6c40f8: Documentation now shows
Example configuration: {
"mcpServers": {
"dataverse": {
"command": "dotnet",
"args": [
"exec",
"--package",
"Rnwood.Dataverse.Data.PowerShell.McpServer",
"rnwood-dataverse-mcp",
"--",
"--allowed-urls",
"https://yourorg.crm.dynamics.com"
]
}
}
}This eliminates the need to install the tool globally while providing automatic updates. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
- Add GetCmdletList tool to list all cmdlets with synopsis - Add GetCmdletHelp tool to get detailed help for specific cmdlets - Add connection name parameter (CLI arg or env var DATAVERSE_CONNECTION_NAME) - Validate connection on startup with helpful error messages - Pre-load $connection variable in script sessions - Update README with setup instructions and new tool documentation Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
…strictions - Add System.CommandLine for proper command-line parsing - Implement persistent sessions with CreateSession/RunScriptInSession/EndSession - Add --unrestricted-mode flag to disable restricted language mode (default: restricted) - Add --enable-providers flag to enable FileSystem/Registry providers (default: disabled) - Track individual script executions, not whole runspace completion - Scripts in same session share variables and state - Update README with new session model and security options - Maintain backward compatibility with session-based execution Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
- Configure project as .NET global tool (command: dataverse-mcp) - Bundle Dataverse PowerShell module in package at tools/net8.0/any/module/ - Update module path resolution to check packaged location first - Add CI workflow steps to build, package and publish to NuGet.org - Publish on stable releases and CI builds from main branch - Update README with installation and usage instructions for global tool - Update Claude Desktop configuration examples Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
Change tool command from 'dataverse-mcp' to 'rnwood-dataverse-mcp' for better namespacing and to avoid potential conflicts with other tools. Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
- Add -SetAsDefault flag when loading named connection in MCP sessions - Add comprehensive e2e test for MCP server that: - Creates and saves a test connection - Launches the MCP server process - Tests MCP protocol initialization - Creates a session - Runs a script (Get-DataverseWhoAmI) - Monitors script execution and retrieves output - Ends the session and cleans up - Test validates full MCP server workflow with real connection Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
- Create new McpServer.Tests.ps1 in e2e-tests directory - Move MCP server test from Module.Tests.ps1 to McpServer.Tests.ps1 - Each test file has its own BeforeAll setup for isolation - Tests can now run in parallel like other test files - No functional changes to test logic Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
- Add --http flag to run server in HTTP mode instead of STDIO - HTTP mode uses ASP.NET Core with JSON-RPC endpoints at /mcp - Supports standard ASP.NET environment variables (ASPNETCORE_URLS, etc.) - Add Microsoft.AspNetCore.App package reference - Implement JSON-RPC request handler for HTTP mode - Update README with HTTP mode documentation and examples - Add comprehensive e2e test for HTTP mode (McpServer-Http.Tests.ps1) - Test validates full HTTP workflow including initialize, session creation, script execution, and cleanup Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
- Add ModelContextProtocol.AspNetCore package (v0.4.0-preview.3) - Remove Microsoft.AspNetCore.App reference (provided by AspNetCore package) - Simplify HTTP mode to use AddMcpServer().WithHttpTransport() and MapMcp() - Remove manual JSON-RPC request handling code - Update README to mention official ASP.NET Core package - HTTP endpoints now managed by ModelContextProtocol framework Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
…ve connection parameter - Remove HTTP mode support and ModelContextProtocol.AspNetCore dependency - Remove --connection parameter (auto-connects to first allowed URL) - Add --allowed-urls parameter (required) for URL allowlist - Add ValidateUrlIfRestricted method in Get-DataverseConnection cmdlet - Cmdlet checks session variable $Global:AllowedDataverseUrls for restrictions - PowerShellExecutor sets allowed URLs as session variable - Simplifies session initialization (just sets URLs and auto-connects) - Remove HTTP e2e test - Update README to reflect new URL restriction model Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
Add ValidateUrlIfRestricted method that checks URLs against a session variable $Global:AllowedDataverseUrls before creating connections. Validation is: - Optional: no restrictions when variable is unset, null, or empty - Case-insensitive: URLs are normalized to lowercase - Trailing-slash normalized: URLs are compared without trailing slashes - Applied to all authentication methods (Interactive, DeviceCode, UsernamePassword, ClientSecret, ClientCertificate, DefaultAzureCredential, ManagedIdentity, AccessToken, Mock, and LoadNamed parameter sets) Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
- Add MCP Server to features list with emoji and anchor link - Add dedicated "MCP Server for AI Assistants" section with: - Quick start guide (install, configure, restart) - 5 practical example use cases with PowerShell code - Security features overview - Advanced configuration examples (multiple envs, unrestricted mode) - Link to full MCP Server documentation - Show installation via dotnet tool - Demonstrate Claude Desktop configuration - Include real-world scenarios (queries, creates, updates, reports) Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
…eeded) - Update MCP Server README to show dotnet exec as recommended method - Update main README to use dotnet exec in quick start and advanced examples - Add benefits: no installation, always latest version, no PATH pollution - Keep global tool as alternative method for users who prefer it - Update all Claude Desktop configuration examples to use dotnet exec syntax - Document version pinning capability with dotnet exec Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
- Replace all dotnet exec --package commands with dnx - Simplify Claude Desktop configuration examples - Update main README MCP server section - Update MCP Server README installation and configuration - Add note about .NET 10 SDK requirement for dnx - Keep global tool installation as alternative option - Much cleaner and simpler syntax for users Co-authored-by: rnwood <1327895+rnwood@users.noreply.github.com>
de743d9 to
0c90000
Compare
Description
Adds a Model Context Protocol (MCP) STDIO server exposing PowerShell with the Dataverse module pre-loaded. Enables AI assistants (e.g., Claude Desktop) to execute PowerShell scripts against Dataverse environments with URL allowlist security enforced at cmdlet level.
Changes Made
MCP Server Project (
Rnwood.Dataverse.Data.PowerShell.McpServer)Security
Get-DataverseConnectioncmdlet (not wrapper - cannot be bypassed)$Global:AllowedDataverseUrlssession variable for all connection methods (interactive, saved, client secret, etc.)MCP Tools
GetCmdletList- Returns cmdlets with synopsisGetCmdletHelp- Returns full help contentCreateSession- Creates persistent PowerShell sessionRunScriptInSession- Executes scripts with state persistenceGetScriptOutput- Retrieves output (full or incremental)EndSession- CleanupCLI
--allowed-urls(required) - URL allowlist--unrestricted-mode- Disable language restrictions--enable-providers- Enable PowerShell providersPackaging & CI/CD
Rnwood.Dataverse.Data.PowerShell.McpServertools/net8.0/any/module/Documentation
dnxcommand (.NET 10 SDK) for streamlined executionExample Usage
Claude Desktop Configuration
{ "mcpServers": { "dataverse": { "command": "dnx", "args": ["rnwood-dataverse-mcp", "--allowed-urls", "https://yourorg.crm.dynamics.com"] } } }Testing
Checklist
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.