Generic SPARQL 1.1 MCP server — connect any AI agent to any triplestore
Strong foundation with 12 well-defined tools covering SPARQL query forms, updates, graph store operations, and SHACL validation. All tools have descriptions (avg 180 chars, within 10-1024 baseline). Input schemas present with type definitions for all parameters. Key strengths: clear verb-noun naming (sparql_select, graph_put, validate_shacl), comprehensive parameter descriptions with examples and constraints, documented output schemas with pagination support. Gaps: no tool annotations (readOnlyHint/destructiveHint/idempotentHint) despite clear risk levels; error handling descriptions lack recovery guidance; some parameter descriptions could be more concise (sparql_select description is 380 chars, approaching verbosity threshold).
Check connectivity to the configured SPARQL endpoint. No parameters — pings the pre-configured query endpoint with a minimal ASK {} query and reports reachability, response time, and the three configured URLs (query, update, graph store). Use this tool first when debugging connectivity issues or verifying setup. Returns {success, reachable, http_status, response_ms, query_url, update_url, graph_store_url} on success, {success, reachable, error, response_ms, ...urls} if unreachable.
Permanently delete a named graph. This operation is irreversible — the graph and all its triples are removed. Use sparql_update with CLEAR GRAPH if you want to keep the empty graph. graph_uri: URI of the named graph to delete. Example: "http://example.org/graph/companies" Returns {success, http_status} on success, {success, error} on failure.
Fetch triples from a named graph as Turtle, with pagination support. For graphs larger than `limit` triples call this tool repeatedly, incrementing offset by limit each time, until has_more is false in the response. Blank node identifiers are not guaranteed to be stable across pages. graph_uri: URI of the named graph to read. Example: "http://example.org/graph/companies" limit: Maximum triples per call (default 1000). Reduce if the agent context window is too small to hold the response. offset: Triples to skip (default 0). Increment by limit each page. output_file: When set, Turtle is appended to this local file path and the response omits content. Use for large graph exports that would overflow the agent context. Returns {success, content|file_path, triple_count, has_more, limit, offset} on success, {success, error} on failure.
Missing tool annotations (readOnlyHint, destructiveHint, idempotentHint). Tools are marked with Risk levels in metadata but MCP spec requires formal annotations in tool definitions for agent safety.
Error handling lacks recovery guidance. Descriptions state 'Returns {success, error} on failure' but do not explain what the LLM should do next (retry, ask user, check configuration). Per pattern:recovery-guide, errors must guide the agent's next action.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 68 | <=2025-11-25 | v2 |
List all named graphs in the SPARQL dataset with their triple counts. No parameters — the endpoint is pre-configured in the server environment. Executes a SPARQL SELECT with COUNT(*) grouped by graph URI. Use this tool to discover what graphs exist before querying or writing to them. Returns {success, graphs: [{uri, triple_count}], count} on success, {success, error} on failure.
Append RDF triples to a named graph without removing existing triples. Use graph_post to add data to a graph. Use graph_put to replace it entirely. For large content without a URL, split into valid self-contained Turtle chunks and call graph_post once per chunk — each call appends to the same graph. Provide exactly one of content or source_url: - content: RDF string to append directly. - source_url: HTTP(S) URL fetched directly by the endpoint via LOAD. graph_uri: URI of the named graph to append to. Example: "http://example.org/graph/companies" content: RDF string to append. source_url: Publicly accessible URL of the RDF file to load. rdf_format: Serialisation of content — "turtle" (default), "json-ld", "n-triples". Ignored when source_url is used. Returns {success, http_status, triples_added?} on success, {success, error} on failure.
Replace a named graph entirely — all existing triples are removed first. Use graph_put when you want to overwrite the graph contents. Use graph_post to append without removing existing triples. Provide exactly one of content or source_url: - content: RDF string sent through this server. Suitable for small graphs. - source_url: HTTP(S) URL of an RDF file. The SPARQL endpoint fetches it directly via LOAD — no file bytes flow through this server. Use for large files or remote datasets. graph_uri: URI of the named graph to replace. Example: "http://example.org/graph/companies" content: RDF string (serialisation set by rdf_format). source_url: Publicly accessible URL of the RDF file to load. Example: "https://example.org/datasets/companies.ttl" rdf_format: Serialisation of content — "turtle" (default), "json-ld", "n-triples". Ignored when source_url is used. Returns {success, http_status, triple_count?} on success. triple_count is omitted when source_url is used (count is unknown locally). Returns {success, error} on failure.
Execute a SPARQL ASK query and return a boolean answer. Use this tool for existence checks and boolean conditions: - "Does this URI already exist in the graph?" - "Are there any triples matching this pattern?" Do NOT use ASK to retrieve data — use sparql_select or sparql_construct for that. query: A complete SPARQL 1.1 ASK query string. Example (duplicate check): ASK { GRAPH <http://example.org/companies> { <http://example.org/entity/vectara> ?p ?o } } Returns {success, result: bool} on success, {success, error} on failure.
Execute a SPARQL CONSTRUCT query and return the result as an RDF graph string. Use this tool to extract or reshape a subgraph — materialise inferences, convert data into a target shape, or copy a subset of triples. For tabular bindings use sparql_select. For a full named graph use graph_get. query: A complete SPARQL 1.1 CONSTRUCT query string. Example (extract a subgraph): CONSTRUCT { ?s ?p ?o } WHERE { GRAPH <http://example.org/companies> { ?s ?p ?o } FILTER(?s = <http://example.org/entity/vectara>) } rdf_format: Serialisation for the returned graph string. One of "turtle" (default), "json-ld", "n-triples". Returns {success, graph, rdf_format, triple_count} on success, {success, error} on failure.
Fetch a concise bounded description of a resource. Returns all triples where the URI appears as subject or object, using the endpoint's own DESCRIBE semantics (typically Concise Bounded Description). Use for quick "tell me everything about X" lookups when you have a URI. For targeted graph patterns use sparql_construct instead. resource_uri: Full URI of the resource to describe, without angle brackets. Example: "http://example.org/entity/company/vectara" rdf_format: Serialisation for the returned description string. One of "turtle" (default), "json-ld", "n-triples". Returns {success, description, rdf_format, resource_uri} on success, {success, error} on failure.
Execute a SPARQL SELECT query and return tabular results. Use this tool when you need structured rows of data — variable bindings from the graph. For retrieving an RDF subgraph use sparql_construct. For a yes/no existence check use sparql_ask. Paginate large result sets with limit + offset: call repeatedly, incrementing offset by limit each time, until has_more is false. query: A complete SPARQL 1.1 SELECT query string including PREFIX declarations. Example: PREFIX schema: <https://schema.org/> SELECT ?name ?url WHERE { GRAPH <http://example.org/companies> { ?org a schema:Organization ; schema:name ?name . OPTIONAL { ?org schema:url ?url } } } limit: Maximum rows to return. Appended as LIMIT if the query has none. offset: Rows to skip. Appended as OFFSET. Use with limit for pagination. Returns {success, columns, rows, count, has_more} on success. All row values are strings — SPARQL binding values are not type-cast. Returns {success, error} on failure.
Execute any SPARQL 1.1 Update operation against the configured endpoint. Covers all update forms defined in the SPARQL 1.1 Update specification: INSERT DATA { ... } — add explicit triples (no variables) DELETE DATA { ... } — remove explicit triples (no variables) INSERT { ... } WHERE { ... } — pattern-matched insert DELETE { ... } WHERE { ... } — pattern-matched delete DELETE { ... } INSERT { ... } WHERE { ... } — atomic replace (delete + insert in one) CLEAR [SILENT] GRAPH <g> — remove all triples; graph still exists DROP [SILENT] GRAPH <g> — delete the named graph entirely CREATE [SILENT] GRAPH <g> — create an empty named graph COPY <src> TO <dst> — copy all triples from one graph to another MOVE <src> TO <dst> — move (copy + drop source) ADD <src> TO <dst> — merge source into destination LOAD <url> INTO GRAPH <g> — server-side HTTP fetch of a remote RDF file; no bytes flow through this server Multiple operations may be chained with semicolons in a single call. Include PREFIX declarations at the top when using abbreviated URIs. Auth credentials are taken from the server's environment configuration. For LOAD operations the timeout is automatically extended to 300 s. update: A complete SPARQL 1.1 Update string. Example — add triples to a named graph: PREFIX schema: <https://schema.org/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> INSERT DATA { GRAPH <http://example.org/companies> { <http://example.org/entity/vectara> a schema:Organization ; schema:name "Vectara" ; schema:foundingDate "2020"^^xsd:gYear . } } Example — load a remote dataset: LOAD <https://example.org/data/companies.ttl> INTO GRAPH <http://example.org/companies> Returns {success, http_status} on success, {success, http_status, error} on failure.
Validate an RDF document against SHACL shapes. This is a pure function — it needs no SPARQL endpoint. Call it before writing data with sparql_update or graph_put/graph_post to catch constraint violations before they reach the database. data_graph: RDF content to validate, as a string. Example (Turtle): @prefix schema: <https://schema.org/> . <http://example.org/alice> a schema:Person ; schema:name "Alice" . shapes_graph: SHACL shapes definition. Accepts three forms: - A raw Turtle or JSON-LD string containing the shapes. - A local file path to a .ttl shapes file (resolved relative to the server's working directory). Example: "shapes/person.ttl" - An HTTP(S) URL from which shapes are fetched at call time. Example: "https://example.org/shapes/person.ttl" data_format: RDF format of data_graph. One of "turtle" (default), "json-ld", "n-triples". shapes_format: RDF format when shapes_graph is a raw string. One of "turtle" (default), "json-ld". Ignored when shapes_graph is a file path or URL (format is detected automatically). Returns {success, conforms, violations, violation_count} on success. violations is a list of {message, path, focus_node, value} objects. Returns {success, error, conforms: false, violations: []} on parse or fetch failure.
Parameter descriptions for graph_put and graph_post do not clarify mutual exclusivity of 'content' vs 'source_url'. LLMs may pass both, causing ambiguous behavior. Per pattern:constrained-input, dependencies must be explicit.
sparql_update description is verbose (380+ chars) and mixes multiple concerns (INSERT, DELETE, CLEAR, DROP, COPY, MOVE, ADD, LOAD). Consider splitting into separate tools or condensing to 150-200 chars with a link to detailed docs.
validate_shacl accepts shapes_graph as raw string, file path, or URL without clear parameter documentation of which form is expected. LLMs may pass invalid formats. Add enum or explicit format constraint.