Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions docs/about.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix dh: <https://w3id.org/atomgraph/linkeddatahub/document-hierarchy#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix schema: <https://schema.org/> .

<> a dh:Item ;
dct:title "About LinkedDataHub" ;
Expand All @@ -11,7 +12,13 @@

<#overview-video> a ldh:Object ;
dct:title "LinkedDataHub 6 overview" ;
rdf:value <https://www.youtube.com/watch?v=g3i-yH95WZA> .
rdf:value <https://www.youtube.com/watch?v=g3i-yH95WZA> ;
ldh:graph <> .

<https://www.youtube.com/watch?v=g3i-yH95WZA> a schema:VideoObject ;
schema:name "LinkedDataHub 6 overview" ;
schema:url <https://www.youtube.com/watch?v=g3i-yH95WZA> ;
schema:thumbnailUrl <https://i.ytimg.com/vi/g3i-yH95WZA/hqdefault.jpg> .

<#content> a ldh:XHTML ;
rdf:value """<div xmlns="http://www.w3.org/1999/xhtml">
Expand All @@ -37,18 +44,14 @@
</div>
<div>
<h2 id="kms">Knowledge management and collaboration</h2>
<div class="screenshot-placeholder">
<span aria-hidden="true" class="msi">play_circle</span>
<p>Screen recording: LinkedDataHub overview</p>
</div>
<p>As an RDF-native CMS, LinkedDataHub provides these end-user features:</p>
<ul>
<li><a href="../user-guide/create-data/create-content/" target="_blank">creating structured content</a> from Linked Data and SPARQL resources</li>
<li><a href="../user-guide/create-data/create-documents/" target="_blank">creating RDF documents (graphs)</a></li>
<li><a href="../user-guide/browse-data/" target="_blank">browsing Linked Data</a></li>
<li><a href="../user-guide/add-data/" target="_blank">copying RDF resources</a> into the local dataspace</li>
<li><a href="../user-guide/browse-data/#text-search" target="_blank">searching</a> and <a href="../user-guide/query-data/" target="_blank">querying</a> SPARQL endpoints</li>
<li><a href="../reference/data-model/resources/#views" target="_blank">creating collections from SPARQL queries</a></li>
<li><a href="../reference/data-model/views/" target="_blank">creating collections from SPARQL queries</a></li>
<li><a href="../user-guide/edit-content/" target="_blank">editing content</a> in place, with RDFa annotations linking text to resources</li>
<li><a href="../user-guide/import-data/import-csv-data/" target="_blank">importing CSV data</a> by mapping it to RDF using SPARQL</li>
<li><a href="../reference/data-model/resources/#charts" target="_blank">visualizing query results as graphs, charts etc.</a></li>
Expand Down
2 changes: 1 addition & 1 deletion docs/extending.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<#content> a ldh:XHTML ;
rdf:value """<div xmlns="http://www.w3.org/1999/xhtml">
<p class="ldh-body-lg">Extending LinkedDataHub with your own code: XSLT stylesheets, Java endpoints, Docker images</p>
<p>Everything in the <a href="../tutorial/">tutorial</a> and the <a href="../user-guide/">user guide</a> happens through the UI, the CLI and RDF files. The pages in this section pick up where low-code ends: they show how to override the rendering with your own <a href="change-layout/">XSLT stylesheet</a> and how to <a href="build-apps/">package an app</a> with custom Java endpoints and a dedicated Docker image.</p>
<p>Everything in the <a href="../tutorial/">tutorial</a> and the <a href="../user-guide/">user guide</a> happens through the UI, the CLI and RDF files. The pages in this section pick up where low-code ends: they show how to override the rendering with your own <a href="change-layout/">XSLT stylesheet</a>, how to <a href="create-packages/">create a package</a> for your own vocabulary, and how to <a href="build-apps/">package an app</a> with custom Java endpoints and a dedicated Docker image.</p>
</div>"""^^rdf:XMLLiteral .

<#select-children> a ldh:Object ;
Expand Down
73 changes: 73 additions & 0 deletions docs/extending/create-packages.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
@prefix ldh: <https://w3id.org/atomgraph/linkeddatahub#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix dh: <https://w3id.org/atomgraph/linkeddatahub/document-hierarchy#> .
@prefix dct: <http://purl.org/dc/terms/> .

<> a dh:Item ;
dct:title "Create packages" ;
dct:description "Bundle the ontology and the stylesheet for your own vocabulary as a reusable package" ;
rdf:_1 <#content> .

<#content> a ldh:XHTML ;
rdf:value """<div xmlns="http://www.w3.org/1999/xhtml">
<p class="ldh-body-lg">Bundle the ontology and the stylesheet for your own vocabulary as a reusable package</p>
<p>A <a href="../../reference/administration/packages/">package</a> is a namespace ontology and an XSLT stylesheet, published as Linked Data behind a package URI.
Developers can create custom packages for their own domain vocabularies. The process has four steps.</p>
<div>
<h2 id="write-ontology">Write package ontology</h2>
<p>Create <samp>ns.ttl</samp> describing both the document the registry serves it as and the ontology inside it, with the vocabulary import and the views:</p>
<pre>&lt;&gt; a dh:Item ;
dct:title "Schema.org ontology" ;
foaf:primaryTopic &lt;#&gt; .

