Skip to content

Commit 803e3fa

Browse files
ElanHassonclaude
andauthored
feat: Add C# Eval MCP server with Roslyn scripting (#2)
* feat: Add C# Eval MCP server with Roslyn scripting - Replace RandomNumberTools with CSharpEvalTools for C# script execution - Add Roslyn scripting support with file and direct code execution - Implement console output capture for MCP protocol compatibility - Add comprehensive NUnit test suite with FluentAssertions - Configure central package management - Add Docker containerization with .NET 9.0 - Configure as dotnet tool for global installation - Add GitHub Actions CI/CD workflows - Add release drafter and dependabot configuration 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * fix: Address code review feedback - Update MCP server configuration with actual values - Add timeout support with configurable parameter (default 30s) - Add file path validation to prevent directory traversal - Restrict file execution to .csx files only - Add more assembly references (HttpClient, JsonSerializer, Regex) - Add exception handling for timeout scenarios - Add tests for new validation and timeout features 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * feat: Add configurable directory restriction for file execution - Add CSX_ALLOWED_PATH environment variable support for directory restriction - When set, only allows script execution from specified directory - Add test for restricted path validation - Update README with security feature documentation This addresses the additional code review feedback about path security. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * feat: Add guideline to never skip tests and always fix them * fix: Improve timeout handling for script execution - Use Task.WhenAny to properly handle timeouts even for blocking operations - Fix timeout test to use Thread.Sleep instead of ignored test - All 15 tests now pass without any ignored tests This ensures that scripts will be terminated after the specified timeout, even if they contain blocking operations that don't check cancellation tokens. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * feat: Enhance error messages with line numbers and context - Compilation errors now show line/column numbers and problematic code - Runtime errors include better formatting and attempt to extract script line numbers - Added visual pointer (^) to show exact error position in code - Inner exceptions are now displayed for better debugging - Added tests for multiline compilation errors and runtime error formatting Example compilation error output: Line 2, Column 9: CS1002 - ; expected Code: var y = ^ This makes debugging scripts much easier by providing clear context about where errors occur and what the problematic code looks like. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 68e68c5 commit 803e3fa

19 files changed

+1516
-2
lines changed

.dockerignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
**/.dockerignore
2+
**/.env
3+
**/.git
4+
**/.gitignore
5+
**/.project
6+
**/.settings
7+
**/.toolstarget
8+
**/.vs
9+
**/.vscode
10+
**/.idea
11+
**/*.*proj.user
12+
**/*.dbmdl
13+
**/*.jfm
14+
**/azds.yaml
15+
**/bin
16+
**/charts
17+
**/docker-compose*
18+
**/Dockerfile*
19+
**/node_modules
20+
**/npm-debug.log
21+
**/obj
22+
**/secrets.dev.yaml
23+
**/values.dev.yaml
24+
LICENSE
25+
README.md
26+
.github/
27+
docs/

.github/dependabot.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
version: 2
2+
updates:
3+
# Enable version updates for NuGet
4+
- package-ecosystem: "nuget"
5+
directory: "/"
6+
schedule:
7+
interval: "weekly"
8+
day: "monday"
9+
open-pull-requests-limit: 10
10+
groups:
11+
microsoft-packages:
12+
patterns:
13+
- "Microsoft.*"
14+
- "System.*"
15+
test-packages:
16+
patterns:
17+
- "NUnit*"
18+
- "FluentAssertions"
19+
- "coverlet.*"
20+
21+
# Enable version updates for GitHub Actions
22+
- package-ecosystem: "github-actions"
23+
directory: "/"
24+
schedule:
25+
interval: "weekly"
26+
day: "monday"
27+
open-pull-requests-limit: 5
28+
29+
# Enable version updates for Docker
30+
- package-ecosystem: "docker"
31+
directory: "/"
32+
schedule:
33+
interval: "weekly"
34+
day: "monday"
35+
open-pull-requests-limit: 5

