technical-answer-validator 0.1.0__tar.gz → 0.1.1__tar.gz
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.
- technical_answer_validator-0.1.1/.github/workflows/publish-mcp-registry.yml +29 -0
- technical_answer_validator-0.1.1/PKG-INFO +35 -0
- technical_answer_validator-0.1.1/README.md +25 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/pyproject.toml +7 -2
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/server.json +5 -4
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/uv.lock +1 -1
- technical_answer_validator-0.1.0/PKG-INFO +0 -92
- technical_answer_validator-0.1.0/README.md +0 -82
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/.dockerignore +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/.env.example +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/.github/workflows/ci.yml +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/.github/workflows/publish-container.yml +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/.github/workflows/publish-pypi.yml +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/.gitignore +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/Dockerfile +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/LICENSE +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/NOTICE.md +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/PUBLISHING.md +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/claude-mcp-config.example.json +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/codex-mcp-config.example.toml +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/compose.yaml +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/mcp_server.py +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/openapi.yaml +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/requirements.txt +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/scripts/create_api_key.py +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/tav_api.py +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/tav_core.py +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/tests/test_api.py +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/tests/test_mcp_server.py +0 -0
- {technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/tests/test_tav.py +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Publish MCP server to Registry
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
tags:
|
|
7
|
+
- "v*"
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
id-token: write
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v5
|
|
20
|
+
- name: Install MCP Publisher
|
|
21
|
+
run: |
|
|
22
|
+
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_linux_amd64.tar.gz" | tar xz mcp-publisher
|
|
23
|
+
chmod +x mcp-publisher
|
|
24
|
+
- name: Validate server descriptor
|
|
25
|
+
run: ./mcp-publisher validate server.json
|
|
26
|
+
- name: Authenticate to MCP Registry
|
|
27
|
+
run: ./mcp-publisher login github-oidc
|
|
28
|
+
- name: Publish server metadata
|
|
29
|
+
run: ./mcp-publisher publish server.json
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: technical-answer-validator
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: MCP and REST tools for deterministic rubric-based technical answer review
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: mcp==2.2.0
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# Technical Answer Validator
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
<!-- mcp-name: io.github.Christofer566/technical-answer-validator -->
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
A tiny, deterministic answer review tool for AI agents, available over **MCP stdio** and as a REST API. Each caller supplies the concepts, accepted synonyms, numeric requirements, and answer text for a single evaluation. It does not include a question bank or answer corpus.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
This is an **assistive practice tool**, not an official certification exam grader. Keyword matching can miss semantically correct paraphrases and can accept misleading surface matches. Users should review the supplied rubric and every result.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## Run locally
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
Python 3.10+; the REST server uses the standard library. The MCP adapter uses the official Python SDK 2.2.0.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
```powershell
|
|
30
|
+
$env:TAV_API_KEY = "replace-with-a-long-random-secret-at-least-24-characters"
|
|
31
|
+
python -m tav_api
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
The service listens on `127.0.0.1:8080` by default. To change it, set `TAV_HOST` and `TAV_PORT`. Local single-key mode refuses to start without a `TAV_API_KEY` of at least 24 characters. For deployment, create a distinct key per caller with `python scripts/create_api_key.py CLIENT_ID` and configure `TAV_API_KEYS` as a JSON object mapping each client ID to the generated SHA-256 digest. Store the one-time raw key with that client; do not store or commit it in this repository. When `TAV_API_KEYS` is set, it takes precedence over `TAV_API_KEY`.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Technical Answer Validator
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
<!-- mcp-name: io.github.Christofer566/technical-answer-validator -->
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
A tiny, deterministic answer review tool for AI agents, available over **MCP stdio** and as a REST API. Each caller supplies the concepts, accepted synonyms, numeric requirements, and answer text for a single evaluation. It does not include a question bank or answer corpus.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
This is an **assistive practice tool**, not an official certification exam grader. Keyword matching can miss semantically correct paraphrases and can accept misleading surface matches. Users should review the supplied rubric and every result.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## Run locally
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
Python 3.10+; the REST server uses the standard library. The MCP adapter uses the official Python SDK 2.2.0.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
```powershell
|
|
20
|
+
$env:TAV_API_KEY = "replace-with-a-long-random-secret-at-least-24-characters"
|
|
21
|
+
python -m tav_api
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
The service listens on `127.0.0.1:8080` by default. To change it, set `TAV_HOST` and `TAV_PORT`. Local single-key mode refuses to start without a `TAV_API_KEY` of at least 24 characters. For deployment, create a distinct key per caller with `python scripts/create_api_key.py CLIENT_ID` and configure `TAV_API_KEYS` as a JSON object mapping each client ID to the generated SHA-256 digest. Store the one-time raw key with that client; do not store or commit it in this repository. When `TAV_API_KEYS` is set, it takes precedence over `TAV_API_KEY`.
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
requires = ["hatchling>=1.27,<2"]
|
|
3
3
|
build-backend = "hatchling.build"
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
[project]
|
|
6
7
|
name = "technical-answer-validator"
|
|
7
|
-
version = "0.1.
|
|
8
|
+
version = "0.1.1"
|
|
8
9
|
description = "MCP and REST tools for deterministic rubric-based technical answer review"
|
|
9
10
|
readme = "README.md"
|
|
10
11
|
requires-python = ">=3.10"
|
|
@@ -12,18 +13,22 @@ license = "MIT"
|
|
|
12
13
|
license-files = ["LICENSE"]
|
|
13
14
|
dependencies = ["mcp==2.2.0"]
|
|
14
15
|
|
|
16
|
+
|
|
15
17
|
[project.scripts]
|
|
16
18
|
tav-mcp = "mcp_server:main"
|
|
17
19
|
tav-api = "tav_api:main"
|
|
18
20
|
|
|
21
|
+
|
|
19
22
|
[tool.hatch.build.targets.wheel]
|
|
20
23
|
only-include = ["mcp_server.py", "tav_core.py", "tav_api.py"]
|
|
21
24
|
|
|
25
|
+
|
|
22
26
|
[tool.hatch.build.targets.wheel.force-include]
|
|
23
27
|
"mcp_server.py" = "mcp_server.py"
|
|
24
28
|
"tav_core.py" = "tav_core.py"
|
|
25
29
|
"tav_api.py" = "tav_api.py"
|
|
26
30
|
|
|
31
|
+
|
|
27
32
|
[tool.hatch.build.targets.sdist]
|
|
28
33
|
only-include = [
|
|
29
34
|
".dockerignore", ".env.example", ".gitignore", "Dockerfile", "NOTICE.md",
|
|
@@ -33,5 +38,5 @@ only-include = [
|
|
|
33
38
|
"tav_api.py", "tav_core.py", "uv.lock", ".github", "scripts", "tests"
|
|
34
39
|
]
|
|
35
40
|
|
|
41
|
+
|
|
36
42
|
[tool.pytest.ini_options]
|
|
37
|
-
testpaths = ["tests"]
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
-
"name": "io.github.
|
|
3
|
+
"name": "io.github.Christofer566/technical-answer-validator",
|
|
4
4
|
"title": "Technical Answer Validator",
|
|
5
|
-
"description": "
|
|
6
|
-
"version": "0.1.
|
|
5
|
+
"description": "Rubric-based technical answer feedback for AI agents. Human review required; not an official grade.",
|
|
6
|
+
"version": "0.1.1",
|
|
7
7
|
"repository": {
|
|
8
8
|
"url": "https://github.com/Christofer566/technical-answer-validator",
|
|
9
9
|
"source": "github"
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
"registryType": "pypi",
|
|
14
14
|
"registryBaseUrl": "https://pypi.org",
|
|
15
15
|
"identifier": "technical-answer-validator",
|
|
16
|
-
"version": "0.1.
|
|
16
|
+
"version": "0.1.1",
|
|
17
17
|
"transport": { "type": "stdio" }
|
|
18
18
|
}
|
|
19
19
|
]
|
|
20
20
|
}
|
|
21
|
+
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.5
|
|
2
|
-
Name: technical-answer-validator
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: MCP and REST tools for deterministic rubric-based technical answer review
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
License-File: LICENSE
|
|
7
|
-
Requires-Python: >=3.10
|
|
8
|
-
Requires-Dist: mcp==2.2.0
|
|
9
|
-
Description-Content-Type: text/markdown
|
|
10
|
-
|
|
11
|
-
# Technical Answer Validator
|
|
12
|
-
|
|
13
|
-
<!-- mcp-name: io.github.christofer566/technical-answer-validator -->
|
|
14
|
-
|
|
15
|
-
A tiny, deterministic answer review tool for AI agents, available over **MCP stdio** and as a REST API. Each caller supplies the concepts, accepted synonyms, numeric requirements, and answer text for a single evaluation. It does not include a question bank or answer corpus.
|
|
16
|
-
|
|
17
|
-
This is an **assistive practice tool**, not an official certification exam grader. Keyword matching can miss semantically correct paraphrases and can accept misleading surface matches. Users should review the supplied rubric and every result.
|
|
18
|
-
|
|
19
|
-
## Run locally
|
|
20
|
-
|
|
21
|
-
Python 3.10+; the REST server uses the standard library. The MCP adapter uses the official Python SDK 2.2.0.
|
|
22
|
-
|
|
23
|
-
```powershell
|
|
24
|
-
$env:TAV_API_KEY = "replace-with-a-long-random-secret-at-least-24-characters"
|
|
25
|
-
python -m tav_api
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
The service listens on `127.0.0.1:8080` by default. To change it, set `TAV_HOST` and `TAV_PORT`. Local single-key mode refuses to start without a `TAV_API_KEY` of at least 24 characters. For deployment, create a distinct key per caller with `python scripts/create_api_key.py CLIENT_ID` and configure `TAV_API_KEYS` as a JSON object mapping each client ID to the generated SHA-256 digest. Store the one-time raw key with that client; do not store or commit it in this repository. When `TAV_API_KEYS` is set, it takes precedence over `TAV_API_KEY`.
|
|
29
|
-
|
|
30
|
-
## MCP for AI agents
|
|
31
|
-
|
|
32
|
-
Install the pinned MCP SDK 2.2.0 in a virtual environment from the committed lockfile:
|
|
33
|
-
|
|
34
|
-
```powershell
|
|
35
|
-
uv sync --locked
|
|
36
|
-
.\.venv\Scripts\Activate.ps1
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
The stdio MCP server exposes one tool: `evaluate_answer(rubric, answer)`. Configure an MCP host with the absolute path to the environment's Python and `mcp_server.py`. Example Claude Desktop configuration (replace paths):
|
|
40
|
-
|
|
41
|
-
```json
|
|
42
|
-
{
|
|
43
|
-
"mcpServers": {
|
|
44
|
-
"technical-answer-validator": {
|
|
45
|
-
"command": "C:\\path\\to\\technical-answer-validator\\.venv\\Scripts\\python.exe",
|
|
46
|
-
"args": ["C:\\path\\to\\technical-answer-validator\\mcp_server.py"]
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
After publishing to PyPI, run with `uvx --from technical-answer-validator tav-mcp`. For local development use the `.venv` Python plus `mcp_server.py`. For Codex CLI or another MCP host, use its stdio server configuration with that command and script path. Restart the host, then ask it to list tools and call `evaluate_answer`. The stdio transport is local to the user's agent host and needs no internet endpoint or API key.
|
|
53
|
-
|
|
54
|
-
The Codex TOML template is `codex-mcp-config.example.toml`; the Claude Desktop JSON template is `claude-mcp-config.example.json`. Replace both placeholder paths with absolute paths. Merge the block into the host configuration; do not overwrite other MCP servers or global settings.
|
|
55
|
-
|
|
56
|
-
## Request
|
|
57
|
-
|
|
58
|
-
`POST /v1/evaluate`
|
|
59
|
-
|
|
60
|
-
```json
|
|
61
|
-
{
|
|
62
|
-
"rubric": {
|
|
63
|
-
"required_concepts": ["isolation", "lockout tag"],
|
|
64
|
-
"accepted_synonyms": {"isolation": ["energy isolation"]},
|
|
65
|
-
"numeric_requirements": [],
|
|
66
|
-
"required_count": 2
|
|
67
|
-
},
|
|
68
|
-
"answer": "Apply energy isolation and attach a lockout tag."
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
`accepted_synonyms` keys must exactly match a concept. `numeric_requirements` is an optional array such as `[{"value":"10","unit":"kN","tolerance":"0"}]`. Numbers in an answer are only checked when explicit requirements are provided. Concept score is matched concepts / required_count (defaults to the number of concepts), capped at 1.0; numeric failures apply a 50% score penalty. The verdict thresholds are `correct >= 0.8`, `partial >= 0.4`, otherwise `wrong`.
|
|
73
|
-
|
|
74
|
-
## Response and errors
|
|
75
|
-
|
|
76
|
-
Successful requests return `api_version`, `status`, `score`, `verdict`, matched/missing concepts, numeric check details, and `review_required: true`.
|
|
77
|
-
|
|
78
|
-
Errors use JSON `{ "error": { "code": "...", "message": "..." } }`. Statuses include 400 (invalid request), 401 (missing/invalid key), 404, 405, 413 (body over 64 KiB), and 429 (over 60 requests/minute per client ID). The rate limit is 60 requests/minute per authenticated client ID, in memory, and resets when the process restarts. Daily request/success/client-error/rate-limited counters are persisted in SQLite without answer text and expire after 90 days. `GET /v1/usage` returns only the caller's current UTC-day counts. Retain and back up the usage volume as desired; it contains client IDs and aggregates only.
|
|
79
|
-
|
|
80
|
-
## Privacy and deployment limits
|
|
81
|
-
|
|
82
|
-
The server does not log request bodies or answers. It stores daily counts keyed by client ID and request timestamps in process memory for REST rate limiting. The **stdio MCP option runs locally inside the agent host** and sends no requests to this HTTP server. The REST API is containerized and keeps usage counters in a persistent volume. Before public service, terminate TLS at a reverse proxy, set proxy-level rate/concurrency limits, deploy from a secret manager, monitor the host, and publish a data-retention/contact policy. The app-level per-client rate limit resets on restart and is not a substitute for edge controls.
|
|
83
|
-
|
|
84
|
-
## Verify
|
|
85
|
-
|
|
86
|
-
```powershell
|
|
87
|
-
python -m unittest discover -s tests -v
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
The OpenAPI contract is in `openapi.yaml`; the draft official MCP Registry descriptor is `server.json`, with publication steps in `PUBLISHING.md`. Run locally with Docker Compose after copying `.env.example` to `.env` and adding a private key; Compose publishes the service only on loopback, so configure an HTTPS reverse proxy separately. `compose.yaml` persists aggregate usage in a named volume and applies a read-only root filesystem, dropped Linux capabilities, and resource limits.
|
|
91
|
-
|
|
92
|
-
These tests check API and grading behavior; they do not establish professional exam accuracy.
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# Technical Answer Validator
|
|
2
|
-
|
|
3
|
-
<!-- mcp-name: io.github.christofer566/technical-answer-validator -->
|
|
4
|
-
|
|
5
|
-
A tiny, deterministic answer review tool for AI agents, available over **MCP stdio** and as a REST API. Each caller supplies the concepts, accepted synonyms, numeric requirements, and answer text for a single evaluation. It does not include a question bank or answer corpus.
|
|
6
|
-
|
|
7
|
-
This is an **assistive practice tool**, not an official certification exam grader. Keyword matching can miss semantically correct paraphrases and can accept misleading surface matches. Users should review the supplied rubric and every result.
|
|
8
|
-
|
|
9
|
-
## Run locally
|
|
10
|
-
|
|
11
|
-
Python 3.10+; the REST server uses the standard library. The MCP adapter uses the official Python SDK 2.2.0.
|
|
12
|
-
|
|
13
|
-
```powershell
|
|
14
|
-
$env:TAV_API_KEY = "replace-with-a-long-random-secret-at-least-24-characters"
|
|
15
|
-
python -m tav_api
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
The service listens on `127.0.0.1:8080` by default. To change it, set `TAV_HOST` and `TAV_PORT`. Local single-key mode refuses to start without a `TAV_API_KEY` of at least 24 characters. For deployment, create a distinct key per caller with `python scripts/create_api_key.py CLIENT_ID` and configure `TAV_API_KEYS` as a JSON object mapping each client ID to the generated SHA-256 digest. Store the one-time raw key with that client; do not store or commit it in this repository. When `TAV_API_KEYS` is set, it takes precedence over `TAV_API_KEY`.
|
|
19
|
-
|
|
20
|
-
## MCP for AI agents
|
|
21
|
-
|
|
22
|
-
Install the pinned MCP SDK 2.2.0 in a virtual environment from the committed lockfile:
|
|
23
|
-
|
|
24
|
-
```powershell
|
|
25
|
-
uv sync --locked
|
|
26
|
-
.\.venv\Scripts\Activate.ps1
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
The stdio MCP server exposes one tool: `evaluate_answer(rubric, answer)`. Configure an MCP host with the absolute path to the environment's Python and `mcp_server.py`. Example Claude Desktop configuration (replace paths):
|
|
30
|
-
|
|
31
|
-
```json
|
|
32
|
-
{
|
|
33
|
-
"mcpServers": {
|
|
34
|
-
"technical-answer-validator": {
|
|
35
|
-
"command": "C:\\path\\to\\technical-answer-validator\\.venv\\Scripts\\python.exe",
|
|
36
|
-
"args": ["C:\\path\\to\\technical-answer-validator\\mcp_server.py"]
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
After publishing to PyPI, run with `uvx --from technical-answer-validator tav-mcp`. For local development use the `.venv` Python plus `mcp_server.py`. For Codex CLI or another MCP host, use its stdio server configuration with that command and script path. Restart the host, then ask it to list tools and call `evaluate_answer`. The stdio transport is local to the user's agent host and needs no internet endpoint or API key.
|
|
43
|
-
|
|
44
|
-
The Codex TOML template is `codex-mcp-config.example.toml`; the Claude Desktop JSON template is `claude-mcp-config.example.json`. Replace both placeholder paths with absolute paths. Merge the block into the host configuration; do not overwrite other MCP servers or global settings.
|
|
45
|
-
|
|
46
|
-
## Request
|
|
47
|
-
|
|
48
|
-
`POST /v1/evaluate`
|
|
49
|
-
|
|
50
|
-
```json
|
|
51
|
-
{
|
|
52
|
-
"rubric": {
|
|
53
|
-
"required_concepts": ["isolation", "lockout tag"],
|
|
54
|
-
"accepted_synonyms": {"isolation": ["energy isolation"]},
|
|
55
|
-
"numeric_requirements": [],
|
|
56
|
-
"required_count": 2
|
|
57
|
-
},
|
|
58
|
-
"answer": "Apply energy isolation and attach a lockout tag."
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
`accepted_synonyms` keys must exactly match a concept. `numeric_requirements` is an optional array such as `[{"value":"10","unit":"kN","tolerance":"0"}]`. Numbers in an answer are only checked when explicit requirements are provided. Concept score is matched concepts / required_count (defaults to the number of concepts), capped at 1.0; numeric failures apply a 50% score penalty. The verdict thresholds are `correct >= 0.8`, `partial >= 0.4`, otherwise `wrong`.
|
|
63
|
-
|
|
64
|
-
## Response and errors
|
|
65
|
-
|
|
66
|
-
Successful requests return `api_version`, `status`, `score`, `verdict`, matched/missing concepts, numeric check details, and `review_required: true`.
|
|
67
|
-
|
|
68
|
-
Errors use JSON `{ "error": { "code": "...", "message": "..." } }`. Statuses include 400 (invalid request), 401 (missing/invalid key), 404, 405, 413 (body over 64 KiB), and 429 (over 60 requests/minute per client ID). The rate limit is 60 requests/minute per authenticated client ID, in memory, and resets when the process restarts. Daily request/success/client-error/rate-limited counters are persisted in SQLite without answer text and expire after 90 days. `GET /v1/usage` returns only the caller's current UTC-day counts. Retain and back up the usage volume as desired; it contains client IDs and aggregates only.
|
|
69
|
-
|
|
70
|
-
## Privacy and deployment limits
|
|
71
|
-
|
|
72
|
-
The server does not log request bodies or answers. It stores daily counts keyed by client ID and request timestamps in process memory for REST rate limiting. The **stdio MCP option runs locally inside the agent host** and sends no requests to this HTTP server. The REST API is containerized and keeps usage counters in a persistent volume. Before public service, terminate TLS at a reverse proxy, set proxy-level rate/concurrency limits, deploy from a secret manager, monitor the host, and publish a data-retention/contact policy. The app-level per-client rate limit resets on restart and is not a substitute for edge controls.
|
|
73
|
-
|
|
74
|
-
## Verify
|
|
75
|
-
|
|
76
|
-
```powershell
|
|
77
|
-
python -m unittest discover -s tests -v
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
The OpenAPI contract is in `openapi.yaml`; the draft official MCP Registry descriptor is `server.json`, with publication steps in `PUBLISHING.md`. Run locally with Docker Compose after copying `.env.example` to `.env` and adding a private key; Compose publishes the service only on loopback, so configure an HTTPS reverse proxy separately. `compose.yaml` persists aggregate usage in a named volume and applies a read-only root filesystem, dropped Linux capabilities, and resource limits.
|
|
81
|
-
|
|
82
|
-
These tests check API and grading behavior; they do not establish professional exam accuracy.
|
|
File without changes
|
|
File without changes
|
{technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/.github/workflows/ci.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/claude-mcp-config.example.json
RENAMED
|
File without changes
|
{technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/codex-mcp-config.example.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/scripts/create_api_key.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{technical_answer_validator-0.1.0 → technical_answer_validator-0.1.1}/tests/test_mcp_server.py
RENAMED
|
File without changes
|
|
File without changes
|