Skip to content

Commit 2308401

Browse files
committed
Housekeeping updates
Refactor timetable service methods and update test cases for clarity and consistency
1 parent fd60e42 commit 2308401

File tree

4 files changed

+63
-28
lines changed

4 files changed

+63
-28
lines changed

.vscode/launch.json

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,26 @@
22
"version": "0.2.0",
33
"configurations": [
44
{
5-
"name": "Debug MCP Server with Inspector (HTTP)",
5+
"name": "Debug C# MCP Server",
6+
"type": "coreclr",
7+
"request": "launch",
8+
"preLaunchTask": "build-solution",
9+
"program": "${workspaceFolder}/AbeckDev.DbTimetable.Mcp/bin/Debug/net9.0/AbeckDev.DbTimetable.Mcp.dll",
10+
"args": [],
11+
"cwd": "${workspaceFolder}/AbeckDev.DbTimetable.Mcp",
12+
"stopAtEntry": false,
13+
"console": "internalConsole",
14+
"env": {
15+
"ASPNETCORE_ENVIRONMENT": "Development",
16+
"ASPNETCORE_URLS": "http://0.0.0.0:3001"
17+
},
18+
"serverReadyAction": {
19+
"action": "openExternally",
20+
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
21+
}
22+
},
23+
{
24+
"name": "Run MCP Inspector",
625
"type": "node",
726
"request": "launch",
827
"runtimeExecutable": "npx",
@@ -18,12 +37,26 @@
1837
},
1938
"console": "integratedTerminal",
2039
"internalConsoleOptions": "neverOpen",
21-
"preLaunchTask": "build-and-run-server",
2240
"serverReadyAction": {
2341
"pattern": "MCP Inspector is up and running at:\\s+(http://[^\\s]+)",
2442
"uriFormat": "%s",
2543
"action": "openExternally"
2644
}
2745
}
46+
],
47+
"compounds": [
48+
{
49+
"name": "Debug MCP Server with Inspector",
50+
"configurations": [
51+
"Debug C# MCP Server",
52+
"Run MCP Inspector"
53+
],
54+
"stopAll": true,
55+
"presentation": {
56+
"hidden": false,
57+
"group": "MCP",
58+
"order": 1
59+
}
60+
}
2861
]
2962
}

AbeckDev.DbTimetable.Mcp.Test/TimetableToolsTests.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public async Task GetFullTimetableChanges_WithValidEventNo_ReturnsXmlContent()
2424
var tools = new Tools.TimetableTools(_mockService.Object);
2525

2626
// Act
27-
var result = await tools.GetFullTimetableChanges(eventNo);
27+
var result = await tools.GetFullStationChanges(eventNo);
2828

2929
// Assert
3030
Assert.Equal(_testXmlResponse, result);
@@ -43,7 +43,7 @@ public async Task GetFullTimetableChanges_WithHttpRequestException_ReturnsErrorM
4343
var tools = new Tools.TimetableTools(_mockService.Object);
4444

4545
// Act
46-
var result = await tools.GetFullTimetableChanges(eventNo);
46+
var result = await tools.GetFullStationChanges(eventNo);
4747

4848
// Assert
4949
Assert.Contains("Error fetching timetable changes:", result);
@@ -62,7 +62,7 @@ public async Task GetFullTimetableChanges_WithGeneralException_ReturnsUnexpected
6262
var tools = new Tools.TimetableTools(_mockService.Object);
6363

6464
// Act
65-
var result = await tools.GetFullTimetableChanges(eventNo);
65+
var result = await tools.GetFullStationChanges(eventNo);
6666

6767
// Assert
6868
Assert.Contains("Unexpected error:", result);
@@ -182,7 +182,7 @@ public async Task GetStationBoard_WithGeneralException_ReturnsUnexpectedErrorMes
182182
}
183183

184184
[Fact]
185-
public async Task GetStationChanges_WithValidEvaNo_ReturnsXmlContent()
185+
public async Task GetRecentChanges_WithValidEvaNo_ReturnsXmlContent()
186186
{
187187
// Arrange
188188
var evaNo = "8000105";
@@ -192,15 +192,15 @@ public async Task GetStationChanges_WithValidEvaNo_ReturnsXmlContent()
192192
var tools = new Tools.TimetableTools(_mockService.Object);
193193

194194
// Act
195-
var result = await tools.GetStationChanges(evaNo);
195+
var result = await tools.GetRecentStationChanges(evaNo);
196196

197197
// Assert
198198
Assert.Equal(_testXmlResponse, result);
199199
_mockService.Verify(s => s.GetRecentTimetableChangesAsync(evaNo, default), Times.Once);
200200
}
201201