&lt;#&gt; a owl:Ontology ;
owl:imports &lt;https://schema.org/&gt; .

# Attach view to a property
schema:knows ldh:view :PersonKnows .

:PersonKnows a ldh:View ;
dct:title "Knows" ;
spin:query :SelectPersonKnows .

:SelectPersonKnows a sp:Select ;
sp:text \"\"\"
SELECT DISTINCT ?person
WHERE { GRAPH ?graph { $about schema:knows ?person } }
ORDER BY ?person
\"\"\" .</pre>
<div class="ac-alert va-warning" role="status">
<span class="ac-alert-ic"><span aria-hidden="true" class="msi outline">warning</span></span>
<div class="ac-alert-body">
<p class="ac-alert-text">The <code>dct:title</code> on <code>&lt;&gt;</code> is not optional. A write is held to the constraints of the document as it will be written, and a LinkedDataHub document must be titled, so an <samp>ns.ttl</samp> that describes only the ontology is refused <samp>422 Unprocessable Entity</samp> when it is pushed.</p>
</div>
</div>
</div>
<div>
<h2 id="write-stylesheet">Write XSLT stylesheet</h2>
<p>Create the stylesheet — name the file for the vocabulary it covers — with XSLT templates using system modes like <code>ac:*</code>, <code>ldh:*</code> and <code>xhtml:*</code>. See the <a href="../../reference/stylesheets/">Stylesheets reference</a> for template customization patterns.</p>
<pre>&lt;xsl:template match="schema:knows" mode="ac:PropertyEditor"/&gt;</pre>
</div>
<div>
<h2 id="publish-metadata">Publish package metadata</h2>
<p>Publish the descriptor as Linked Data at your package URI, naming the ontology beside it:</p>
<pre>&lt;&gt; a dh:Container ;
dct:title "Schema.org" ;
foaf:primaryTopic &lt;#this&gt; .

&lt;#this&gt; a lds:Package ;
dct:title "Schema.org Package" ;
dct:description "Schema.org vocabulary support" ;
lds:ontology &lt;ns/#&gt; .</pre>
<p>Then upload the stylesheet into the package document and add <code>ac:stylesheet</code> naming that upload, which is where a registry published with <samp>ldh push</samp> gets it:</p>
<pre>package="https://packages.example.com/schema.org/"

