Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add nezolder/civil3d-mcp-roslyn --skill compare_surface_elevationsgit clone --depth 1 https://github.com/nezolder/civil3d-mcp-roslynWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/nezolder/civil3d-mcp-roslyn/compare_surface_elevations)<a href="https://agentmods.dev/skills/nezolder/civil3d-mcp-roslyn/compare_surface_elevations"><img src="https://agentmods.dev/badge/skills/nezolder/civil3d-mcp-roslyn/compare_surface_elevations/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/nezolder/civil3d-mcp-roslyn/compare_surface_elevations"><img src="https://agentmods.dev/badge/skills/nezolder/civil3d-mcp-roslyn/compare_surface_elevations.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00024 | $0.02185 |
| Opus 5.5 | $0.00010 | $0.00874 |
| Sonnet 5.5 | $0.00005 | $0.00437 |
| Haiku 4.5 | $0.00002 | $0.00218 |
Grade A, and why
compare_surface_elevations scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured today.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 158 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Code Template
var surfaceAHandle = "REFERENCE_SURFACE_HANDLE";
var surfaceBHandle = "COMPARISON_SURFACE_HANDLE";
var samplePoints = new (double x, double y)[] { };
var tolerance = double.NaN;
var detailLimit = 50;
var isHandle = new Func<string, bool>(value =>
!string.IsNullOrWhiteSpace(value)
&& System.Text.RegularExpressions.Regex.IsMatch(value, "^[0-9A-Fa-f]{1,16}$")
&& long.TryParse(value, System.Globalization.NumberStyles.HexNumber,
System.Globalization.CultureInfo.InvariantCulture, out var parsed) && parsed > 0);
if (!isHandle(surfaceAHandle) || !isHandle(surfaceBHandle)
|| surfaceAHandle.Equals(surfaceBHandle, StringComparison.OrdinalIgnoreCase))
return new { success = false, error = "Configure two distinct positive hexadecimal TIN surface handles." };
if (samplePoints == null || samplePoints.Length < 1 || samplePoints.Length > 2000
|| samplePoints.Any(p => !Double.IsFinite(p.x) || !Double.IsFinite(p.y))
|| samplePoints.Distinct().Count() != samplePoints.Length)
return new { success = false, error = "Supply 1..2000 distinct finite XY sample points." };
if (!Double.IsFinite(tolerance) || tolerance < 0 || detailLimit < 1 || detailLimit > 200)
return new { success = false, error = "Tolerance must be finite/nonnegative and detailLimit must be 1..200." };
// Pure statistics also support host-free arithmetic verification.
var summarize = new Func<double[], object>(values => {
if (values.Length == 0) return null;
if (values.Any(v => !Double.IsFinite(v))) throw new InvalidOperationException("Nonfinite differences cannot enter statistics.");
var absolute = values.Select(Math.Abs).OrderBy(v => v).ToArray();
var signed = values.OrderBy(v => v).ToArray();
var scale = absolute[absolute.Length - 1];
var normalized = values.Select(v => scale == 0 ? 0 : v / scale).ToArray();
var normalizedMean = normalized.Average();
var mean = normalizedMean * scale;
var rmse = Math.Sqrt(normalized.Average(v => v * v)) * scale;
var standardDeviation = Math.Sqrt(normalized.Average(v => (v - normalizedMean) * (v - normalizedMean))) * scale;
var mae = (scale == 0 ? 0 : absolute.Average(v => v / scale)) * scale;
var percentile = new Func<double[], double, double>((sorted, fraction) => {
var position = (sorted.Length - 1) * fraction;
var lo = (int)Math.Floor(position);
var hi = (int)Math.Ceiling(position);
var f = position - lo;
return sorted[lo] * (1 - f) + sorted[hi] * f;
});
if (!Double.IsFinite(mean) || !Double.IsFinite(rmse) || !Double.IsFinite(standardDeviation) || !Double.IsFinite(mae))
throw new InvalidOperationException("Statistics overflowed; no misleading finite result is returned.");
var within = absolute.Count(v => v <= tolerance);
return new {
count = values.Length, mean, rmse, mae, standardDeviation,
min = signed[0], max = signed[signed.Length - 1], median = percentile(signed, 0.5),
p95Absolute = percentile(absolute, 0.95), withinTolerance = within,
outsideTolerance = values.Length - within, withinTolerancePercent = 100.0 * within / values.Length
};
});
// Host access starts here.
ObjectId aId;
ObjectId bId;
try
{
aId = Database.GetObjectId(false, new Handle(Convert.ToInt64(surfaceAHandle, 16)), 0);
bId = Database.GetObjectId(false, new Handle(Convert.ToInt64(surfaceBHandle, 16)), 0);
}
catch { return new { success = false, error = "A requested surface handle does not resolve in this drawing." }; }
if (aId == bId) return new { success = false, error = "The two handles resolve to the same surface." };
var surfaceA = Transaction.GetObject(aId, OpenMode.ForRead) as TinSurface;
var surfaceB = Transaction.GetObject(bId, OpenMode.ForRead) as TinSurface;
if (surfaceA == null || surfaceB == null || surfaceA.IsErased || surfaceB.IsErased
|| surfaceA is TinVolumeSurface || surfaceB is TinVolumeSurface)
return new { success = false, error = "Two existing non-volume TIN surfaces are required." };
foreach (var surface in new[] { surfaceA, surfaceB })
if (surface.IsReferenceObject && (!surface.IsReferenceValid || surface.IsReferenceStale || !surface.IsReferencedSourceExisting))
return new { success = false, error = "A reference surface is invalid, stale or missing its source." };
var differences = new List<double>();
var rows = new List<object>();
var missingA = 0;
var missingB = 0;
var lookupErrors = 0;
var nonfiniteDifferences = 0;
var lookup = new Func<TinSurface, double, double, (bool available, double z, string status)>((surface, x, y) => {
try
{
var z = surface.FindElevationAtXY(x, y);
return Double.IsFinite(z) ? (true, z, "available") : (false, 0, "nonfinite_elevation");
}
catch (Autodesk.Civil.PointNotOnEntityException) { return (false, 0, "outside_surface"); }
catch { lookupErrors++; return (false, 0, "lookup_error"); }
});
foreach (var p in samplePoints)
{
var a = lookup(surfaceA, p.x, p.y);
var b = lookup(surfaceB, p.x, p.y);
if (!a.available) missingA++;
if (!b.available) missingB++;
double? difference = null;
if (a.available && b.available)
{
var delta = b.z - a.z;
if (Double.IsFinite(delta)) { difference = delta; differences.Add(delta); }
else nonfiniteDifferences++;
}
if (rows.Count < detailLimit)
rows.Add(new {
x = p.x, y = p.y,
elevationA = a.available ? (double?)a.z : null,
elevationB = b.available ? (double?)b.z : null,
statusA = a.status, statusB = b.status, difference
});
}
return new {
success = true, surfaceA = new { handle = surfaceA.Handle.ToString(), name = surfaceA.Name },
surfaceB = new { handle = surfaceB.Handle.ToString(), name = surfaceB.Name },
differenceDefinition = "B minus A", units = CivilDoc.Settings.DrawingSettings.UnitZoneSettings.DrawingUnits.ToString(),
tolerance, total = samplePoints.Length, valid = differences.Count,
missingA, missingB, lookupErrors, nonfiniteDifferences,
coveragePercent = 100.0 * differences.Count / samplePoints.Length,
returned = rows.Count, truncated = samplePoints.Length > rows.Count, limit = detailLimit,
statistics = summarize(differences.ToArray()), samples = rows
};
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- today First seen · 158 lines · 24 tokens per session scan A a2b33c14c14d
compare_surface_elevations is a skill published in the GitHub repository nezolder/civil3d-mcp-roslyn (3 stars, last pushed today), licensed MIT. It adds 24 tokens to every session and 2,185 once invoked, about $0.0001 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-10-02.
Other skills, from other repositories
research-engineer
An uncompromising Academic Research Engineer. Operates with absolute scientific rigor, objective criticism, and zero flair. Focuses on theoretical correctness, formal verification, and optimal implementation across any required technology.
eval-dataset-design
A guide to creating reliable test sets for AI agents. Each evaluation task includes the request, the simulated user's behaviour, a reset starting state, and a success check that can be independently verified.
tika-eval-compare
Compare extracts from two Tika builds over a corpus to detect regressions in content, encoding, exceptions, and embedded-document handling. Use for "compare before/after extracts", "eval this change against the corpus".
cua-driver
Use Cua Driver for desktop or browser tasks that are awkward or unavailable through Bash/APIs, or when the user explicitly wants GUI interaction: app testing, visual bug reproduction, form filling, calendar entry, screenshots, and demo recording. Also covers Cua setup; not OpenAI Codex Computer Use or web research.
jetson-validate-image
Use after jetson-flash-image to run static BSP checks, on-target smoke/regression tests on a flashed DUT, or both. Not for build or flash steps. Triggers: validate bsp, on-target validation.
atmos-validation
Validate Atmos projects, components, arbitrary JSON Schema inputs, EditorConfig, and GitHub Actions; use affected-file selection and native CI annotations.