Convert between YAML and JSON via @mukundakatta/yaml-mcp (npx)
How do you convert between YAML and JSON from an AI agent via MCP? The server should parse YAML strings (including multi-document streams) into JSON-compatible values, and serialize JSON objects back to indented YAML. Essential for agents working with Kubernetes manifests, CI pipeline configs (GitHub Actions, GitLab CI), Docker Compose files, or any YAML-based configuration.
Recipe: Convert YAML ↔ JSON via @mukundakatta/yaml-mcp (npx)
Surface: @mukundakatta/yaml-mcp v0.1.0 (npm) — bin name mcp-yaml Transport: stdio (JSON-RPC 2.0, newline-delimited) Auth: none required Tools: 2 — to_json, to_yaml
Server info
name: "yaml", version: "0.1.0"
capabilities: toolsTool schemas
{
"name": "to_json",
"description": "Parse YAML and return the JSON-compatible value.",
"inputSchema": {
"type": "object",
"properties": {
"text": { "type": "string", "description": "YAML source." },
"all_documents": { "type": "boolean", "default": false, "description": "If true, parse a multi-document YAML stream and return an array of docs." }
},
"required": ["text"]
}
}{
"name": "to_yaml",
"description": "Serialize a JSON-compatible value to YAML.",
"inputSchema": {
"type": "object",
"properties": {
"value": { "description": "JSON value to serialize. Any type." },
"indent": { "type": "integer", "default": 2, "description": "Indent width." }
},
"required": ["value"]
}
}Setup & gotcha
Important: The npx -y @mukundakatta/yaml-mcp approach silently fails because of an import.meta.url guard in the entry point. You must either:
- Install globally:
npm install -g @mukundakatta/yaml-mcpthen runnode $(npm root -g)/@mukundakatta/yaml-mcp/dist/server.js - Or spawn the
dist/server.jsfile directly after npx caches the package
Verified trace
Request: to_json — parse a YAML server config into JSON
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"to_json","arguments":{"text":"name: my-api\nversion: 2.1.0\nserver:\n port: 8080\n host: 0.0.0.0\n cors:\n origins:\n - https://app.example.com\n - https://staging.example.com\n methods: [GET, POST, PUT, DELETE]\ndatabase:\n url: postgres://localhost:5432/mydb\n pool_size: 10\n ssl: true\nfeature_flags:\n new_dashboard: true\n beta_api: false"}}}Response: (truncated for readability)
{"result":{"content":[{"type":"text","text":"{\"value\":{\"name\":\"my-api\",\"version\":\"2.1.0\",\"server\":{\"port\":8080,\"host\":\"0.0.0.0\",\"cors\":{\"origins\":[\"https://app.example.com\",\"https://staging.example.com\"],\"methods\":[\"GET\",\"POST\",\"PUT\",\"DELETE\"]}},\"database\":{\"url\":\"postgres://localhost:5432/mydb\",\"pool_size\":10,\"ssl\":true},\"feature_flags\":{\"new_dashboard\":true,\"beta_api\":false}}}"}]},"jsonrpc":"2.0","id":3}Request: to_yaml — serialize a Kubernetes ConfigMap JSON to YAML
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"to_yaml","arguments":{"value":{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"app-config","namespace":"production","labels":{"app":"my-api","env":"prod"}},"data":{"DATABASE_URL":"postgres://db:5432/prod","REDIS_URL":"redis://cache:6379","LOG_LEVEL":"info","MAX_CONNECTIONS":"100"}}}}}Response:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
labels:
app: my-api
env: prod
data:
DATABASE_URL: postgres://db:5432/prod
REDIS_URL: redis://cache:6379
LOG_LEVEL: info
MAX_CONNECTIONS: "100"Notes
- Backed by the
yamlnpm package (YAML 1.2 compliant) to_jsonwraps parsed value in{"value": ...}— unwrap in your agentto_yamlaccepts any JSON-serializable value, not just objectsall_documents: truehandles multi-doc YAML streams (separated by---)indentparam controls YAML output indentation (default 2 spaces)- Numeric strings like
"100"are preserved as strings in YAML output (correctly quoted)
{ "server": "@mukundakatta/yaml-mcp", "version": "0.1.0", "transport": "stdio", "launch": "node $(npm root -g)/@mukundakatta/yaml-mcp/dist/server.js", "tools": ["to_json", "to_yaml"], "trace": [ { "request": { "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "to_json", "arguments": { "text": "name: my-api version: 2.1.0 server: port: 8080 host: 0.0.0.0 cors: origins: - https://app.example.com - https://staging.example.com methods: [GET, POST, PUT, DELETE] database: url: postgres://localhost:5432/mydb pool_size: 10 ssl: true feature_flags: new_dashboard: true beta_api: false" } } }, "response": { "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "{"value":{"name":"my-api","version":"2.1.0","server":{"port":8080,"host":"0.0.0.0","cors":{"origins":["https://app.example.com","https://staging.example.com"],"methods":["GET","POST","PUT","DELETE"]}},"database":{"url":"postgres://localhost:5432/mydb","pool_size":10,"ssl":true},"feature_flags":{"new_dashboard":true,"beta_api":false}}}" } ] } } }, { "request": { "jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": { "name": "to_yaml", "arguments": { "value": { "apiVersion": "v1", "kind": "ConfigMap", "metadata": { "name": "app-config", "namespace": "production", "labels": { "app": "my-api", "env": "prod" } }, "data": { "DATABASE_URL": "postgres://db:5432/prod", "REDIS_URL": "redis://cache:6379", "LOG_LEVEL": "info", "MAX_CONNECTIONS": "100" } } } } }, "response": { "jsonrpc": "2.0", "id": 4, "result": { "content": [ { "type": "text", "text": "apiVersion: v1 kind: ConfigMap metadata: name: app-config namespace: production labels: app: my-api env: prod data: DATABASE_URL: postgres://db:5432/prod REDIS_URL: redis://cache:6379 LOG_LEVEL: info MAX_CONNECTIONS: "100" " } ] } } } ], "gotcha": "npx fails silently due to import.meta.url guard — must run dist/server.js directly or install globally" }