202202
[Fact]
203-
public async Task GetStationChanges_WithHttpRequestException_ReturnsErrorMessage()
203+
public async Task GetRecentChanges_WithHttpRequestException_ReturnsErrorMessage()
204204
{
205205
// Arrange
206206
var evaNo = "8000105";
@@ -211,15 +211,15 @@ public async Task GetStationChanges_WithHttpRequestException_ReturnsErrorMessage
211211
var tools = new Tools.TimetableTools(_mockService.Object);
212212

213213
// Act
214-
var result = await tools.GetStationChanges(evaNo);
214+
var result = await tools.GetRecentStationChanges(evaNo);
215215

216216
// Assert
217217
Assert.Contains("Error fetching station changes:", result);
218218
Assert.Contains(exceptionMessage, result);
219219
}
220220

221221
[Fact]
222-
public async Task GetStationChanges_WithGeneralException_ReturnsUnexpectedErrorMessage()
222+
public async Task GetRecentChanges_WithGeneralException_ReturnsUnexpectedErrorMessage()
223223
{
224224
// Arrange
225225
var evaNo = "8000105";
@@ -230,7 +230,7 @@ public async Task GetStationChanges_WithGeneralException_ReturnsUnexpectedErrorM
230230
var tools = new Tools.TimetableTools(_mockService.Object);
231231

232232
// Act
233-
var result = await tools.GetStationChanges(evaNo);
233+
var result = await tools.GetRecentStationChanges(evaNo);
234234

235235
// Assert
236236
Assert.Contains("Unexpected error:", result);
@@ -248,7 +248,7 @@ public async Task GetStationDetails_WithValidPattern_ReturnsXmlContent()
248248
var tools = new Tools.TimetableTools(_mockService.Object);
249249

250250
// Act
251-
var result = await tools.GetStationDetails(pattern);
251+
var result = await tools.GetStationInformation(pattern);
252252

253253
// Assert
254254
Assert.Equal(_testXmlResponse, result);
@@ -267,7 +267,7 @@ public async Task GetStationDetails_WithHttpRequestException_ReturnsErrorMessage
267267
var tools = new Tools.TimetableTools(_mockService.Object);
268268

269269
// Act
270-
var result = await tools.GetStationDetails(pattern);
270+
var result = await tools.GetStationInformation(pattern);
271271

272272
// Assert
273273
Assert.Contains("Error fetching station details:", result);
@@ -286,7 +286,7 @@ public async Task GetStationDetails_WithGeneralException_ReturnsUnexpectedErrorM
286286
var tools = new Tools.TimetableTools(_mockService.Object);
287287

288288
// Act
289-
var result = await tools.GetStationDetails(pattern);
289+
var result = await tools.GetStationInformation(pattern);
290290

291291
// Assert
292292
Assert.Contains("Unexpected error:", result);

AbeckDev.DbTimetable.Mcp/Services/TimeTableService.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ public TimeTableService(HttpClient httpClient, IOptions<Configuration> config)
1717
}
1818