upload=$(ldh add file --title schema.xsl --file schema.xsl "$package")
echo "INSERT { &lt;${package}#this&gt; &lt;https://w3id.org/atomgraph/client#stylesheet&gt; &lt;$upload&gt; } WHERE { }" | ldh patch "$package"</pre>
<p>A dataspace importing the package dereferences its descriptor, ontology and stylesheet anonymously, so all three have to be readable without a certificate.</p>
</div>
<div>
<h2 id="test-installation">Test installation</h2>
<p>Declare the <code>ldh:import</code> triple in a test dataspace's <samp>settings</samp> document — see <a href="../../reference/administration/packages/#management">Management</a> for the command.</p>
</div>
</div>"""^^rdf:XMLLiteral .
2 changes: 1 addition & 1 deletion docs/get-started.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</div>
<div>
<h2 id="connect-an-agent">Connect an agent</h2>
<p>AI agents such as Claude Code or Cursor work with LinkedDataHub through the same HTTP API, using Web-Algebra's MCP server. Connected that way, an agent can declare a working application in a dataspace — containers, views and charts — instead of generating code for one.</p>
<p>AI agents such as Claude Code or Cursor work with LinkedDataHub through the same HTTP API, with the <samp>ldh</samp> Claude Code plugin or over Web-Algebra's MCP server. Connected that way, an agent can declare a working application in a dataspace — containers, views and charts — instead of generating code for one.</p>
<p class="ldh-body-lg"><a href="agents/">Read instructions on connecting an agent.</a></p>
</div>
<div>
Expand Down
68 changes: 57 additions & 11 deletions docs/get-started/agents.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,66 @@

<> a dh:Item ;
dct:title "Connect an agent" ;
dct:description "Give an AI agent such as Claude Code or Cursor access to a LinkedDataHub instance over MCP, using Web-Algebra" ;
dct:description "Give an AI agent such as Claude Code or Cursor access to a LinkedDataHub instance, with the ldh Claude Code plugin or over MCP with Web-Algebra" ;
rdf:_1 <#content> .

<#content> a ldh:XHTML ;
rdf:value """<div xmlns="http://www.w3.org/1999/xhtml">
<p class="ldh-body-lg">Give an AI agent such as Claude Code or Cursor access to a LinkedDataHub instance over MCP, using Web-Algebra</p>
<p>Agents use the same HTTP API as the browser and the <a href="../../reference/command-line-interface/">CLI</a>. The bridge is
<a href="https://github.com/AtomGraph/Web-Algebra" target="_blank">Web-Algebra</a>, which exposes LinkedDataHub operations as
<a href="https://modelcontextprotocol.io/" target="_blank">Model Context Protocol</a> (MCP) tools: creating containers and items, adding views,
queries and charts, reading and writing RDF, and running SPARQL. An agent connected this way can build a working application in a dataspace —
<p class="ldh-body-lg">Give an AI agent such as Claude Code or Cursor access to a LinkedDataHub instance, with the ldh Claude Code plugin or over MCP with Web-Algebra</p>
<p>Agents use the same HTTP API as the browser and the <a href="../../reference/command-line-interface/">CLI</a>, and act as a WebID: an agent can read and
write only what its WebID is authorized to. There are two ways to connect one. The <a href="#claude-code-plugin">Claude Code plugin</a> gives Claude Code
skills for building on LinkedDataHub with the <samp>ldh</samp> CLI. <a href="#mcp">Web-Algebra</a> exposes LinkedDataHub operations to any
<a href="https://modelcontextprotocol.io/" target="_blank">Model Context Protocol</a> (MCP) client as tools: creating containers and items, adding views,
queries and charts, reading and writing RDF, and running SPARQL. Either way, an agent can build a working application in a dataspace:
its classes, containers, views and charts are documents like any other.</p>
<p>The conventions agents should follow when writing to LinkedDataHub are in
<a href="https://github.com/AtomGraph/LinkedDataHub/blob/master/AGENTS.md" target="_blank">AGENTS.md</a>.</p>
<a href="https://github.com/AtomGraph/LinkedDataHub/blob/master/AGENTS.md" target="_blank">AGENTS.md</a>. To ask questions about the data in a document
from the browser instead, use the <a href="../../user-guide/use-the-assistant/">assistant</a>.</p>
<div>
<h2 id="prerequisites">Prerequisites</h2>
<h2 id="claude-code-plugin">Claude Code plugin</h2>
<p>The <a href="https://github.com/AtomGraph/LinkedDataHub/tree/master/plugins/ldh" target="_blank"><samp>ldh</samp> plugin</a> ships with LinkedDataHub.
Its marketplace is the LinkedDataHub repository, so Claude Code is told about it once and then installs the plugin from it. In Claude Code:</p>
<pre>/plugin marketplace add AtomGraph/LinkedDataHub
/plugin install ldh@linkeddatahub</pre>
<p>The skills drive the <samp>ldh</samp> CLI, so they need a LinkedDataHub instance, the owner's WebID certificate and the CLI on the <samp>PATH</samp>
(see <a href="../../reference/command-line-interface/#install">installing the CLI</a>). Claude loads a skill by itself when a request matches what it
covers. To call one explicitly, type <samp>/ldh:</samp> followed by its name.</p>
<table>
<caption class="ac-vh">Skills of the ldh plugin</caption>
<thead>
<tr>
<th scope="col">Skill</th>
<th scope="col">Covers</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row"><samp>ldh:dataspace</samp></th>
<td>Provisioning a new dataspace on a self-hosted instance: the configuration files, the restart, and checking that it is up</td>
</tr>
<tr>
<th scope="row"><samp>ldh:dataset</samp></th>
<td>The namespace ontology and its install, CSV and RDF imports, federation with remote SPARQL endpoints, and building a large dataset standalone and bulk-loading it</td>
</tr>
<tr>
<th scope="row"><samp>ldh:app</samp></th>
<td>Documents, blocks, views and charts, and an app kept as a directory and installed with <samp>ldh push</samp></td>
</tr>
<tr>
<th scope="row"><samp>ldh:package</samp></th>
<td>A reusable <a href="../../reference/administration/packages/">package</a>: an ontology and an XSLT stylesheet, published to a registry and imported with <samp>ldh packages add</samp></td>
</tr>
</tbody>
</table>
<p>A request can span several skills, and Claude uses them in turn:</p>
<blockquote><p>Here are products.csv and categories.csv. Model them with schema.org, import them into the inventory dataspace, and make each category's page list its products.</p></blockquote>
</div>
<div>
<h2 id="mcp">Web-Algebra over MCP</h2>
<p><a href="https://github.com/AtomGraph/Web-Algebra" target="_blank">Web-Algebra</a> expresses LinkedDataHub operations, SPARQL queries and Linked Data
reads as plans that run as one unit, and its MCP server offers them as tools. Any MCP client can use it.</p>
<div>
<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li>A running LinkedDataHub instance. The examples below assume the default <a href="../setup/">local setup</a> at <samp>https://localhost:4443/</samp>.</li>
<li>The WebID certificate the agent will act as. For your own instance that is the owner certificate, <samp>ssl/owner/cert.pem</samp>, with the password from
Expand All @@ -28,7 +73,7 @@
</ul>
</div>
<div>
<h2 id="claude-code">Claude Code</h2>
<h3 id="claude-code">Claude Code</h3>
<p>Register Web-Algebra as an MCP server, run from the LinkedDataHub directory:</p>
<pre>claude mcp add web-algebra \\
--env CERT_PEM_PATH="$PWD/ssl/owner/cert.pem" \\
Expand All @@ -37,7 +82,7 @@
<p>Start <samp>claude</samp> and check that <samp>/mcp</samp> lists <samp>web-algebra</samp> as connected.</p>
</div>
<div>
<h2 id="cursor-and-claude-desktop">Cursor and Claude Desktop</h2>
<h3 id="cursor-and-claude-desktop">Cursor and Claude Desktop</h3>
<p>Both read an <samp>mcpServers</samp> entry: <samp>~/.cursor/mcp.json</samp> for Cursor, <samp>claude_desktop_config.json</samp> for Claude Desktop.
Use absolute paths and the literal password, since these files are not run by a shell.</p>
<pre>{
Expand All @@ -55,7 +100,7 @@
<p>If the client cannot find <samp>uv</samp>, replace <samp>"uv"</samp> with its absolute path, as printed by <samp>which uv</samp>.</p>
</div>
<div>
<h2 id="http-transport">Streamable HTTP transport</h2>
<h3 id="http-transport">Streamable HTTP transport</h3>
<p>Clients that connect to an MCP URL instead of launching a process can use Web-Algebra's HTTP server:</p>
<pre>CERT_PEM_PATH="$PWD/ssl/owner/cert.pem" \\
CERT_PASSWORD="$(cat secrets/owner_cert_password.txt)" \\
Expand All @@ -70,6 +115,7 @@ uv run --with web-algebra uvicorn web_algebra.server:app</pre>
</div>
</div>
</div>
</div>
<div>
<h2 id="try-it">Try it</h2>
<p>Ask the agent for something small that it has to declare rather than code. With the <a href="https://github.com/AtomGraph/LinkedDataHub-Apps/tree/master/demo/northwind-traders" target="_blank">Northwind Traders</a> demo installed, for example:</p>
Expand Down
2 changes: 1 addition & 1 deletion docs/reference.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
rdf:value """<div xmlns="http://www.w3.org/1999/xhtml">
<p class="ldh-body-lg">Feature-by-feature reference for the LinkedDataHub platform, its data model, HTTP API and administration</p>
<p>The concept pages describe the <a href="dataspace/">dataspace</a>, its <a href="dataset/">dataset</a> and the <a href="data-model/">data model</a>.
The interface pages cover the <a href="user-interface/">user interface</a>, the <a href="http-api/">HTTP API</a> and the <a href="command-line-interface/">command line interface</a>.
The interface pages cover the <a href="user-interface/">user interface</a>, the <a href="http-api/">HTTP API</a>, the <a href="command-line-interface/">command line interface</a> and the <a href="assistant/">assistant</a>.
Customization is covered by the <a href="stylesheets/">stylesheets</a> and <a href="imports/">imports</a> pages,
and operations by the <a href="configuration/">configuration</a>, <a href="triplestores/">triplestores</a>, <a href="versioning/">versioning</a> and <a href="administration/">administration</a> pages.
Start with the dataspace and data model pages; an application or deployment moving off 5.x starts at
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/administration/acl.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<p>LinkedDataHub access control is based on the W3C <a href="https://www.w3.org/wiki/WebAccessControl" target="_blank">ACL ontology</a>.</p>
<div>
<h2 id="access-modes">Access modes</h2>
<p>There are four access modes (classes of operation) that map to <a href="../../http-api/">HTTP methods</a>:</p>
<p>There are four access modes (classes of operation) that map to <a href="../../http-api/documents/#methods">HTTP methods</a>:</p>
<table>
<caption class="ac-vh">Access modes and the HTTP methods they permit</caption>
<thead>
Expand Down
Loading
Loading