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 agentmods add skills/signnow/sn-mcp-server/sn-testingnpx skills add signnow/sn-mcp-server --skill sn-testinggit clone --depth 1 https://github.com/signnow/sn-mcp-serverWrote 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/signnow/sn-mcp-server/sn-testing)<a href="https://agentmods.dev/skills/signnow/sn-mcp-server/sn-testing"><img src="https://agentmods.dev/badge/skills/signnow/sn-mcp-server/sn-testing.svg" alt="Measured on agentmods" 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.00081 | $0.01554 |
| Opus 5 | $0.00041 | $0.00777 |
| Sonnet 5 | $0.00016 | $0.00311 |
| Haiku 4.5 | $0.00008 | $0.00155 |
Grade A, and why
sn-testing 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 5d ago.
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 — 174 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Testing Standards
Analyze Protocol
Before writing tests, evaluate each change with the 3 YES criteria — at least one must be met:
- Business Logic: Does the change affect business logic?
- Regression Risk: Is it prone to regression?
- Complexity: Is it complex enough to benefit from tests?
Do not write useless tests. Quality over quantity.
Testing Strategy by Layer
A. Tool Business Logic (sn_mcp_server/tools/<feature>.py)
- Type: Unit. Isolation: Mock
SignNowAPIClientviaMagicMock. Mockfastmcp.ContextviaAsyncMockwhen function acceptsctx. - Focus: Data transformation, curated response fields, edge cases (empty data, missing optionals), error propagation, status normalization.
class TestFeatureName:
"""Test cases for _feature_function."""
@pytest.fixture
def mock_client(self):
"""Create a mock SignNowAPIClient."""
return MagicMock()
def test_feature_happy_path(self, mock_client):
"""Test successful execution with valid data."""
mock_client.api_method.return_value = SampleModel(...)
result = _feature_function(mock_client, "test_token", "param_value")
assert isinstance(result, ExpectedResponseModel)
assert result.field == "expected_value"
mock_client.api_method.assert_called_once_with("test_token", "param_value")
B. Tool Response Models (sn_mcp_server/tools/models.py)
- Type: Unit. Focus: Construction, defaults,
from_*factories, status normalization, edge cases.
class TestResponseModel:
"""Test cases for ResponseModel."""
def test_model_construction_with_defaults(self):
"""Test model handles missing optional fields."""
model = ResponseModel(id="test123", name="Test")
assert model.optional_field is None
@pytest.mark.parametrize("raw_status,expected", [
("sent", "pending"),
("fulfilled", "completed"),
])
def test_status_normalization(self, raw_status, expected):
"""Test raw API status maps to unified status."""
result = InviteStatusValues.from_raw_status(raw_status)
assert result == expected
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.
- 5d ago First seen · 174 lines · 81 tokens per session scan A 3e9f7a744a1e
sn-testing is a skill published in the GitHub repository signnow/sn-mcp-server (8 stars, last pushed 1mo ago), licensed MIT. It adds 81 tokens to every session and 1,554 once invoked, about $0.0004 per session on Opus 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-08-31.
Other skills, from other repositories
webhook-handler-patterns
Best practices for webhook handlers: verify → parse → handle idempotently. Covers idempotency, error handling, retry logic, framework-specific gotchas (Express, Next.js, FastAPI). Use when implementing any webhook receiver.
api
FastAPI + async/sync HTTP client patterns, JWT auth, multi-provider routing, Pydantic request/response models, CORS, background tasks, and typed frontend API clients — synthesized from lead-gen-engine and seo-geo-aeo-engine.
webfetch
Fetch live web pages, inspect responses, extract relevant content, and summarize findings with links.
free-business-template-library
Finds relevant PandaDoc business document templates in a catalog of 1,000+ free templates and returns direct links for customization and eSignature. Use when the user asks for a ready-made business document template or wants to find, browse, compare, or select PandaDoc templates for proposals, contracts, agreements…
datamodel-code-generator
Use this skill when the user wants Python data models, Pydantic models, dataclasses, TypedDicts, msgspec structs, or type-safe Python classes generated from OpenAPI, AsyncAPI, JSON Schema, GraphQL, JSON/YAML/CSV sample data, MCP tool schemas, Protocol Buffers, XML Schema, Apache Avro, or existing Python model objects.…
trellis-start
Initializes an AI development session by reading workflow guides, developer identity, git status, active tasks, and project guidelines from .trellis/. Classifies incoming tasks and routes to brainstorm, direct edit, or task workflow. Use when beginning a new coding session, resuming work, starting a new task, or…