.github/release-drafter.yml

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
name-template: 'v$RESOLVED_VERSION'
2+
tag-template: 'v$RESOLVED_VERSION'
3+
categories:
4+
- title: '🚀 Features'
5+
labels:
6+
- 'feature'
7+
- 'enhancement'
8+
- title: '🐛 Bug Fixes'
9+
labels:
10+
- 'fix'
11+
- 'bugfix'
12+
- 'bug'
13+
- title: '🧰 Maintenance'
14+
labels:
15+
- 'chore'
16+
- 'maintenance'
17+
- title: '📚 Documentation'
18+
labels:
19+
- 'documentation'
20+
- 'docs'
21+
- title: '🔒 Security'
22+
labels:
23+
- 'security'
24+
- title: '⬆️ Dependencies'
25+
labels:
26+
- 'dependencies'
27+
collapse-after: 5
28+
29+
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
30+
change-title-escapes: '\<*_&'
31+
32+
version-resolver:
33+
major:
34+
labels:
35+
- 'major'
36+
- 'breaking-change'
37+
minor:
38+
labels:
39+
- 'minor'
40+
- 'feature'
41+
- 'enhancement'
42+
patch:
43+
labels:
44+
- 'patch'
45+
- 'bug'
46+
- 'bugfix'
47+
- 'fix'
48+
- 'documentation'
49+
- 'dependencies'
50+
- 'chore'
51+
default: patch
52+
53+
autolabeler:
54+
- label: 'feature'
55+
branch:
56+
- '/^feat(ure)?[/-].+/'
57+
- label: 'bug'
58+
branch:
59+
- '/^(bug)?fix[/-].+/'
60+
- label: 'chore'
61+
branch:
62+
- '/^chore[/-].+/'
63+
- label: 'documentation'
64+
branch:
65+
- '/^docs?[/-].+/'
66+
files:
67+
- '*.md'
68+
- 'docs/**'
69+
- label: 'dependencies'
70+
files:
71+
- 'Directory.Packages.props'
72+
- '*.csproj'
73+
- 'Dockerfile'
74+
75+
template: |
76+
## What's Changed
77+
78+
$CHANGES
79+
80+
## 📦 Installation
81+
82+
### Docker
83+
```bash
84+
docker pull ghcr.io/infinityflowapp/csharp-mcp:$RESOLVED_VERSION
85+
```
86+
87+
### .NET Tool
88+
```bash
89+
dotnet tool install -g InfinityFlow.CSharp.Eval --version $RESOLVED_VERSION
90+
```
91+
92+
### NuGet Package
93+
```xml
94+
<PackageReference Include="InfinityFlow.CSharp.Eval" Version="$RESOLVED_VERSION" />
95+
```
96+
97+
## 🏃 Running
98+
99+
### Docker
100+
```bash
101+
docker run -it ghcr.io/infinityflowapp/csharp-mcp:$RESOLVED_VERSION
102+
```
103+
104+
### .NET Tool
105+
```bash
106+
infinityflow-csharp-eval
107+
```
108+
109+
**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION
110+
111+
## Contributors
112+
113+
$CONTRIBUTORS

