@jrpool/kilotest 59.0.4 → 59.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/api/orderNewTest.ts +1 -1
- package/api/orderRetest.ts +1 -1
- package/api/util.ts +1 -1
- package/capability.md +1 -1
- package/docs/AI-TOOLS.md +1 -1
- package/env.example +1 -1
- package/lhm.plugin.json +25 -25
- package/llms-full.txt +1 -1
- package/llms.txt +1 -1
- package/mcp.test.ts +4 -4
- package/mcp.ts +31 -35
- package/openapi.yaml +2 -2
- package/package.json +1 -1
- package/scripts/generate-openapi.ts +1 -1
- package/server.json +2 -2
- package/util.ts +1 -1
- package/web/home/index.html +4 -4
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ An ensemble testing and reporting service for front-end web quality
|
|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
13
|
-
This application uses an ensemble of 12 rule engines to test web pages for front-end quality (i.e. accessibility, usability, and standards
|
|
13
|
+
This application uses an ensemble of 12 rule engines to test web pages for front-end quality (i.e. accessibility, usability, and web standards).
|
|
14
14
|
|
|
15
15
|
The testing paradigm employed by Kilotest is discussed in these papers:
|
|
16
16
|
|
|
@@ -40,7 +40,7 @@ In the steps below, hosts `T` and `K` may be the same host or two different host
|
|
|
40
40
|
|
|
41
41
|
### Usage
|
|
42
42
|
|
|
43
|
-
1. In the `testaro` directory, make Testaro start listening for jobs: `node call netWatch true nn true`, where `nn` is the number of seconds to wait between checks for new jobs. Note that Kilotest promises nearly immediate review and, on approval, immediate execution of “orders” for tests and retests, with typical total elapsed time
|
|
43
|
+
1. In the `testaro` directory, make Testaro start listening for jobs: `node call netWatch true nn true`, where `nn` is the number of seconds to wait between checks for new jobs. Note that Kilotest promises nearly immediate review and, on approval, immediate execution of “orders” for tests and retests, with typical total elapsed time 2 to 4 minutes. That promise implies a promise to keep `nn` small. A reasonable value is between 10 and 20.
|
|
44
44
|
1. In the `kilotest` directory, start the Kilotest service: `node index`.
|
|
45
45
|
|
|
46
46
|
### Contributing
|
package/api/orderNewTest.ts
CHANGED
|
@@ -93,7 +93,7 @@ export const response = async (args: string[]) => {
|
|
|
93
93
|
'what happens next': 'Testing has begun. Once it finishes, the report will be available via the listIssues tool.',
|
|
94
94
|
'report identifier': {timeStamp, jobID: reportJobID},
|
|
95
95
|
'how you can check for completion': `Call the listIssues tool with timeStamp "${timeStamp}" and jobID "${reportJobID}" to learn whether the report is ready.`,
|
|
96
|
-
'do you want to wait for completion': 'Testing typically takes
|
|
96
|
+
'do you want to wait for completion': 'Testing typically takes 2 to 4 minutes. Do you want to wait (and be notified of completion) instead of checking back later? If so, call the awaitTest tool with the same timeStamp and jobID.'
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
else {
|
package/api/orderRetest.ts
CHANGED
|
@@ -68,7 +68,7 @@ export const response = async (args: string[]) => {
|
|
|
68
68
|
'what happens next': 'Testing has begun. Once it finishes, the report will be available via the listIssues tool.',
|
|
69
69
|
'report identifier': {timeStamp: reportTimeStamp, jobID: reportJobID},
|
|
70
70
|
'how you can check for completion': `Call the listIssues tool with timeStamp "${reportTimeStamp}" and jobID "${reportJobID}" to learn whether the report is ready.`,
|
|
71
|
-
'do you want to wait for completion': 'Testing typically takes
|
|
71
|
+
'do you want to wait for completion': 'Testing typically takes 2 to 4 minutes. Do you want to wait (and be notified of completion) instead of checking back later? If so, call the awaitTest tool with the same timeStamp and jobID.'
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
74
|
else {
|
package/api/util.ts
CHANGED
|
@@ -51,7 +51,7 @@ export const getResponseMetadata = () => ({
|
|
|
51
51
|
export const getToolsFacts = () => ({
|
|
52
52
|
'name': 'Kilotest',
|
|
53
53
|
'description': {
|
|
54
|
-
'what Kilotest does': 'Kilotest tools generate and make available findings about the front-end quality (i.e. accessibility, usability, and standards
|
|
54
|
+
'what Kilotest does': 'Kilotest tools generate and make available findings about the front-end quality (i.e. accessibility, usability, and web standards) of web pages. A Kilotest job generates findings by using Testaro to test a page against about 1300 rules defined by an ensemble of twelve rule engines. Testaro produces a report of the job. The report describes violations of the rules. Kilotest uses Testilo to enhance the report with a classification of the rule violations into about 380 issues. Kilotest makes facts about the tested pages, the issues, and the violations retrievable at four levels of granularity.',
|
|
55
55
|
'how to retrieve findings': {
|
|
56
56
|
'level 1': 'Use the listPages tool to get a list of tested pages, each with its latest report. The listIssues output about any report lists all reports about the same page.',
|
|
57
57
|
'level 2': 'Use the listIssues tool to get a list of issues in one report.',
|
package/capability.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Capability
|
|
4
4
|
|
|
5
|
-
Web-page front-end quality audit. Kilotest tests web pages for front-end quality, namely accessibility, usability, and standards
|
|
5
|
+
Web-page front-end quality audit. Kilotest tests web pages for front-end quality, namely accessibility, usability, and web standards, and makes structured findings available for retrieval.
|
|
6
6
|
|
|
7
7
|
## Purpose
|
|
8
8
|
|
package/docs/AI-TOOLS.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Until 2026 Kilotest was intended, and implemented, as a web application performing a service for human users.
|
|
6
6
|
|
|
7
|
-
Beginning in May 2026, it [became evident](https://github.com/jrpool/kilotest/issues/2) that Kilotest could operate as a set of tools for language models to allow them to improve their answers to questions about the front-end quality (accessibility, usability, and standards
|
|
7
|
+
Beginning in May 2026, it [became evident](https://github.com/jrpool/kilotest/issues/2) that Kilotest could operate as a set of tools for language models to allow them to improve their answers to questions about the front-end quality (accessibility, usability, and web standards) of specific web pages.
|
|
8
8
|
|
|
9
9
|
A decision was made to **make Kilotest discoverable, usable, and, where appropriate, used as a provider of tools for language models**.
|
|
10
10
|
|
package/env.example
CHANGED
|
@@ -54,7 +54,7 @@ JOB_QUEUE_MAX=__placeholder__
|
|
|
54
54
|
|
|
55
55
|
# Timing for the awaitTest MCP tool's wait on a job ordered via orderNewTest/orderRetest.
|
|
56
56
|
# Defaults: 2000ms poll interval, 300000ms (5 minutes) maximum wait. The maximum wait
|
|
57
|
-
# deliberately exceeds the "
|
|
57
|
+
# deliberately exceeds the "2 to 4 minutes" callers are told to expect, to
|
|
58
58
|
# leave margin so a job that is genuinely still running is not mistaken for one that
|
|
59
59
|
# never will finish. Lower values are useful for local testing.
|
|
60
60
|
|
package/lhm.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Jonathan Robert Pool",
|
|
3
3
|
"cloudEndpoint": "https://kilotest.com/mcp",
|
|
4
|
-
"description": "Tools that test web pages for front-end quality (accessibility, usability, and standards
|
|
4
|
+
"description": "Tools that test web pages for front-end quality (accessibility, usability, and web standards) and make test results available",
|
|
5
5
|
"homepage": "https://github.com/jrpool/kilotest",
|
|
6
6
|
"identifier": "jrpool-kilotest",
|
|
7
7
|
"name": "Kilotest",
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
"tools": [
|
|
19
19
|
{
|
|
20
20
|
"name": "getKilotestOverview",
|
|
21
|
-
"description": "
|
|
21
|
+
"description": "Explains what Kilotest is, what its tools do, and how its results are structured. Use this before any other tool when the available tools or workflow are unclear. Returns a prose overview of the Kilotest domain, the tool workflow, and links to further documentation. Kilotest integrates an ensemble of 12 rule engines, with about 1,300 rules, to test web pages for front-end quality (accessibility, usability, and web standards). Each test session generates a standardized report describing which elements violated which rules and grouping the violations into about 380 issues. Kilotest can list the tested pages, the reports about each page, the issues in each report, the violators of each issue, and the diagnoses of each violation. Kilotest also accepts requests to test pages not yet tested and to retest already tested pages.",
|
|
22
22
|
"inputSchema": {
|
|
23
23
|
"type": "object",
|
|
24
24
|
"properties": {},
|
|
25
25
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
26
26
|
},
|
|
27
27
|
"annotations": {
|
|
28
|
-
"title": "Explain
|
|
28
|
+
"title": "Explain Kilotest and its tools",
|
|
29
29
|
"readOnlyHint": true,
|
|
30
30
|
"destructiveHint": false,
|
|
31
31
|
"idempotentHint": true,
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"name": "listPages",
|
|
40
|
-
"description": "
|
|
40
|
+
"description": "Lists all pages Kilotest has tested. Use this first to discover whether a page already has a report before requesting a test. Returns, for each tested page, its description, URL, and the timestamp and job identifier of its latest report.",
|
|
41
41
|
"inputSchema": {
|
|
42
42
|
"type": "object",
|
|
43
43
|
"properties": {},
|
|
@@ -400,7 +400,7 @@
|
|
|
400
400
|
}
|
|
401
401
|
},
|
|
402
402
|
"annotations": {
|
|
403
|
-
"title": "
|
|
403
|
+
"title": "List tested pages",
|
|
404
404
|
"readOnlyHint": true,
|
|
405
405
|
"destructiveHint": false,
|
|
406
406
|
"idempotentHint": true,
|
|
@@ -412,7 +412,7 @@
|
|
|
412
412
|
},
|
|
413
413
|
{
|
|
414
414
|
"name": "listIssues",
|
|
415
|
-
"description": "
|
|
415
|
+
"description": "Lists the issues reported in one report, along with the history of all reports about the same page. Use this after listPages to drill into a specific report, identified by its timestamp and job identifier. Returns basics about the report's issues and a list of every report about the same page, from oldest to latest.",
|
|
416
416
|
"inputSchema": {
|
|
417
417
|
"type": "object",
|
|
418
418
|
"properties": {
|
|
@@ -1139,7 +1139,7 @@
|
|
|
1139
1139
|
}
|
|
1140
1140
|
},
|
|
1141
1141
|
"annotations": {
|
|
1142
|
-
"title": "
|
|
1142
|
+
"title": "List issues in a report",
|
|
1143
1143
|
"readOnlyHint": true,
|
|
1144
1144
|
"destructiveHint": false,
|
|
1145
1145
|
"idempotentHint": true,
|
|
@@ -1151,7 +1151,7 @@
|
|
|
1151
1151
|
},
|
|
1152
1152
|
{
|
|
1153
1153
|
"name": "listViolators",
|
|
1154
|
-
"description": "
|
|
1154
|
+
"description": "Lists the elements of a tested page that were reported as exhibiting one issue in one report. Use this after listIssues to drill from an issue down to the elements it affects. Returns basics about each violating element, including its identifier in the page's element catalog.",
|
|
1155
1155
|
"inputSchema": {
|
|
1156
1156
|
"type": "object",
|
|
1157
1157
|
"properties": {
|
|
@@ -1645,7 +1645,7 @@
|
|
|
1645
1645
|
}
|
|
1646
1646
|
},
|
|
1647
1647
|
"annotations": {
|
|
1648
|
-
"title": "
|
|
1648
|
+
"title": "List elements exhibiting an issue",
|
|
1649
1649
|
"readOnlyHint": true,
|
|
1650
1650
|
"destructiveHint": false,
|
|
1651
1651
|
"idempotentHint": true,
|
|
@@ -1657,7 +1657,7 @@
|
|
|
1657
1657
|
},
|
|
1658
1658
|
{
|
|
1659
1659
|
"name": "listDiagnoses",
|
|
1660
|
-
"description": "
|
|
1660
|
+
"description": "Lists the diagnoses that rule engines gave for how one element exhibited one issue in one report. Use this after listViolators to drill from an element down to the rule-engine explanations of why it was flagged. Returns, for each rule engine that reported the issue on that element, its diagnosis.",
|
|
1661
1661
|
"inputSchema": {
|
|
1662
1662
|
"type": "object",
|
|
1663
1663
|
"properties": {
|
|
@@ -2169,7 +2169,7 @@
|
|
|
2169
2169
|
}
|
|
2170
2170
|
},
|
|
2171
2171
|
"annotations": {
|
|
2172
|
-
"title": "
|
|
2172
|
+
"title": "List diagnoses of a violation",
|
|
2173
2173
|
"readOnlyHint": true,
|
|
2174
2174
|
"destructiveHint": false,
|
|
2175
2175
|
"idempotentHint": true,
|
|
@@ -2181,7 +2181,7 @@
|
|
|
2181
2181
|
},
|
|
2182
2182
|
{
|
|
2183
2183
|
"name": "getReport",
|
|
2184
|
-
"description": "
|
|
2184
|
+
"description": "Retrieves one entire report as JSON, with all of its issues, violators, and diagnoses. Use this instead of drilling down through listIssues, listViolators, and listDiagnoses when the full report is needed in one call. Returns the complete report data for the specified timestamp and job identifier.",
|
|
2185
2185
|
"inputSchema": {
|
|
2186
2186
|
"type": "object",
|
|
2187
2187
|
"properties": {
|
|
@@ -2432,7 +2432,7 @@
|
|
|
2432
2432
|
}
|
|
2433
2433
|
},
|
|
2434
2434
|
"annotations": {
|
|
2435
|
-
"title": "Get
|
|
2435
|
+
"title": "Get a full report",
|
|
2436
2436
|
"readOnlyHint": true,
|
|
2437
2437
|
"destructiveHint": false,
|
|
2438
2438
|
"idempotentHint": true,
|
|
@@ -2444,7 +2444,7 @@
|
|
|
2444
2444
|
},
|
|
2445
2445
|
{
|
|
2446
2446
|
"name": "requestNewTest",
|
|
2447
|
-
"description": "
|
|
2447
|
+
"description": "Submits a request to test a page that has no report yet; queued for manual approval. Use orderNewTest instead for immediate, automatically approved testing. Returns a request confirmation with disposition details.",
|
|
2448
2448
|
"inputSchema": {
|
|
2449
2449
|
"type": "object",
|
|
2450
2450
|
"properties": {
|
|
@@ -2791,7 +2791,7 @@
|
|
|
2791
2791
|
}
|
|
2792
2792
|
},
|
|
2793
2793
|
"annotations": {
|
|
2794
|
-
"title": "
|
|
2794
|
+
"title": "Request testing of a new page",
|
|
2795
2795
|
"readOnlyHint": false,
|
|
2796
2796
|
"destructiveHint": false,
|
|
2797
2797
|
"idempotentHint": false,
|
|
@@ -2803,7 +2803,7 @@
|
|
|
2803
2803
|
},
|
|
2804
2804
|
{
|
|
2805
2805
|
"name": "requestRetest",
|
|
2806
|
-
"description": "
|
|
2806
|
+
"description": "Submits a request to retest a page whose existing report is obsolete; queued for manual approval. Use orderRetest instead for immediate, automatically approved retesting. Returns a request confirmation with disposition details.",
|
|
2807
2807
|
"inputSchema": {
|
|
2808
2808
|
"type": "object",
|
|
2809
2809
|
"properties": {
|
|
@@ -3140,7 +3140,7 @@
|
|
|
3140
3140
|
}
|
|
3141
3141
|
},
|
|
3142
3142
|
"annotations": {
|
|
3143
|
-
"title": "
|
|
3143
|
+
"title": "Request a retest",
|
|
3144
3144
|
"readOnlyHint": false,
|
|
3145
3145
|
"destructiveHint": false,
|
|
3146
3146
|
"idempotentHint": false,
|
|
@@ -3152,7 +3152,7 @@
|
|
|
3152
3152
|
},
|
|
3153
3153
|
{
|
|
3154
3154
|
"name": "requestFeature",
|
|
3155
|
-
"description": "
|
|
3155
|
+
"description": "Submits a request to add a new feature or improve an existing one; queued for manual review. There is no immediate-approval alternative for feature requests. Returns a request confirmation with disposition details.",
|
|
3156
3156
|
"inputSchema": {
|
|
3157
3157
|
"type": "object",
|
|
3158
3158
|
"properties": {
|
|
@@ -3414,7 +3414,7 @@
|
|
|
3414
3414
|
}
|
|
3415
3415
|
},
|
|
3416
3416
|
"annotations": {
|
|
3417
|
-
"title": "
|
|
3417
|
+
"title": "Request a feature",
|
|
3418
3418
|
"readOnlyHint": false,
|
|
3419
3419
|
"destructiveHint": false,
|
|
3420
3420
|
"idempotentHint": false,
|
|
@@ -3426,7 +3426,7 @@
|
|
|
3426
3426
|
},
|
|
3427
3427
|
{
|
|
3428
3428
|
"name": "orderNewTest",
|
|
3429
|
-
"description": "
|
|
3429
|
+
"description": "Orders testing of a page that has no report yet, with automated approval or rejection and immediate enqueueing if approved. Use this instead of requestNewTest when immediate testing is wanted; testing typically takes 2 to 4 minutes. Returns an order confirmation and disposition details, including, if approved, a report identifier (timestamp and job identifier) and a question about whether to wait for completion with the awaitTest tool.",
|
|
3430
3430
|
"inputSchema": {
|
|
3431
3431
|
"type": "object",
|
|
3432
3432
|
"properties": {
|
|
@@ -3798,7 +3798,7 @@
|
|
|
3798
3798
|
}
|
|
3799
3799
|
},
|
|
3800
3800
|
"annotations": {
|
|
3801
|
-
"title": "
|
|
3801
|
+
"title": "Order immediate testing of a new page",
|
|
3802
3802
|
"readOnlyHint": false,
|
|
3803
3803
|
"destructiveHint": false,
|
|
3804
3804
|
"idempotentHint": false,
|
|
@@ -3810,7 +3810,7 @@
|
|
|
3810
3810
|
},
|
|
3811
3811
|
{
|
|
3812
3812
|
"name": "orderRetest",
|
|
3813
|
-
"description": "
|
|
3813
|
+
"description": "Orders a retest of a page whose existing report is considered obsolete, with automated approval or rejection and immediate enqueuing if approved. Use this instead of requestRetest when immediate retesting is wanted; testing typically takes 2 to 4 minutes. Returns an order confirmation and disposition details, including, if approved, a report identifier (timestamp and job identifier) and a question about whether to wait for completion with the awaitTest tool.",
|
|
3814
3814
|
"inputSchema": {
|
|
3815
3815
|
"type": "object",
|
|
3816
3816
|
"properties": {
|
|
@@ -4172,7 +4172,7 @@
|
|
|
4172
4172
|
}
|
|
4173
4173
|
},
|
|
4174
4174
|
"annotations": {
|
|
4175
|
-
"title": "
|
|
4175
|
+
"title": "Order an immediate retest",
|
|
4176
4176
|
"readOnlyHint": false,
|
|
4177
4177
|
"destructiveHint": false,
|
|
4178
4178
|
"idempotentHint": false,
|
|
@@ -4184,7 +4184,7 @@
|
|
|
4184
4184
|
},
|
|
4185
4185
|
{
|
|
4186
4186
|
"name": "awaitTest",
|
|
4187
|
-
"description": "
|
|
4187
|
+
"description": "Waits for a job ordered via the orderNewTest or orderRetest tool to finish, using the report identifier either tool returned. Use this instead of polling listIssues when an immediate answer is preferred. Blocks until the report is ready, the job fails, or a maximum wait time elapses, sending no interim notices; returns the finished job's status and, if ready, its report identifier.",
|
|
4188
4188
|
"inputSchema": {
|
|
4189
4189
|
"type": "object",
|
|
4190
4190
|
"properties": {
|
|
@@ -4495,7 +4495,7 @@
|
|
|
4495
4495
|
}
|
|
4496
4496
|
},
|
|
4497
4497
|
"annotations": {
|
|
4498
|
-
"title": "Wait for
|
|
4498
|
+
"title": "Wait for an ordered job to finish",
|
|
4499
4499
|
"readOnlyHint": true,
|
|
4500
4500
|
"destructiveHint": false,
|
|
4501
4501
|
"idempotentHint": false,
|
package/llms-full.txt
CHANGED
|
@@ -160,7 +160,7 @@ Kilotest offers these tools:
|
|
|
160
160
|
- `timeStamp`: initial segment of the report identifier returned by `orderNewTest` or `orderRetest`
|
|
161
161
|
- `jobID`: final segment of the report identifier returned by `orderNewTest` or `orderRetest`
|
|
162
162
|
- source of parameters: response to an `orderNewTest` or `orderRetest` request
|
|
163
|
-
- caveat: testing typically takes
|
|
163
|
+
- caveat: testing typically takes 2 to 4 minutes; sends no interim notices while waiting
|
|
164
164
|
|
|
165
165
|
## After a test, retest, or feature request
|
|
166
166
|
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Kilotest
|
|
2
2
|
|
|
3
|
-
Kilotest helps language models and AI platforms to give thorough, accurate and truthful answers when users ask about the front-end quality (i.e. accessibility, usability, and standards
|
|
3
|
+
Kilotest helps language models and AI platforms to give thorough, accurate and truthful answers when users ask about the front-end quality (i.e. accessibility, usability, and web standards) of web pages. Kilotest integrates an ensemble of twelve independent rule engines to test a web page. Kilotest creates a structured report of the results and saves the report for future reference. Kilotest API endpoints and MCP tools can provide multipage, single-page, and element-level test results.
|
|
4
4
|
|
|
5
5
|
## API
|
|
6
6
|
|
package/mcp.test.ts
CHANGED
|
@@ -62,12 +62,12 @@ test('each tool has a description and a handler function', () => {
|
|
|
62
62
|
const tools = (server as any)._registeredTools;
|
|
63
63
|
for (const [name, tool] of Object.entries(tools) as [string, any][]) {
|
|
64
64
|
assert.ok(tool.description, `${name} has a description`);
|
|
65
|
-
assert.ok(
|
|
66
|
-
tool.description.includes('front-end quality'),
|
|
67
|
-
`${name} description includes the shared domain context`
|
|
68
|
-
);
|
|
69
65
|
assert.equal(typeof tool.handler, 'function', `${name} has a handler function`);
|
|
70
66
|
}
|
|
67
|
+
// Only getKilotestOverview repeats the shared domain context in its own description; the
|
|
68
|
+
// other tools rely on the server instructions for that context, so their descriptions stay
|
|
69
|
+
// focused on what each tool does, when to use it, and what it returns.
|
|
70
|
+
assert.ok(tools.getKilotestOverview.description.includes('front-end quality'));
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
test('getKilotestOverview handler returns overview text and records a metric', async () => {
|
package/mcp.ts
CHANGED
|
@@ -50,16 +50,16 @@ import {
|
|
|
50
50
|
|
|
51
51
|
export const mcpPath = '/mcp';
|
|
52
52
|
|
|
53
|
-
// Shared statement of the Kilotest domain and data hierarchy, repeated in
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
// description to their models.
|
|
57
|
-
const sharedContext = 'Kilotest
|
|
53
|
+
// Shared statement of the Kilotest domain and data hierarchy, repeated in the server
|
|
54
|
+
// instructions and in the getKilotestOverview tool description (but not in the other tool
|
|
55
|
+
// descriptions, to avoid diluting how models read each tool), because some MCP clients do
|
|
56
|
+
// not propagate server-level instructions or the server description to their models.
|
|
57
|
+
const sharedContext = 'Kilotest integrates an ensemble of 12 rule engines, with about 1,300 rules, to test web pages for front-end quality (accessibility, usability, and web standards). Each test job generates a standardized report describing which elements violated which rules and grouping the violations into about 380 issues. Kilotest can list the tested pages, the reports about each page, the issues in each report, the violators of each issue, and the diagnoses of each violation. Kilotest also accepts requests to test pages not yet tested and to retest already tested pages.';
|
|
58
58
|
|
|
59
59
|
// Detailed overview of the Kilotest domain, data hierarchy, and tool workflow, returned by
|
|
60
60
|
// the getKilotestOverview tool and served as the docs://kilotest/overview resource.
|
|
61
61
|
const kilotestOverview = [
|
|
62
|
-
'Kilotest tests web pages for front-end quality: accessibility, usability, and standards
|
|
62
|
+
'Kilotest tests web pages for front-end quality: accessibility, usability, and web standards.',
|
|
63
63
|
'Kilotest integrates an ensemble of twelve independent rule engines to test a web page and stores the results as a structured report.',
|
|
64
64
|
'Results are organized as a hierarchy. A tested page has one or more reports, from oldest to latest. A report contains issues. An issue has violators: elements of the tested page reported as exhibiting the issue. A violator has diagnoses: explanations from rule engines of how the element exhibited the issue.',
|
|
65
65
|
'Typical workflow: call the listPages tool to learn whether the page has been tested. If it has, drill down from its latest report with the listIssues, listViolators, and listDiagnoses tools, or retrieve the entire report with the getReport tool. The listIssues output also lists all reports about the same page, so you can examine earlier reports. If the page has not been tested, request a test with the requestNewTest tool. If the latest report is obsolete, request a retest with the requestRetest tool.',
|
|
@@ -69,16 +69,12 @@ const kilotestOverview = [
|
|
|
69
69
|
|
|
70
70
|
// FUNCTIONS
|
|
71
71
|
|
|
72
|
-
// Returns a tool description consisting of the tool-specific summary followed by the shared
|
|
73
|
-
// Kilotest domain context.
|
|
74
|
-
const toolDoc = (summary: string): string => `${summary} ${sharedContext}`;
|
|
75
|
-
|
|
76
72
|
// Creates and returns an McpServer with Kilotest tools registered.
|
|
77
73
|
export const createMCPServer = (): McpServer => {
|
|
78
74
|
const server = new McpServer({
|
|
79
75
|
name: 'Kilotest',
|
|
80
76
|
version,
|
|
81
|
-
description: 'Tools that test web pages for front-end quality (accessibility, usability, and standards
|
|
77
|
+
description: 'Tools that test web pages for front-end quality (accessibility, usability, and web standards) and make test results available'
|
|
82
78
|
},
|
|
83
79
|
{
|
|
84
80
|
instructions: `${sharedContext} Use the listPages tool to start. If it shows that the page you want facts about has been tested, drill down from its latest report with the listIssues, listViolators, and listDiagnoses tools. If not, use the requestNewTest tool to request that the page be tested, or the orderNewTest tool for immediate, automatically approved testing. If the latest report about the page is obsolete, use the requestRetest tool to request that the page be retested, or the orderRetest tool for immediate, automatically approved retesting. For detailed documentation, call the getKilotestOverview tool.`
|
|
@@ -86,10 +82,10 @@ export const createMCPServer = (): McpServer => {
|
|
|
86
82
|
server.registerTool(
|
|
87
83
|
'getKilotestOverview',
|
|
88
84
|
{
|
|
89
|
-
description:
|
|
85
|
+
description: `Explains what Kilotest is, what its tools do, and how its results are structured. Use this before any other tool when the available tools or workflow are unclear. Returns a prose overview of the Kilotest domain, the tool workflow, and links to further documentation. ${sharedContext}`,
|
|
90
86
|
inputSchema: {},
|
|
91
87
|
annotations: {
|
|
92
|
-
title:
|
|
88
|
+
title: 'Explain Kilotest and its tools',
|
|
93
89
|
readOnlyHint: true,
|
|
94
90
|
idempotentHint: true,
|
|
95
91
|
destructiveHint: false,
|
|
@@ -104,11 +100,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
104
100
|
server.registerTool(
|
|
105
101
|
'listPages',
|
|
106
102
|
{
|
|
107
|
-
description:
|
|
103
|
+
description: 'Lists all pages Kilotest has tested. Use this first to discover whether a page already has any reports before requesting a test. Returns, for each tested page, its description, URL, and the timestamp and job identifier of its latest available report.',
|
|
108
104
|
inputSchema: {},
|
|
109
105
|
outputSchema: listPagesResponseSchema,
|
|
110
106
|
annotations: {
|
|
111
|
-
title:
|
|
107
|
+
title: 'List tested pages',
|
|
112
108
|
readOnlyHint: true,
|
|
113
109
|
idempotentHint: true,
|
|
114
110
|
destructiveHint: false,
|
|
@@ -124,11 +120,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
124
120
|
server.registerTool(
|
|
125
121
|
'listIssues',
|
|
126
122
|
{
|
|
127
|
-
description:
|
|
123
|
+
description: 'Lists the issues reported in one report, along with the history of all reports about the same page. Use this after listPages to switch to an earlier or later report or to begin examining this report. Returns the history and the basics about this report’s issues.',
|
|
128
124
|
inputSchema: listIssuesSchema,
|
|
129
125
|
outputSchema: listIssuesResponseSchema,
|
|
130
126
|
annotations: {
|
|
131
|
-
title:
|
|
127
|
+
title: 'List issues in a report',
|
|
132
128
|
readOnlyHint: true,
|
|
133
129
|
idempotentHint: true,
|
|
134
130
|
destructiveHint: false,
|
|
@@ -144,11 +140,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
144
140
|
server.registerTool(
|
|
145
141
|
'listViolators',
|
|
146
142
|
{
|
|
147
|
-
description:
|
|
143
|
+
description: 'Lists the elements of a tested page that were reported as exhibiting one issue in one report. Use this after listIssues to drill down from an issue to the elements violating rules belonging to that issue. Returns basics about each violating element.',
|
|
148
144
|
inputSchema: listViolatorsSchema,
|
|
149
145
|
outputSchema: listViolatorsResponseSchema,
|
|
150
146
|
annotations: {
|
|
151
|
-
title:
|
|
147
|
+
title: 'List elements exhibiting an issue',
|
|
152
148
|
readOnlyHint: true,
|
|
153
149
|
idempotentHint: true,
|
|
154
150
|
destructiveHint: false,
|
|
@@ -164,11 +160,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
164
160
|
server.registerTool(
|
|
165
161
|
'listDiagnoses',
|
|
166
162
|
{
|
|
167
|
-
description:
|
|
163
|
+
description: 'Lists the diagnoses that rule engines gave for how one element exhibited one issue in one report. Use this after listViolators to get details about the element as a violator of the issue. Returns, for each rule engine that reported a violation by the element of a rule belonging to the issue, the diagnosis given by the rule engine.',
|
|
168
164
|
inputSchema: listDiagnosesSchema,
|
|
169
165
|
outputSchema: listDiagnosesResponseSchema,
|
|
170
166
|
annotations: {
|
|
171
|
-
title:
|
|
167
|
+
title: 'List diagnoses of a violation',
|
|
172
168
|
readOnlyHint: true,
|
|
173
169
|
idempotentHint: true,
|
|
174
170
|
destructiveHint: false,
|
|
@@ -184,11 +180,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
184
180
|
server.registerTool(
|
|
185
181
|
'getReport',
|
|
186
182
|
{
|
|
187
|
-
description:
|
|
183
|
+
description: 'Retrieves one entire report as JSON, with all of its issues, violators, and diagnoses. Use this instead of drilling down through listIssues, listViolators, and listDiagnoses when the full report is needed in one call. Returns the complete report data for the specified timestamp and job identifier. The size of the report is disclosed by the listIssues tool.',
|
|
188
184
|
inputSchema: getReportSchema,
|
|
189
185
|
outputSchema: getReportResponseSchema,
|
|
190
186
|
annotations: {
|
|
191
|
-
title:
|
|
187
|
+
title: 'Get a full report',
|
|
192
188
|
readOnlyHint: true,
|
|
193
189
|
idempotentHint: true,
|
|
194
190
|
destructiveHint: false,
|
|
@@ -204,11 +200,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
204
200
|
server.registerTool(
|
|
205
201
|
'requestNewTest',
|
|
206
202
|
{
|
|
207
|
-
description:
|
|
203
|
+
description: 'Submits a request to test a page that has no report yet; queued for manager approval. Use orderNewTest instead for immediate, automatically approved testing. Returns a request confirmation with disposition details.',
|
|
208
204
|
inputSchema: requestNewTestSchema,
|
|
209
205
|
outputSchema: requestNewTestResponseSchema,
|
|
210
206
|
annotations: {
|
|
211
|
-
title:
|
|
207
|
+
title: 'Request testing of a new page',
|
|
212
208
|
readOnlyHint: false,
|
|
213
209
|
idempotentHint: false,
|
|
214
210
|
destructiveHint: false,
|
|
@@ -224,11 +220,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
224
220
|
server.registerTool(
|
|
225
221
|
'requestRetest',
|
|
226
222
|
{
|
|
227
|
-
description:
|
|
223
|
+
description: 'Submits a request to retest a page whose existing report is considered obsolete; queued for manager approval. Use orderRetest instead for immediate, automatically approved retesting. Returns a request confirmation with disposition details.',
|
|
228
224
|
inputSchema: requestRetestSchema,
|
|
229
225
|
outputSchema: requestRetestResponseSchema,
|
|
230
226
|
annotations: {
|
|
231
|
-
title:
|
|
227
|
+
title: 'Request a retest',
|
|
232
228
|
readOnlyHint: false,
|
|
233
229
|
idempotentHint: false,
|
|
234
230
|
destructiveHint: false,
|
|
@@ -244,11 +240,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
244
240
|
server.registerTool(
|
|
245
241
|
'requestFeature',
|
|
246
242
|
{
|
|
247
|
-
description:
|
|
243
|
+
description: 'Submits a request to add a new feature or improve an existing one; queued for manager review. There is no immediate-approval alternative for feature requests. Returns a request confirmation with disposition details.',
|
|
248
244
|
inputSchema: requestFeatureSchema,
|
|
249
245
|
outputSchema: requestFeatureResponseSchema,
|
|
250
246
|
annotations: {
|
|
251
|
-
title:
|
|
247
|
+
title: 'Request a feature',
|
|
252
248
|
readOnlyHint: false,
|
|
253
249
|
idempotentHint: false,
|
|
254
250
|
destructiveHint: false,
|
|
@@ -264,11 +260,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
264
260
|
server.registerTool(
|
|
265
261
|
'orderNewTest',
|
|
266
262
|
{
|
|
267
|
-
description:
|
|
263
|
+
description: 'Orders testing of a page that has no report yet, with automated approval or rejection and immediate enqueueing if approved. Use this instead of requestNewTest when immediate testing is wanted; testing typically takes 2 to 4 minutes. Returns an order confirmation and disposition details, including, if approved, a report identifier (timestamp and job identifier) and a question about whether to wait for completion with the awaitTest tool.',
|
|
268
264
|
inputSchema: orderNewTestSchema,
|
|
269
265
|
outputSchema: orderNewTestResponseSchema,
|
|
270
266
|
annotations: {
|
|
271
|
-
title:
|
|
267
|
+
title: 'Order immediate testing of a new page',
|
|
272
268
|
readOnlyHint: false,
|
|
273
269
|
idempotentHint: false,
|
|
274
270
|
destructiveHint: false,
|
|
@@ -284,11 +280,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
284
280
|
server.registerTool(
|
|
285
281
|
'orderRetest',
|
|
286
282
|
{
|
|
287
|
-
description:
|
|
283
|
+
description: 'Orders a retest of a page whose existing report is considered obsolete, with automated approval or rejection and immediate enqueuing if approved. Use this instead of requestRetest when immediate retesting is wanted; testing typically takes 2 to 4 minutes. Returns an order confirmation and disposition details, including, if approved, a report identifier (timestamp and job identifier) and a question about whether to wait for completion with the awaitTest tool.',
|
|
288
284
|
inputSchema: orderRetestSchema,
|
|
289
285
|
outputSchema: orderRetestResponseSchema,
|
|
290
286
|
annotations: {
|
|
291
|
-
title:
|
|
287
|
+
title: 'Order an immediate retest',
|
|
292
288
|
readOnlyHint: false,
|
|
293
289
|
idempotentHint: false,
|
|
294
290
|
destructiveHint: false,
|
|
@@ -304,11 +300,11 @@ export const createMCPServer = (): McpServer => {
|
|
|
304
300
|
server.registerTool(
|
|
305
301
|
'awaitTest',
|
|
306
302
|
{
|
|
307
|
-
description:
|
|
303
|
+
description: 'Waits for a job ordered via the orderNewTest or orderRetest tool to finish, using the report identifier either tool returned. Use this instead of polling listIssues when an immediate answer is preferred. Blocks until the report is ready, the job fails, or a maximum wait time elapses, sending no interim notices; returns the finished job’s status and, if ready, its report identifier.',
|
|
308
304
|
inputSchema: awaitTestSchema,
|
|
309
305
|
outputSchema: awaitTestResponseSchema,
|
|
310
306
|
annotations: {
|
|
311
|
-
title:
|
|
307
|
+
title: 'Wait for an ordered job to finish',
|
|
312
308
|
readOnlyHint: true,
|
|
313
309
|
idempotentHint: false,
|
|
314
310
|
destructiveHint: false,
|
package/openapi.yaml
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
openapi: 3.1.0
|
|
2
2
|
info:
|
|
3
3
|
title: Kilotest API
|
|
4
|
-
description: 'Kilotest is an ensemble testing and reporting service for front-end web quality. It uses an ensemble of 12 rule engines to test web pages for front-end quality (accessibility, usability, and standards
|
|
5
|
-
version:
|
|
4
|
+
description: 'Kilotest is an ensemble testing and reporting service for front-end web quality. It uses an ensemble of 12 rule engines to test web pages for front-end quality (accessibility, usability, and web standards). Kilotest acts as a web server for human users, an MCP server for AI platforms, and an API for programmatic access. With this API you can request that a page be tested or retested, discover available reports, incrementally retrieve facts from a report: from what reports are available, to what issues were reported in one report, to what elements violated one issue, to what diagnoses rule engines gave for one violation.'
|
|
5
|
+
version: 59.1.0
|
|
6
6
|
license:
|
|
7
7
|
name: MIT
|
|
8
8
|
identifier: MIT
|
package/package.json
CHANGED
|
@@ -58,7 +58,7 @@ const generate = () => {
|
|
|
58
58
|
openapi: '3.1.0',
|
|
59
59
|
info: {
|
|
60
60
|
title: 'Kilotest API',
|
|
61
|
-
description: 'Kilotest is an ensemble testing and reporting service for front-end web quality. It uses an ensemble of 12 rule engines to test web pages for front-end quality (accessibility, usability, and standards
|
|
61
|
+
description: 'Kilotest is an ensemble testing and reporting service for front-end web quality. It uses an ensemble of 12 rule engines to test web pages for front-end quality (accessibility, usability, and web standards). Kilotest acts as a web server for human users, an MCP server for AI platforms, and an API for programmatic access. With this API you can request that a page be tested or retested, discover available reports, incrementally retrieve facts from a report: from what reports are available, to what issues were reported in one report, to what elements violated one issue, to what diagnoses rule engines gave for one violation.',
|
|
62
62
|
version,
|
|
63
63
|
license: {
|
|
64
64
|
name: license,
|
package/server.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.jrpool/kilotest",
|
|
4
|
-
"description": "Ensemble testing of web pages for accessibility, usability, and standards
|
|
4
|
+
"description": "Ensemble testing of web pages for accessibility, usability, and web standards",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/jrpool/kilotest",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "59.
|
|
9
|
+
"version": "59.1.0",
|
|
10
10
|
"remotes": [
|
|
11
11
|
{
|
|
12
12
|
"type": "streamable-http",
|
package/util.ts
CHANGED
|
@@ -1205,7 +1205,7 @@ export const orderJob = (
|
|
|
1205
1205
|
// waits before giving up. Both are read at call time (not cached), via environment
|
|
1206
1206
|
// variables, so tests can shrink them well below the real ~2-to-4-minute wait a
|
|
1207
1207
|
// production caller experiences; AWAIT_JOB_TIMEOUT_MS deliberately exceeds the
|
|
1208
|
-
// documented "
|
|
1208
|
+
// documented "2 to 4 minutes" a caller is told to expect, leaving margin
|
|
1209
1209
|
// so a job that is genuinely still running is not mistaken for one that never will
|
|
1210
1210
|
// finish.
|
|
1211
1211
|
const awaitJobPollMs = () => getEnvMax('AWAIT_JOB_POLL_MS', 2000);
|
package/web/home/index.html
CHANGED
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
"sameAs": "https://github.com/jrpool/kilotest",
|
|
17
17
|
"datePublished": "2025-10-14",
|
|
18
18
|
"dateModified": "2026-08-26",
|
|
19
|
-
"applicationCategory": "Front-end quality (i.e.
|
|
19
|
+
"applicationCategory": "Front-end quality (i.e. accessibility, usability, and web standards) testing and reporting service",
|
|
20
20
|
"isAccessibleForFree": true,
|
|
21
|
-
"description": "Testing of web pages for front-end quality (i.e.
|
|
21
|
+
"description": "Testing of web pages for front-end quality (i.e. accessibility, usability, and web standards) with an ensemble of 12 rule engines and provision of results at selectable levels of detail.",
|
|
22
22
|
"softwareHelp": {
|
|
23
23
|
"@type": "CreativeWork",
|
|
24
24
|
"url": "https://kilotest.com/tutorialWeb.html"
|
|
25
25
|
},
|
|
26
26
|
"featureList": [
|
|
27
|
-
"Automated testing of front-end quality (i.e.
|
|
27
|
+
"Automated testing of front-end quality (i.e. accessibility, usability, and web standards)",
|
|
28
28
|
"WCAG 2.2 conformance evaluation",
|
|
29
29
|
"HTML5 conformance evaluation",
|
|
30
30
|
"CSS3 conformance evaluation",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
<details>
|
|
63
63
|
<summary>More than a thousand? Really?</summary>
|
|
64
64
|
<h2>Ensemble testing</h2>
|
|
65
|
-
<p>Kilotest does <strong>ensemble testing</strong> of web pages for <a href="https://www.w3.org/mission/accessibility/">accessibility</a>, usability, and standards
|
|
65
|
+
<p>Kilotest does <strong>ensemble testing</strong> of web pages for <a href="https://www.w3.org/mission/accessibility/">accessibility</a>, usability, and web standards.</p>
|
|
66
66
|
<p>Efficient testing <strong>first</strong> leverages <strong>automated rule engines</strong> and corrects the defects that they discover, <strong>then</strong> employs human testers.</p>
|
|
67
67
|
<p>Choosing among the <a href="https://www.w3.org/WAI/test-evaluate/tools/list/">many automated rule engines</a> is hard, because they <a href="https://arxiv.org/pdf/2304.07591">vary in what and how they test</a>.</p>
|
|
68
68
|
<p><strong>Ensemble testing</strong>, instead of choosing only one, combines <strong>multiple rule engines</strong>. It can discover more issues than single-rule-engine testing, and the rule engines can check one another’s quality.</p>
|