|
|
@@ -13,7 +13,15 @@ fi
|
|
|
|
|
|
PORT=8501
|
|
|
BASE_URL="http://127.0.0.1:$PORT"
|
|
|
-TEST_GRAPH="http://world.eu.org/cannabis-breeding#test"
|
|
|
+TEST_GRAPH="${EXAMPLE_GRAPH:-http://example.org/catalog#test}"
|
|
|
+DERIVED_PROPERTY="http://example.org/relations#derivedFrom"
|
|
|
+SOURCE_BATCH_PROPERTY="http://example.org/relations#sourceBatch"
|
|
|
+ORIGIN_BATCH_PROPERTY="http://example.org/relations#originBatch"
|
|
|
+CATEGORY_TYPE="http://example.org/catalog#Category"
|
|
|
+ROOT_ITEM="http://example.org/catalog#Item_Prototype"
|
|
|
+PATH_SUBJECT="http://example.org/catalog#Item_Prime"
|
|
|
+SAMPLE_FIXTURE="catalog_fixture.ttl"
|
|
|
+: "${MCP_ALLOW_EXAMPLE_LOAD:=true}"
|
|
|
|
|
|
if ! command -v jq >/dev/null 2>&1; then
|
|
|
echo "ERROR: jq is required for test output parsing."
|
|
|
@@ -76,6 +84,18 @@ assert_tool_ok() {
|
|
|
return 0
|
|
|
}
|
|
|
|
|
|
+section "Load sample dataset"
|
|
|
+if [[ "${MCP_ALLOW_EXAMPLE_LOAD:-false}" == "true" ]]; then
|
|
|
+ payload=$(jq -n --arg file "$SAMPLE_FIXTURE" --arg graph "$TEST_GRAPH" '{"tool":"load_examples","input":{"files":[$file],"graph":$graph}}')
|
|
|
+ TOOL_LAST_RESPONSE=""
|
|
|
+ if assert_tool_ok "load_examples" "$payload"; then
|
|
|
+ echo "Loaded fixtures:"
|
|
|
+ echo "$TOOL_LAST_RESPONSE" | jq -r '.result.loaded[] | " - " + (.file + " → " + .graph)' || true
|
|
|
+ fi
|
|
|
+else
|
|
|
+ echo "MCP_ALLOW_EXAMPLE_LOAD not true; skipping sample dataset load."
|
|
|
+fi
|
|
|
+
|
|
|
section "Health check"
|
|
|
root_json="$(curl -sS "$BASE_URL/")"
|
|
|
echo "$root_json" | jq '{status, virtuoso, tools, guardrails}'
|
|
|
@@ -94,7 +114,8 @@ fi
|
|
|
|
|
|
section "Update path (fabricated triples)"
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "insert_triple" '{"tool":"insert_triple","input":{"subject":"http://example.org/plain#TestPlant1","predicate":"http://www.w3.org/1999/02/22-rdf-syntax-ns#type","object":"http://example.org/plain#Specimen","object_type":"uri","graph":"http://world.eu.org/cannabis-breeding#test"}}'; then
|
|
|
+payload=$(jq -n --arg subject "http://example.org/plain#TestItem1" --arg predicate "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" --arg object "http://example.org/plain#Specimen" --arg graph "$TEST_GRAPH" '{"tool":"insert_triple","input":{"subject":$subject,"predicate":$predicate,"object":$object,"object_type":"uri","graph":$graph}}')
|
|
|
+if assert_tool_ok "insert_triple" "$payload"; then
|
|
|
echo "Inserted query preview:"
|
|
|
echo "$TOOL_LAST_RESPONSE" | jq -r '.query' | sed 's/^/ /'
|
|
|
fi
|
|
|
@@ -102,8 +123,8 @@ fi
|
|
|
EXAMPLE_TTL=$(cat <<'EOF'
|
|
|
@prefix ex: <http://example.org/plain#> .
|
|
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
|
-ex:PlainPlant a ex:Specimen ;
|
|
|
- rdfs:label "Plain test plant" .
|
|
|
+ex:PlainItem a ex:Specimen ;
|
|
|
+ rdfs:label "Plain test item" .
|
|
|
EOF
|
|
|
)
|
|
|
|
|
|
@@ -116,80 +137,88 @@ fi
|
|
|
|
|
|
section "Helper retrieval checks"
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "get_entities_by_type(Strain)" '{"tool":"get_entities_by_type","input":{"type_uri":"http://world.eu.org/cannabis-breeding#Strain","limit":5}}'; then
|
|
|
+payload=$(jq -n --arg type_uri "$CATEGORY_TYPE" --argjson limit 5 '{"tool":"get_entities_by_type","input":{"type_uri":$type_uri,"limit":$limit}}')
|
|
|
+if assert_tool_ok "get_entities_by_type(Category)" "$payload"; then
|
|
|
echo "Entity IRIs:"
|
|
|
echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[].s.value' | sed 's/^/ - /' || true
|
|
|
fi
|
|
|
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "search_label(term=King)" '{"tool":"search_label","input":{"term":"King","limit":5}}'; then
|
|
|
+payload=$(jq -n --arg term "Variant" --argjson limit 5 '{"tool":"search_label","input":{"term":$term,"limit":$limit}}')
|
|
|
+if assert_tool_ok "search_label(term=Variant)" "$payload"; then
|
|
|
echo "Label hits:"
|
|
|
- echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[] | " - \(.label.value) (\(.s.value))"' || true
|
|
|
+ echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[] | " - " + (.label.value // "<no label>") + " (" + .s.value + ")"' || true
|
|
|
fi
|
|
|
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "get_predicates_for_subject(Strain_king_kong)" '{"tool":"get_predicates_for_subject","input":{"subject_uri":"http://world.eu.org/example1#Strain_king_kong","limit":10}}'; then
|
|
|
+payload=$(jq -n --arg subject_uri "$PATH_SUBJECT" --argjson limit 10 '{"tool":"get_predicates_for_subject","input":{"subject_uri":$subject_uri,"limit":$limit}}')
|
|
|
+if assert_tool_ok "get_predicates_for_subject(Prime Item)" "$payload"; then
|
|
|
echo "Predicates found:"
|
|
|
echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[].p.value' | sed 's/^/ - /' || true
|
|
|
fi
|
|
|
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "get_labels_for_subject(Strain_king_kong)" '{"tool":"get_labels_for_subject","input":{"subject_uri":"http://world.eu.org/example1#Strain_king_kong"}}'; then
|
|
|
+payload=$(jq -n --arg subject_uri "$PATH_SUBJECT" '{"tool":"get_labels_for_subject","input":{"subject_uri":$subject_uri}}')
|
|
|
+if assert_tool_ok "get_labels_for_subject(Prime Item)" "$payload"; then
|
|
|
echo "Subject labels:"
|
|
|
echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[].label.value' | sed 's/^/ - /' || true
|
|
|
fi
|
|
|
|
|
|
-section "Clone inspection"
|
|
|
-KEROSENE_ROOT="http://world.eu.org/example1#Plant_90d53925-bb5"
|
|
|
+section "Relationship inspection"
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "traverse_property(cloneOf incoming)" '{"tool":"traverse_property","input":{"subject_uri":"http://world.eu.org/example1#Plant_90d53925-bb5","property_uri":"http://world.eu.org/cannabis-breeding#cloneOf","direction":"incoming","limit":20}}'; then
|
|
|
- echo "Clones of Kerosene Krash root:"
|
|
|
- echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[] | " - \(.neighbor.value) (label: \(.label.value // "<no label>"))"'
|
|
|
+payload=$(jq -n --arg subject_uri "$ROOT_ITEM" --arg property_uri "$DERIVED_PROPERTY" --arg direction "incoming" --argjson limit 20 '{"tool":"traverse_property","input":{"subject_uri":$subject_uri,"property_uri":$property_uri,"direction":$direction,"limit":$limit}}')
|
|
|
+if assert_tool_ok "traverse_property(derivedFrom incoming)" "$payload"; then
|
|
|
+ echo "Items derived from the prototype:"
|
|
|
+ echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[] | " - " + (.neighbor.value) + " (label: " + (.label.value // "<no label>") + ")"'
|
|
|
fi
|
|
|
|
|
|
section "Ontology discovery"
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
if assert_tool_ok "list_classes(term=cycle)" '{"tool":"list_classes","input":{"term":"cycle","limit":10}}'; then
|
|
|
echo "Class hits:"
|
|
|
- echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[] | " - \(.class.value) (\(.label.value // "<no label>"))"' || true
|
|
|
+ echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[] | " - " + .class.value + " (" + (.label.value // "<no label>") + ")"' || true
|
|
|
fi
|
|
|
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "list_properties(term=clone)" '{"tool":"list_properties","input":{"term":"clone","limit":10}}'; then
|
|
|
+if assert_tool_ok "list_properties(term=derived)" '{"tool":"list_properties","input":{"term":"derived","limit":10}}'; then
|
|
|
echo "Property hits:"
|
|
|
- echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[] | " - \(.property.value) (\(.label.value // "<no label>"))"' || true
|
|
|
+ echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[] | " - " + .property.value + " (" + (.label.value // "<no label>") + ")"' || true
|
|
|
fi
|
|
|
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "describe_property(cb:cloneOf)" '{"tool":"describe_property","input":{"property_uri":"http://world.eu.org/cannabis-breeding#cloneOf","usage_limit":5}}'; then
|
|
|
- echo "cloneOf metadata rows:"
|
|
|
+payload=$(jq -n --arg property_uri "$DERIVED_PROPERTY" --argjson limit 5 '{"tool":"describe_property","input":{"property_uri":$property_uri,"usage_limit":$limit}}')
|
|
|
+if assert_tool_ok "describe_property(derivedFrom)" "$payload"; then
|
|
|
+ echo "derivedFrom metadata rows:"
|
|
|
echo "$TOOL_LAST_RESPONSE" | jq -r '.result.metadata.results.bindings | length | tostring | " - rows: " + .'
|
|
|
fi
|
|
|
|
|
|
section "Subject/path helpers"
|
|
|
-PATH_SUBJECT="http://world.eu.org/example1#Plant_cookie_kerosene_2026_3"
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "describe_subject(cookie path)" "{\"tool\":\"describe_subject\",\"input\":{\"subject_uri\":\"${PATH_SUBJECT}\",\"limit\":10}}"; then
|
|
|
+payload=$(jq -n --arg subject_uri "$PATH_SUBJECT" --argjson limit 10 '{"tool":"describe_subject","input":{"subject_uri":$subject_uri,"limit":$limit}}')
|
|
|
+if assert_tool_ok "describe_subject(Prime Item)" "$payload"; then
|
|
|
echo "Subject triples:"
|
|
|
- echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[] | " - \(.predicate.value) -> \(.objectLabel.value // .object.value)"' || true
|
|
|
+ echo "$TOOL_LAST_RESPONSE" | jq -r '.result.results.bindings[] | " - " + .predicate.value + " -> " + (.objectLabel.value // .object.value)' || true
|
|
|
fi
|
|
|
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "path_traverse(seed lineage)" "{\"tool\":\"path_traverse\",\"input\":{\"subject_uri\":\"${PATH_SUBJECT}\",\"property_path\":[\"http://world.eu.org/cannabis-breeding#grownFromSeedProduct\",\"http://world.eu.org/cannabis-breeding#seedProductFromPollination\"],\"limit\":5}}"; then
|
|
|
+payload=$(jq -n --arg subject_uri "$PATH_SUBJECT" --arg property1 "$SOURCE_BATCH_PROPERTY" --arg property2 "$ORIGIN_BATCH_PROPERTY" --argjson limit 5 '{"tool":"path_traverse","input":{"subject_uri":$subject_uri,"property_path":[$property1,$property2],"limit":$limit}}')
|
|
|
+if assert_tool_ok "path_traverse(batch lineage)" "$payload"; then
|
|
|
echo "Path traverse results:"
|
|
|
echo "$TOOL_LAST_RESPONSE" | jq -r '.result.result.results.bindings[] | " - " + (.n1Label.value // .n1.value) + " -> " + (.n2Label.value // .n2.value)' || true
|
|
|
fi
|
|
|
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "property_usage_statistics" '{"tool":"property_usage_statistics","input":{"property_uri":"http://world.eu.org/cannabis-breeding#cloneOf","examples_limit":3}}'; then
|
|
|
- echo "cloneOf usage count:"
|
|
|
- echo "$TOOL_LAST_RESPONSE" | jq -r '.result.count.results.bindings[0].usageCount.value // "0" | " - " + .' || true
|
|
|
- echo "Sample bindings:"
|
|
|
+payload=$(jq -n --arg property_uri "$DERIVED_PROPERTY" --argjson examples_limit 3 '{"tool":"property_usage_statistics","input":{"property_uri":$property_uri,"examples_limit":$examples_limit}}')
|
|
|
+if assert_tool_ok "property_usage_statistics" "$payload"; then
|
|
|
+ echo "derivedFrom usage count:"
|
|
|
+ echo "$TOOL_LAST_RESPONSE" | jq -r '.result.count.results.bindings[0].usageCount.value // "0" | " - " + .'
|
|
|
+ echo "Sample bindings:"
|
|
|
echo "$TOOL_LAST_RESPONSE" | jq -r '.result.examples.results.bindings[] | " - " + (.subjectLabel.value // .subject.value) + " -> " + (.objectLabel.value // .object.value)' || true
|
|
|
fi
|
|
|
|
|
|
TOOL_LAST_RESPONSE=""
|
|
|
-if assert_tool_ok "batch_insert(test)" '{"tool":"batch_insert","input":{"ttl":"<http://example.org/plain#BatchPlant> <http://www.w3.org/2000/01/rdf-schema#label> \"batch helper\" .","graph":"http://world.eu.org/cannabis-breeding#test"}}'; then
|
|
|
+payload=$(jq -n --arg ttl "<http://example.org/plain#BatchItem> <http://www.w3.org/2000/01/rdf-schema#label> \"batch helper\" ." --arg graph "$TEST_GRAPH" '{"tool":"batch_insert","input":{"ttl":$ttl,"graph":$graph}}')
|
|
|
+if assert_tool_ok "batch_insert(test)" "$payload"; then
|
|
|
echo "Batch insert query:"
|
|
|
echo "$TOOL_LAST_RESPONSE" | jq -r '.result.query' | sed 's/^/ /'
|
|
|
fi
|