.github/workflows/ci-cd.yml

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
name: CI/CD
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
tags: [ 'v*' ]
7+
pull_request:
8+
branches: [ main, develop ]
9+
workflow_dispatch:
10+
11+
env:
12+
DOTNET_VERSION: '9.0.x'
13+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
14+
DOTNET_NOLOGO: true
15+
NUGET_XMLDOC_MODE: skip
16+
REGISTRY: ghcr.io
17+
IMAGE_NAME: ${{ github.repository }}
18+
19+
jobs:
20+
test:
21+
name: Test
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
- name: Checkout
26+
uses: actions/checkout@v4
27+
28+
- name: Setup .NET
29+
uses: actions/setup-dotnet@v4
30+
with:
31+
dotnet-version: ${{ env.DOTNET_VERSION }}
32+
33+
- name: Restore dependencies
34+
run: dotnet restore
35+
36+
- name: Build
37+
run: dotnet build --no-restore --configuration Release
38+
39+
- name: Test
40+
run: dotnet test --no-build --configuration Release --verbosity normal
41+
42+
build-docker:
43+
name: Build and Push Docker Image
44+
runs-on: ubuntu-latest
45+
needs: test
46+
permissions:
47+
contents: read
48+
packages: write
49+
50+
steps:
51+
- name: Checkout
52+
uses: actions/checkout@v4
53+
54+
- name: Set up Docker Buildx
55+
uses: docker/setup-buildx-action@v3
56+
57+
- name: Log in to GitHub Container Registry
58+
uses: docker/login-action@v3
59+
with:
60+
registry: ${{ env.REGISTRY }}
61+
username: ${{ github.actor }}
62+
password: ${{ secrets.GITHUB_TOKEN }}
63+
64+
- name: Extract metadata
65+
id: meta
66+
uses: docker/metadata-action@v5
67+
with:
68+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
69+
tags: |
70+
type=ref,event=branch
71+
type=ref,event=pr
72+
type=semver,pattern={{version}}
73+
type=semver,pattern={{major}}.{{minor}}
74+
type=semver,pattern={{major}}
75+
type=raw,value=latest,enable={{is_default_branch}}
76+
77+
- name: Build and push Docker image
78+
uses: docker/build-push-action@v5
79+
with:
80+
context: .
81+
platforms: linux/amd64,linux/arm64
82+
push: true
83+
tags: ${{ steps.meta.outputs.tags }}
84+
labels: ${{ steps.meta.outputs.labels }}
85+
cache-from: type=gha
86+
cache-to: type=gha,mode=max
87+
88+
publish-nuget:
89+
name: Publish to NuGet
90+
runs-on: ubuntu-latest
91+
needs: test
92+
if: startsWith(github.ref, 'refs/tags/v')
93+
94+
steps:
95+
- name: Checkout
96+
uses: actions/checkout@v4
97+
98+
- name: Setup .NET
99+
uses: actions/setup-dotnet@v4
100+
with:
101+
dotnet-version: ${{ env.DOTNET_VERSION }}
102+
103+
- name: Extract version from tag
104+
id: version
105+
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
106+
107+
- name: Restore dependencies
108+
run: dotnet restore
109+
110+
- name: Build
111+
run: dotnet build --no-restore --configuration Release
112+
113+
- name: Pack
114+
run: |
115+
dotnet pack src/InfinityFlow.CSharp.Eval/InfinityFlow.CSharp.Eval.csproj \
116+
--no-build \
117+
--configuration Release \
118+
--output ./artifacts \
119+
-p:PackageVersion=${{ steps.version.outputs.VERSION }}
120+
121+
- name: Upload NuGet package artifact
122+
uses: actions/upload-artifact@v4
123+
with:
124+
name: nuget-package
125+
path: ./artifacts/*.nupkg
126+
127+
- name: Push to NuGet.org
128+
run: |
129+
dotnet nuget push ./artifacts/*.nupkg \
130+
--api-key ${{ secrets.NUGET_API_KEY }} \
131+
--source https://api.nuget.org/v3/index.json \
132+
--skip-duplicate
133+
134+
- name: Push to GitHub Packages
135+
run: |
136+
dotnet nuget push ./artifacts/*.nupkg \
137+
--api-key ${{ secrets.GITHUB_TOKEN }} \
138+
--source https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json \
139+
--skip-duplicate
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Release Drafter
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
types: [opened, reopened, synchronize]
9+
pull_request_target:
10+
types: [opened, reopened, synchronize]
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
update_release_draft:
17+
permissions:
18+
contents: write
19+
pull-requests: write
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: release-drafter/release-drafter@v6
23+
with:
24+
config-name: release-drafter.yml
25+
env:
26+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)