We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jmagar/homelab-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
import { describe, expect, it } from "vitest";
import {
formatScoutAuthMarkdown,
formatScoutDfMarkdown,
formatScoutDiffMarkdown,
formatScoutDmesgMarkdown,
formatScoutExecMarkdown,
formatScoutFindMarkdown,
formatScoutJournalMarkdown,
formatScoutListMarkdown,
formatScoutNodesMarkdown,
formatScoutPsMarkdown,
formatScoutReadMarkdown,
formatScoutSyslogMarkdown,
formatScoutTransferMarkdown,
formatScoutTreeMarkdown,
formatScoutZfsDatasetsMarkdown,
formatScoutZfsPoolsMarkdown,
formatScoutZfsSnapshotsMarkdown,
} from "./scout.js";
describe("scout formatters - emoji removal", () => {
describe("formatScoutReadMarkdown", () => {
it("should NOT contain file emoji π", () => {
const output = formatScoutReadMarkdown("host1", "/path/file.txt", "content", 100, false);
expect(output).not.toContain("π");
});
it("should NOT contain warning emoji β οΈ", () => {
const output = formatScoutReadMarkdown("host1", "/path/file.txt", "content", 100, true);
expect(output).not.toContain("β οΈ");
});
it("should include pipe-separated summary (STYLE.md 3.2)", () => {
const output = formatScoutReadMarkdown("host1", "/path/file.txt", "content", 1024, false);
// Verify pipe-separated summary format: "Size: X | truncated: no"
expect(output).toMatch(/Size: .+ \| truncated: (yes|no)/);
});
});
describe("formatScoutListMarkdown", () => {
it("should NOT contain folder emoji π", () => {
const output = formatScoutListMarkdown("host1", "/path", "listing");
expect(output).not.toContain("π");
});
it("should include pipe-separated summary", () => {
const output = formatScoutListMarkdown("host1", "/path", "file1\nfile2\nfile3");
// Verify summary shows item count
expect(output).toMatch(/Items: \d+/);
});
});
describe("formatScoutTreeMarkdown", () => {
it("should NOT contain tree emoji π³", () => {
const output = formatScoutTreeMarkdown("host1", "/path", "tree output", 2);
expect(output).not.toContain("π³");
});
});
describe("formatScoutExecMarkdown", () => {
it("should NOT contain success emoji β
", () => {
const output = formatScoutExecMarkdown("host1", "/tmp", "ls -la", "output", 0);
expect(output).not.toContain("β
");
});
it("should NOT contain error emoji β", () => {
const output = formatScoutExecMarkdown("host1", "/tmp", "false", "error", 1);
expect(output).not.toContain("β");
});
it("should include freshness timestamp (volatile data)", () => {
const output = formatScoutExecMarkdown("host1", "/tmp", "uptime", "output", 0);
expect(output).toMatch(/As of \([^)]+\): \d{2}:\d{2}:\d{2} \| \d{2}\/\d{2}\/\d{4}/);
});
it("should include exit code in summary", () => {
const successOutput = formatScoutExecMarkdown("host1", "/tmp", "echo test", "output", 0);
expect(successOutput).toMatch(/Exit: 0/);
const errorOutput = formatScoutExecMarkdown("host1", "/tmp", "false", "error", 1);
expect(errorOutput).toMatch(/Exit: 1/);
});
});
describe("formatScoutFindMarkdown", () => {
it("should NOT contain magnifying glass emoji π", () => {
const output = formatScoutFindMarkdown("host1", "/path", "*.txt", "file1.txt\nfile2.txt");
expect(output).not.toContain("π");
});
it("should include pattern and result count in summary", () => {
const output = formatScoutFindMarkdown("host1", "/path", "*.txt", "file1.txt\nfile2.txt");
expect(output).toMatch(/Pattern: \*\.txt \| Results: \d+/);
});
});
describe("formatScoutTransferMarkdown", () => {
it("should NOT contain package emoji π¦", () => {
const output = formatScoutTransferMarkdown(
"host1",
"/src/file.txt",
"host2",
"/dest/file.txt",
100
);
expect(output).not.toContain("π¦");
});
it("should NOT contain warning emoji β οΈ", () => {
const output = formatScoutTransferMarkdown(
"host1",
"/src/file.txt",
"host2",
"/dest/file.txt",
100,
"warning message"
);
expect(output).not.toContain("β οΈ");
});
it("should include source, target, and size in summary", () => {
const output = formatScoutTransferMarkdown(
"host1",
"/src/file.txt",
"host2",
"/dest/file.txt",
1024
);
expect(output).toMatch(/From: host1 \| To: host2 \| Size: .+/);
});
});
describe("formatScoutDiffMarkdown", () => {
it("should NOT contain chart emoji π", () => {
const output = formatScoutDiffMarkdown(
"host1",
"/path/file1",
"host2",
"/path/file2",
"diff output"
);
expect(output).not.toContain("π");
});
it("should include both file paths in summary", () => {
const output = formatScoutDiffMarkdown(
"host1",
"/path/file1",
"host2",
"/path/file2",
"diff output"
);
expect(output).toMatch(/File 1: host1:\/path\/file1 \| File 2: host2:\/path\/file2/);
});
});
});
describe("formatScoutTreeMarkdown summary", () => {
it("should include depth in summary", () => {
const output = formatScoutTreeMarkdown("host1", "/path", "tree", 3);
expect(output).toMatch(/Depth: \d+/);
});
});
describe("formatScoutNodesMarkdown", () => {
it("should format multiple hosts as table", () => {
const hosts = ["squirts", "boops", "nicks"];
const output = formatScoutNodesMarkdown(hosts);
// Should have table header
expect(output).toMatch(/\| Host \|/);
// Should have all hosts
expect(output).toContain("squirts");
expect(output).toContain("boops");
expect(output).toContain("nicks");
});
it("should include host count in summary", () => {
const hosts = ["squirts", "boops"];
const output = formatScoutNodesMarkdown(hosts);
expect(output).toMatch(/Hosts: 2/);
});
});
describe("formatScoutPsMarkdown", () => {
it("should include freshness timestamp for volatile process data", () => {
const processes = "PID COMMAND\n1234 nginx\n5678 node";
const output = formatScoutPsMarkdown("squirts", processes);
expect(output).toMatch(/As of \(EST\): \d{2}:\d{2}:\d{2} \| \d{2}\/\d{2}\/\d{4}/);
});
it("should include process count in summary", () => {
const processes = "PID COMMAND\n1234 nginx\n5678 node";
const output = formatScoutPsMarkdown("squirts", processes);
expect(output).toMatch(/Processes: \d+/);
});
});
describe("formatScoutDfMarkdown", () => {
it("should include freshness timestamp for volatile disk data", () => {
const diskUsage =
"Filesystem Size Used Avail Use% Mounted on\n/dev/sda1 100G 50G 50G 50% /";
const output = formatScoutDfMarkdown("squirts", diskUsage);
expect(output).toMatch(/As of \(EST\): \d{2}:\d{2}:\d{2} \| \d{2}\/\d{2}\/\d{4}/);
});
it("should include warning symbol for filesystems over 85% usage", () => {
const diskUsage =
"Filesystem Size Used Avail Use% Mounted on\n/dev/sda1 100G 90G 10G 90% /";
const output = formatScoutDfMarkdown("squirts", diskUsage);
expect(output).toContain("β ");
});
it("should not include warning for filesystems under 85% usage", () => {
const diskUsage =
"Filesystem Size Used Avail Use% Mounted on\n/dev/sda1 100G 50G 50G 50% /";
const output = formatScoutDfMarkdown("squirts", diskUsage);
expect(output.match(/β /g)).toBeNull();
});
});
describe("formatScoutSyslogMarkdown", () => {
it("should include freshness timestamp for volatile log data", () => {
const logs = "Feb 13 11:00:00 squirts sshd: Connection from 192.168.1.1";
const output = formatScoutSyslogMarkdown("squirts", 50, logs);
expect(output).toMatch(/As of \(EST\): \d{2}:\d{2}:\d{2} \| \d{2}\/\d{2}\/\d{4}/);
});
it("should include request echo showing lines requested", () => {
const logs = "Feb 13 11:00:00 squirts sshd: Connection from 192.168.1.1";
const output = formatScoutSyslogMarkdown("squirts", 50, logs);
expect(output).toMatch(/Lines requested: 50/);
});
it("should include grep filter in request echo when provided", () => {
const logs = "Feb 13 11:00:00 squirts sshd: Connection from 192.168.1.1";
const output = formatScoutSyslogMarkdown("squirts", 50, logs, "sshd");
expect(output).toMatch(/Filter: sshd/);
});
});
describe("formatScoutJournalMarkdown", () => {
it("should include freshness timestamp and request echo", () => {
const logs = "Feb 13 11:30:00 squirts systemd[1]: Started service";
const output = formatScoutJournalMarkdown("squirts", 100, logs);
expect(output).toMatch(/As of \(EST\): \d{2}:\d{2}:\d{2} \| \d{2}\/\d{2}\/\d{4}/);
expect(output).toMatch(/Lines requested: 100/);
});
});
describe("formatScoutDmesgMarkdown", () => {
it("should include freshness timestamp and request echo", () => {
const logs = "[ 0.000000] Linux version 6.1.0-generic";
const output = formatScoutDmesgMarkdown("squirts", 200, logs);
expect(output).toMatch(/As of \(EST\): \d{2}:\d{2}:\d{2} \| \d{2}\/\d{2}\/\d{4}/);
expect(output).toMatch(/Lines requested: 200/);
});
});
describe("formatScoutAuthMarkdown", () => {
it("should include freshness timestamp and request echo", () => {
const logs = "Feb 13 11:00:00 squirts sshd[1234]: Accepted publickey for user";
const output = formatScoutAuthMarkdown("squirts", 50, logs);
expect(output).toMatch(/As of \(EST\): \d{2}:\d{2}:\d{2} \| \d{2}\/\d{2}\/\d{4}/);
expect(output).toMatch(/Lines requested: 50/);
});
});
describe("formatScoutZfsPoolsMarkdown", () => {
it("should include health status symbols for pools", () => {
const pools =
"NAME SIZE ALLOC FREE HEALTH ALTROOT\ntank 10.9T 8.2T 2.7T ONLINE -";
const output = formatScoutZfsPoolsMarkdown("squirts", pools);
// Should show ONLINE status with β symbol per STYLE.md 4.1
expect(output).toContain("β");
});
it("should include warning symbol for degraded pools", () => {
const pools =
"NAME SIZE ALLOC FREE HEALTH ALTROOT\ntank 10.9T 8.2T 2.7T DEGRADED -";
const output = formatScoutZfsPoolsMarkdown("squirts", pools);
// Should show DEGRADED status with β symbol
expect(output).toContain("β ");
});
it("should include error symbol for faulted pools", () => {
const pools =
"NAME SIZE ALLOC FREE HEALTH ALTROOT\ntank 10.9T 8.2T 2.7T FAULTED -";
const output = formatScoutZfsPoolsMarkdown("squirts", pools);
// Should show FAULTED status with β symbol
expect(output).toContain("β");
});
it("should include pool count in summary", () => {
const pools =
"NAME SIZE ALLOC FREE HEALTH ALTROOT\ntank 10.9T 8.2T 2.7T ONLINE -\nbackup 5.4T 2.1T 3.3T ONLINE -";
const output = formatScoutZfsPoolsMarkdown("squirts", pools);
expect(output).toMatch(/Pools: 2/);
});
});
describe("formatScoutZfsDatasetsMarkdown", () => {
it("should include warning symbol for datasets over 85% used", () => {
const datasets =
"NAME USED AVAIL REFER MOUNTPOINT\ntank/media 8.2T 2.7T 8.2T /mnt/media";
const output = formatScoutZfsDatasetsMarkdown("squirts", datasets);
// 8.2T used / (8.2T + 2.7T) total = 75% - no warning
expect(output).not.toContain("β ");
});
it("should include warning for high usage datasets", () => {
const datasets =
"NAME USED AVAIL REFER MOUNTPOINT\ntank/media 9.3T 1.0T 9.3T /mnt/media";
const output = formatScoutZfsDatasetsMarkdown("squirts", datasets);
// 9.3T used / (9.3T + 1.0T) total = 90% - should warn
expect(output).toContain("β ");
});
it("should include dataset count in summary", () => {
const datasets =
"NAME USED AVAIL REFER MOUNTPOINT\ntank/media 8.2T 2.7T 8.2T /mnt/media\ntank/backup 2.1T 3.3T 2.1T /mnt/backup";
const output = formatScoutZfsDatasetsMarkdown("squirts", datasets);
expect(output).toMatch(/Datasets: 2/);
});
it("should correctly parse large unit suffixes for warnings", () => {
const datasets =
"NAME USED AVAIL REFER MOUNTPOINT\ntank/archive 9.5P 0.5P 9.5P /mnt/archive";
const output = formatScoutZfsDatasetsMarkdown("squirts", datasets);
expect(output).toContain("β ");
});
});
describe("formatScoutZfsSnapshotsMarkdown", () => {
it("should include snapshot count in summary", () => {
const snapshots =
"NAME USED REFER\ntank/media@2024-02-13 512M 8.2T\ntank/media@2024-02-12 256M 8.1T";
const output = formatScoutZfsSnapshotsMarkdown("squirts", snapshots);
expect(output).toMatch(/Snapshots: 2/);
});
it("should format snapshot timestamps", () => {
const snapshots =
"NAME USED REFER\ntank/media@2024-02-13 512M 8.2T";
const output = formatScoutZfsSnapshotsMarkdown("squirts", snapshots);
// Should preserve snapshot name with @ separator
expect(output).toContain("@");
});
});