-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathTools.fs
More file actions
63 lines (56 loc) · 2.9 KB
/
Copy pathTools.fs
File metadata and controls
63 lines (56 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
module FsLangMcp.Tools
open System
open System.Threading.Tasks
open FsLangMcp.Types
open FsMcp.Core
open FsMcp.Server
open System.Text.Encodings.Web
open System.Text.Json
open System.Text.Json.Nodes
// ─── MCP helpers ───────────────────────────────────────────────────────────────
let private serializeOpts =
JsonSerializerOptions(Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping)
let private renderOpts =
JsonSerializerOptions(Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, WriteIndented = true)
let toolErrorToJson (err: ToolError) : string =
match err with
| InvalidArgs msg ->
sprintf """{"errorKind":"InvalidArgs","message":%s}""" (JsonSerializer.Serialize(msg, serializeOpts))
| NotReady msg -> sprintf """{"errorKind":"NotReady","message":%s}""" (JsonSerializer.Serialize(msg, serializeOpts))
| InfraFailure ex ->
sprintf """{"errorKind":"InfraFailure","message":%s}""" (JsonSerializer.Serialize(ex.Message, serializeOpts))
| FcsAborted msg ->
sprintf """{"errorKind":"FcsAborted","message":%s}""" (JsonSerializer.Serialize(msg, serializeOpts))
| FileNotFound msg ->
sprintf """{"errorKind":"FileNotFound","message":%s}""" (JsonSerializer.Serialize(msg, serializeOpts))
let renderToken (token: JsonNode) =
JsonSerializer.Serialize(token, renderOpts)
let toolResult (work: Task<JsonNode>) : Task<Result<Content list, McpError>> =
task {
try
let! payload = work
return Ok [ Content.text (renderToken payload) ]
with
| :? OperationCanceledException as ex ->
// TaskCanceledException is a subclass of OperationCanceledException — both caught here
let err = FcsAborted ex.Message
return Error(McpError.TransportError(toolErrorToJson err))
| :? ArgumentException as ex ->
let err = InvalidArgs ex.Message
return Error(McpError.TransportError(toolErrorToJson err))
// Guard for external process exceptions that surface "not ready" text.
// Note: current not-ready paths return via NotReadyResponse() (no exception),
// so this arm is defensive — it would fire if a future external dep raises.
| ex when
ex.Message.IndexOf("not ready", StringComparison.OrdinalIgnoreCase) >= 0
|| ex.Message.IndexOf("NotReady", StringComparison.Ordinal) >= 0
->
let err = NotReady ex.Message
return Error(McpError.TransportError(toolErrorToJson err))
| :? System.IO.FileNotFoundException as ex ->
let err = FileNotFound ex.Message
return Error(McpError.TransportError(toolErrorToJson err))
| ex ->
let err = InfraFailure ex
return Error(McpError.TransportError(toolErrorToJson err))
}