1919
/// <summary>
20-
/// Get recent timetable changes for a specific event number
20+
/// Get recent timetable changes for a specific event number. Recent changes are always a subset of the full changes. They may equal full changes but are typically much smaller.
21+
/// Data includes only those changes that became known within the last 2 minutes.
2122
/// </summary>
2223
public async Task<string> GetRecentTimetableChangesAsync(
2324
string eventNo,
@@ -36,30 +37,31 @@ public async Task<string> GetRecentTimetableChangesAsync(
3637
}
3738

3839
/// <summary>
39-
/// Get station board (departures/arrivals) for a specific station
40+
/// Get station board (departures/arrivals) for a specific station in hourly slices.
4041
/// </summary>
4142
public async Task<string> GetStationBoardAsync(
42-
string evaNo,
43+
string evaNo,
4344
DateTime? date = null,
4445
CancellationToken cancellationToken = default)
4546
{
4647
// Format: yyMMddHHmm (e.g., 2511051830 for 2025-11-05 18:30)
4748
var dateParam = date?.ToString("yyMMdd") ?? DateTime.UtcNow.ToString("yyMMdd");
4849
var hourParam = date?.ToString("HH") ?? DateTime.UtcNow.ToString("HH");
49-
50+
5051
using var request = new HttpRequestMessage(HttpMethod.Get, $"plan/{evaNo}/{dateParam}/{hourParam}");
5152
request.Headers.Add("DB-Client-Id", _config.ClientId);
5253
request.Headers.Add("DB-Api-Key", _config.ApiKey);
5354
request.Headers.Add("accept", "application/xml");
54-
55+
5556
var response = await _httpClient.SendAsync(request, cancellationToken);
5657
response.EnsureSuccessStatusCode();
57-
58+
5859
return await response.Content.ReadAsStringAsync(cancellationToken);
5960
}
6061

6162
/// <summary>
62-
/// Get full changes for a station at a specific time
63+
/// Returns a Timetable object (see Timetable) that contains all known changes for the station given by evaNo.
64+
/// The data includes all known changes from now on until ndefinitely into the future. Once changes become obsolete (because their trip departs from the station) they are removed from this resource
6365
/// </summary>
6466
public async Task<string> GetFullChangesAsync(
6567
string evaNo,

AbeckDev.DbTimetable.Mcp/Tools.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public TimetableTools(ITimeTableService timeTableService)
2323
}
2424

2525
[McpServerTool]
26-
[Description("Get full timetable changes for a specific train event. The data includes all known changes from now on until indefinitely into the future. Once changes become obsolete (because their trip departs from the station) they are removed.")]
27-
public async Task<string> GetFullTimetableChanges(
26+
[Description("Get all known timetable changes for the station given by evaNo . The data includes all known changes from now on until indefinitely into the future. Once changes become obsolete (because their trip departs from the station) they are removed.")]
27+
public async Task<string> GetFullStationChanges(
2828
[Description("Event number (EVA number) of the train event")] string eventNo)
2929
{
3030
try
@@ -43,7 +43,7 @@ public async Task<string> GetFullTimetableChanges(
4343
}
4444

4545
[McpServerTool]
46-
[Description("Get station board (departures and arrivals) for a specific station. Returns XML data with train schedules.")]
46+
[Description("Get station board (departures and arrivals) for a specific station in hourly slices. Returns XML data with train schedules.")]
4747
public async Task<string> GetStationBoard(
4848
[Description("EVA station number (e.g., 8000105 for Frankfurt Hauptbahnhof)")] string evaNo,
4949
[Description("Date and time in format 'yyyy-MM-dd HH:mm' (UTC). Leave empty for current time.")] string? dateTime = null)
@@ -77,8 +77,8 @@ public async Task<string> GetStationBoard(
7777
}
7878

7979
[McpServerTool]
80-
[Description("Get all current changes (delays, cancellations, platform changes) for a specific station. Recent changes are always a subset of the full changes. They may equal full changes but are typically much smaller. Data includes only those changes that became known within the last 2 minutes.")]
81-
public async Task<string> GetStationChanges([Description("EVA station number (e.g., 8000105 for Frankfurt Hauptbahnhof)")] string evaNo)
80+
[Description("Get all recent changes (delays, cancellations, platform changes) for a specific station. Recent changes are always a subset of the full changes. They may equal full changes but are typically much smaller. Data includes only those changes that became known within the last 2 minutes.")]
81+
public async Task<string> GetRecentStationChanges([Description("EVA station number (e.g., 8000105 for Frankfurt Hauptbahnhof)")] string evaNo)
8282
{
8383
try
8484
{
@@ -96,8 +96,8 @@ public async Task<string> GetStationBoard(
9696
}
9797

9898
[McpServerTool]
99-
[Description("Get information about stations.")]
100-
public async Task<string> GetStationDetails([Description("Either a station name (prefix), eva number, ds100/rl100 code, wildcard (*); doesn't seem to work with umlauten in station name (prefix). If unsure use the Station Name e.g. \"Dresden Hbf\" ")] string pattern)
99+
[Description("Get information about stations. Returns Name, EVA number and ds100 code for the provided pattern. Can be used to find the EVA station number for a given full text station.")]
100+
public async Task<string> GetStationInformation([Description("Either a station name (prefix), eva number, ds100/rl100 code, wildcard (*); doesn't seem to work with umlauten in station name (prefix). If unsure use the Station Name e.g. \"Dresden Hbf\" ")] string pattern)
101101
{
102102
try
103103
{

0 commit comments

Comments
 (0)