MCP Terminal Server

// Copyright 2024 Google LLC // SPDX-License-Identifier: Apache-2.0 package base import ( "encoding/json" "errors" "fmt" "log" "os" "regexp" "github.com/invopop/jsonschema" ) // JSONString returns json.Marshal(x) as a string. If json.Marshal returns // an error, jsonString returns the error text as a JSON string beginning "ERROR:". func JSONString(x any) string { bytes, err := json.Marshal(x) if err != nil { bytes, _ = json.Marshal(fmt.Sprintf("ERROR: %v", err)) } return string(bytes) } // PrettyJSONString returns json.MarshalIndent(x, "", " ") as a string. // If json.MarshalIndent returns an error, jsonString returns the error text as // a JSON string beginning "ERROR:". func PrettyJSONString(x any) string { bytes, err := json.MarshalIndent(x, "", " ") if err != nil { bytes, _ = json.MarshalIndent(fmt.Sprintf("ERROR: %v", err), "", " ") } return string(bytes) } // WriteJSONFile writes value to filename as JSON. func WriteJSONFile(filename string, value any) error { f, err := os.Create(filename) if err != nil { return err } defer func() { err = errors.Join(err, f.Close()) }() enc := json.NewEncoder(f) enc.SetIndent("", " ") // make the value easy to read for debugging return enc.Encode(value) } // ReadJSONFile JSON-decodes the contents of filename into pvalue, // which must be a pointer. func ReadJSONFile(filename string, pvalue any) error { f, err := os.Open(filename) if err != nil { return err } defer f.Close() return json.NewDecoder(f).Decode(pvalue) } func InferJSONSchema(x any) (s *jsonschema.Schema) { r := jsonschema.Reflector{} s = r.Reflect(x) // TODO: Unwind this change once Monaco Editor supports newer than JSON schema draft-07. s.Version = "" return s } func InferJSONSchemaNonReferencing(x any) (s *jsonschema.Schema) { r := jsonschema.Reflector{ DoNotReference: true, } s = r.Reflect(x) // TODO: Unwind this change once Monaco Editor supports newer than JSON schema draft-07. s.Version = "" return s } // SchemaAsMap convers json schema struct to a map (JSON representation). func SchemaAsMap(s *jsonschema.Schema) map[string]any { jsb, err := s.MarshalJSON() if err != nil { log.Panicf("failed to marshal schema: %v", err) } var m map[string]any err = json.Unmarshal(jsb, &m) if err != nil { log.Panicf("failed to unmarshal schema: %v", err) } return m } var jsonMarkdownRegex = regexp.MustCompile("```(json)?((\n|.)*?)```") // ExtractJSONFromMarkdown returns the contents of the first fenced code block in // the markdown text md. If there is none, it returns md. func ExtractJSONFromMarkdown(md string) string { // TODO: improve this matches := jsonMarkdownRegex.FindStringSubmatch(md) if matches == nil { return md } return matches[2] }