@comunica/mcp-sparql-solid 1.0.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/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2026-now Ruben Taelman
4
+ Ghent University – imec, Belgium
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,211 @@
1
+ # Comunica MCP SPARQL Solid
2
+
3
+ [![npm version](https://badge.fury.io/js/%40comunica%2Fmcp-sparql-solid.svg)](https://www.npmjs.com/package/@comunica/mcp-sparql-solid)
4
+
5
+ Comunica MCP SPARQL Solid is an [MCP server](https://modelcontextprotocol.io/) for allowing AI agents to execute SPARQL queries over [Solid](https://solidproject.org/) data pods with authentication support.
6
+
7
+ Solid (Social Linked Data) is a specification for decentralized data storage and personal data management. This MCP server enables authenticated access to private Solid pods.
8
+
9
+ It's main distinguishing features are the following:
10
+
11
+ * Improves the accuracy of your AI agent's answers by leveraging the power of SPARQL and Knowledge Graphs.
12
+ * Execute [SPARQL 1.2](https://www.w3.org/TR/sparql12-query/) queries over Solid data pods.
13
+ * Interactive authentication with Solid identity providers.
14
+ * Access both public and private Solid resources.
15
+ * Query over federated Solid pods with single sign-on.
16
+
17
+ **[Learn more about Comunica on our website](https://comunica.dev/).**
18
+
19
+ _Internally, this is a [Comunica module](https://comunica.dev/) that is configured with modules to execute SPARQL queries over Solid pods through MCP._
20
+
21
+ ## Supported by
22
+
23
+ Comunica is a community-driven project, sustained by the [Comunica Association](https://comunica.dev/association/).
24
+ If you are using Comunica, [becoming a sponsor or member](https://opencollective.com/comunica-association) is a way to make Comunica sustainable in the long-term.
25
+
26
+ Our top sponsors are shown below!
27
+
28
+ <a href="https://opencollective.com/comunica-association/sponsor/0/website" target="_blank"><img src="https://opencollective.com/comunica-association/sponsor/0/avatar.svg"></a>
29
+ <a href="https://opencollective.com/comunica-association/sponsor/1/website" target="_blank"><img src="https://opencollective.com/comunica-association/sponsor/1/avatar.svg"></a>
30
+ <a href="https://opencollective.com/comunica-association/sponsor/2/website" target="_blank"><img src="https://opencollective.com/comunica-association/sponsor/2/avatar.svg"></a>
31
+ <a href="https://opencollective.com/comunica-association/sponsor/3/website" target="_blank"><img src="https://opencollective.com/comunica-association/sponsor/3/avatar.svg"></a>
32
+
33
+ ## Usage examples
34
+
35
+ After connecting this MCP server to your AI agent (see some examples on how to do this below),
36
+ your agent can SPARQL query Solid data pods, including private resources.
37
+
38
+ For example, use it to ask:
39
+
40
+ > Use Comunica SPARQL Solid to query my personal Solid pod and find all my contacts.
41
+
42
+ ### Prompt suggestions
43
+
44
+ If you want your agent to always use SPARQL for higher accuracy in answers, you can tell it the following:
45
+
46
+ > When looking up data from Solid pods, always prefer using SPARQL queries as this is more precise.
47
+ > Solid pods may contain private data that requires authentication, so make sure to use the authenticated query engine.
48
+ > Since SPARQL queries can take a while to execute, start producing an approximate answer yourself and show it to me if the SPARQL query takes more than 1 second, but then make the answer more concrete based on the SPARQL query once it finalized, as it will be more accurate.
49
+
50
+ ## Installation
51
+
52
+ Comunica requires [Node.JS](http://nodejs.org/) 14.0 or higher and is tested on OSX and Linux.
53
+
54
+ The easiest way to install the client is by installing it from NPM as follows:
55
+
56
+ ```bash
57
+ $ [sudo] npm install -g @comunica/mcp-sparql-solid
58
+ ```
59
+
60
+ Alternatively, you can install from the latest GitHub sources.
61
+ For this, please refer to the README of the [Comunica monorepo](https://github.com/comunica/comunica).
62
+ If you do so, the following examples require replacing `comunica-mcp-sparql-solid` with `node engines/mcp-sparql-solid/bin/mcp.js`.
63
+
64
+ ## Important: HTTP Mode Only
65
+
66
+ **Note:** Due to the interactive nature of Solid authentication, this MCP server only supports HTTP mode. Stdio mode is not available as it cannot handle the interactive login flow required for Solid authentication.
67
+
68
+ ## Connect this MCP server to your agent
69
+
70
+ Below, a non-exhaustive list of examples is given to connect this MCP server to your agent.
71
+
72
+ ### Claude Desktop
73
+
74
+ After installing, you need to run the MCP server in HTTP mode:
75
+
76
+ #### HTTP Mode with Authentication
77
+
78
+ First, start the server manually:
79
+
80
+ ```bash
81
+ $ comunica-mcp-sparql-solid --mode http --port 3123
82
+ ```
83
+
84
+ This will prompt you to authenticate with your Solid identity provider. Follow the interactive login instructions in your terminal.
85
+
86
+ Then, add the following entry to your `claude_desktop_config.json`:
87
+
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "comunica-sparql-solid": {
92
+ "command": "npx",
93
+ "args": [
94
+ "-y",
95
+ "mcp-remote",
96
+ "http://localhost:3123/mcp",
97
+ "--allow-http"
98
+ ]
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ Then, you can ask Claude something like the following:
105
+
106
+ > Using Comunica SPARQL Solid, can you show me information about myself based on my profile?
107
+
108
+ #### Custom Identity Provider
109
+
110
+ You can specify a custom Solid identity provider using the `--idp` flag:
111
+
112
+ ```bash
113
+ $ comunica-mcp-sparql-solid --mode http --port 3123 --idp https://login.inrupt.com/
114
+ ```
115
+
116
+ #### Disable Authentication
117
+
118
+ If you only need to query public Solid resources, you can disable authentication:
119
+
120
+ ```bash
121
+ $ comunica-mcp-sparql-solid --mode http --port 3123 --idp void
122
+ ```
123
+
124
+ #### Default Sources
125
+
126
+ You can optionally configure default Solid pod URLs when starting the MCP server:
127
+
128
+ ```bash
129
+ $ comunica-mcp-sparql-solid --mode http --port 3123 https://example.solidcommunity.net/profile/card
130
+ ```
131
+
132
+ ### Claude Code
133
+
134
+ #### HTTP Mode
135
+
136
+ Run the MCP server in HTTP mode, which requires starting the server manually first:
137
+
138
+ ```bash
139
+ $ comunica-mcp-sparql-solid --mode http --port 3123
140
+ ```
141
+
142
+ Then add it to Claude Code:
143
+
144
+ ```bash
145
+ claude mcp add --transport http sparql-solid http://localhost:3123/mcp
146
+ ```
147
+
148
+ Learn more in the [Claude Code MCP docs](https://code.claude.com/docs/en/mcp).
149
+
150
+ ### ChatGPT
151
+
152
+ At the time of writing, ChatGPT only supports HTTP-based MCP servers.
153
+ So you'll need to run this tool under HTTP mode and expose it to the public Web,
154
+ possibly combined with a reverse proxy and/or OAuth layer.
155
+
156
+ ```bash
157
+ $ comunica-mcp-sparql-solid --mode http --port 3123
158
+ ```
159
+
160
+ ## Available Tools
161
+
162
+ This MCP server provides the following tools:
163
+
164
+ ### query_sparql
165
+
166
+ Execute SPARQL queries over one or more Solid pods or SPARQL endpoints, which also includes update queries.
167
+
168
+ **Parameters:**
169
+ - `query` (required): SPARQL query string
170
+ - `sources` (required, unless default sources are configured): List of Solid pod URLs or SPARQL endpoint URLs
171
+ - `queryFormatLanguage` (optional): Query language (e.g., `sparql`, `graphql`). Allows you to specify alternative query languages supported by Comunica
172
+ - `queryFormatVersion` (optional): Query language version (e.g., `1.0`, `1.1`, `1.2`). Specifies the version of the query language to use
173
+ - `baseIRI` (optional): Base IRI for resolving relative IRIs in the query
174
+ - `httpProxy` (optional): HTTP proxy URL (e.g., `http://proxy.example.com:8080`)
175
+ - `httpAuth` (optional): HTTP basic authentication in the format `username:password`
176
+ - `httpTimeout` (optional): HTTP request timeout in milliseconds
177
+ - `httpRetryCount` (optional): Number of HTTP request retries on failure
178
+
179
+ **Note:** When the MCP server is started with default sources, the `sources` parameter is not available, and all queries automatically use the configured default sources.
180
+
181
+ ### query_sparql_rdf
182
+
183
+ Execute SPARQL queries over a serialized RDF dataset provided as a string (useful for querying Turtle, N-Triples, or other RDF formats directly).
184
+
185
+ **Parameters:**
186
+ - `query` (required): SPARQL query string
187
+ - `value` (required): Serialized RDF dataset as a string
188
+ - `mediaType` (required): Media type of the serialized RDF dataset (e.g., `text/turtle`, `application/n-triples`, `application/ld+json`)
189
+ - `fileBaseIRI` (optional): Base IRI for resolving relative IRIs in the RDF dataset
190
+ - `baseIRI` (optional): Base IRI for resolving relative IRIs in the query
191
+ - `queryFormatLanguage` (optional): Query language (e.g., `sparql`, `graphql`). Allows you to specify alternative query languages supported by Comunica
192
+ - `queryFormatVersion` (optional): Query language version (e.g., `1.0`, `1.1`, `1.2`). Specifies the version of the query language to use
193
+
194
+ ## Authentication Flow
195
+
196
+ When you start the MCP server with authentication enabled (default), you will be prompted to:
197
+
198
+ 1. Visit a URL in your web browser
199
+ 2. Log in to your Solid identity provider
200
+ 3. Authorize the application
201
+ 4. The server will automatically receive the authentication token
202
+
203
+ Once authenticated, all queries will be executed with your Solid credentials, allowing access to private resources.
204
+
205
+ ## Learn more
206
+
207
+ This README just shows the tip of the iceberg!
208
+ Learn more about Comunica's functionalities in the following guides:
209
+
210
+ * _[*Full documentation*](https://comunica.dev/docs/)_
211
+ * _[*Solid documentation*](https://solidproject.org/)_
package/bin/mcp.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/bin/mcp.js ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const query_sparql_solid_1 = require("@comunica/query-sparql-solid");
5
+ const BinHelpersSolid_1 = require("../lib/BinHelpersSolid");
6
+ // eslint-disable-next-line ts/no-require-imports,ts/no-var-requires,import/extensions
7
+ (0, BinHelpersSolid_1.runCliSolid)(new query_sparql_solid_1.QueryEngine(), require('../package.json').version);
8
+ //# sourceMappingURL=mcp.js.map
package/bin/mcp.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["mcp.ts"],"names":[],"mappings":";;;AACA,qEAA2D;AAC3D,4DAAqD;AAErD,sFAAsF;AACtF,IAAA,6BAAW,EAAC,IAAI,gCAAW,EAAE,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { QueryEngine } from '@comunica/query-sparql-solid';\nimport { runCliSolid } from '../lib/BinHelpersSolid';\n\n// eslint-disable-next-line ts/no-require-imports,ts/no-var-requires,import/extensions\nrunCliSolid(new QueryEngine(), require('../package.json').version);\n"]}
@@ -0,0 +1,2 @@
1
+ import type { QueryEngineBase } from '@comunica/actor-init-query';
2
+ export declare function runCliSolid(queryEngine: QueryEngineBase, version: string): void;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runCliSolid = runCliSolid;
4
+ const utils_mcp_1 = require("@comunica/utils-mcp");
5
+ const yargs_1 = require("yargs");
6
+ const helpers_1 = require("yargs/helpers");
7
+ // eslint-disable-next-line ts/no-require-imports,ts/no-var-requires
8
+ const { interactiveLogin } = require('solid-node-interactive-auth');
9
+ function runCliSolid(queryEngine, version) {
10
+ (async () => {
11
+ const argv = await (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
12
+ .usage('Usage: $0 [options] [sources...]')
13
+ .option('mode', {
14
+ alias: 'm',
15
+ type: 'string',
16
+ choices: ['http'],
17
+ demandOption: true,
18
+ description: 'Transport mode for the MCP server (only http mode supported for Solid)',
19
+ })
20
+ .option('port', {
21
+ alias: 'p',
22
+ type: 'number',
23
+ default: 3123,
24
+ description: 'Port to run the MCP server on',
25
+ })
26
+ .option('idp', {
27
+ type: 'string',
28
+ description: 'Solid identity provider to authenticate with (set to \'void\' to disable auth)',
29
+ default: 'https://solidcommunity.net/',
30
+ })
31
+ .example([
32
+ ['$0 --mode http --port 3000', 'Start MCP server in HTTP mode on port 3000 with default IDP'],
33
+ ['$0 --mode http --idp https://solidcommunity.net/', 'Start with a specific identity provider'],
34
+ ['$0 --mode http --idp void', 'Start without authentication'],
35
+ ['$0 --mode http https://example.org/data/', 'Start with a default Solid pod URL'],
36
+ ])
37
+ .parse();
38
+ // Extract positional arguments as default sources
39
+ const defaultSources = argv._.length > 0 ? argv._.map(String) : undefined;
40
+ // Handle Solid authentication
41
+ let session;
42
+ if (argv.idp !== 'void') {
43
+ try {
44
+ process.stderr.write(`Authenticating with identity provider: ${argv.idp}\n`);
45
+ session = await interactiveLogin({
46
+ oidcIssuer: argv.idp,
47
+ });
48
+ process.stderr.write('Authentication successful!\n');
49
+ }
50
+ catch (error) {
51
+ process.stderr.write(`Authentication error: ${error.message}\n`);
52
+ if (error.stack) {
53
+ process.stderr.write(`${error.stack}\n`);
54
+ }
55
+ process.exit(1);
56
+ }
57
+ }
58
+ // Prepare custom context with Solid session if authenticated
59
+ const customContext = session ?
60
+ { '@comunica/actor-http-inrupt-solid-client-authn:session': session } :
61
+ undefined;
62
+ const server = new utils_mcp_1.SparqlMcpServer('http', argv.port, queryEngine, version, process.stderr, defaultSources, customContext, ` If you want to query the WebID or pod of the user, you can pass the URL ${session?.info.webId}.`);
63
+ // Handle graceful shutdown
64
+ const cleanup = async () => {
65
+ if (session) {
66
+ try {
67
+ await session.logout();
68
+ process.stderr.write('Logged out from Solid pod\n');
69
+ }
70
+ catch (error) {
71
+ process.stderr.write(`Logout error: ${error.message}\n`);
72
+ }
73
+ }
74
+ };
75
+ process.on('SIGINT', () => {
76
+ cleanup().then(() => process.exit(0)).catch(() => process.exit(1));
77
+ });
78
+ process.on('SIGTERM', () => {
79
+ cleanup().then(() => process.exit(0)).catch(() => process.exit(1));
80
+ });
81
+ await server.start().catch((error) => {
82
+ process.stderr.write(`Server error: ${error.message}\n`);
83
+ if (error.stack) {
84
+ process.stderr.write(`${error.stack}\n`);
85
+ }
86
+ return cleanup().finally(() => process.exit(1));
87
+ });
88
+ })().catch((error) => {
89
+ process.stderr.write(`Initialization error: ${error.message}\n`);
90
+ if (error.stack) {
91
+ process.stderr.write(`${error.stack}\n`);
92
+ }
93
+ process.exit(1);
94
+ });
95
+ }
96
+ //# sourceMappingURL=BinHelpersSolid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BinHelpersSolid.js","sourceRoot":"","sources":["BinHelpersSolid.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable unicorn/no-process-exit */\nimport type { QueryEngineBase } from '@comunica/actor-init-query';\nimport { SparqlMcpServer } from '@comunica/utils-mcp';\nimport type { Session } from '@rubensworks/solid-client-authn-isomorphic';\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\n\n// eslint-disable-next-line ts/no-require-imports,ts/no-var-requires\nconst { interactiveLogin } = require('solid-node-interactive-auth');\n\nexport function runCliSolid(queryEngine: QueryEngineBase, version: string): void {\n (async() => {\n const argv = await yargs(hideBin(process.argv))\n .usage('Usage: $0 [options] [sources...]')\n .option('mode', {\n alias: 'm',\n type: 'string',\n choices: [ 'http' ],\n demandOption: true,\n description: 'Transport mode for the MCP server (only http mode supported for Solid)',\n })\n .option('port', {\n alias: 'p',\n type: 'number',\n default: 3123,\n description: 'Port to run the MCP server on',\n })\n .option('idp', {\n type: 'string',\n description: 'Solid identity provider to authenticate with (set to \\'void\\' to disable auth)',\n default: 'https://solidcommunity.net/',\n })\n .example([\n [ '$0 --mode http --port 3000', 'Start MCP server in HTTP mode on port 3000 with default IDP' ],\n [ '$0 --mode http --idp https://solidcommunity.net/', 'Start with a specific identity provider' ],\n [ '$0 --mode http --idp void', 'Start without authentication' ],\n [ '$0 --mode http https://example.org/data/', 'Start with a default Solid pod URL' ],\n ])\n .parse();\n\n // Extract positional arguments as default sources\n const defaultSources: string[] | undefined = argv._.length > 0 ? argv._.map(String) : undefined;\n\n // Handle Solid authentication\n let session: Session | undefined;\n if (argv.idp !== 'void') {\n try {\n process.stderr.write(`Authenticating with identity provider: ${argv.idp}\\n`);\n session = await interactiveLogin({\n oidcIssuer: argv.idp,\n });\n process.stderr.write('Authentication successful!\\n');\n } catch (error: any) {\n process.stderr.write(`Authentication error: ${error.message}\\n`);\n if (error.stack) {\n process.stderr.write(`${error.stack}\\n`);\n }\n process.exit(1);\n }\n }\n\n // Prepare custom context with Solid session if authenticated\n const customContext = session ?\n { '@comunica/actor-http-inrupt-solid-client-authn:session': session } :\n undefined;\n\n const server = new SparqlMcpServer(\n 'http',\n argv.port,\n queryEngine,\n version,\n process.stderr,\n defaultSources,\n customContext,\n ` If you want to query the WebID or pod of the user, you can pass the URL ${session?.info.webId}.`,\n );\n\n // Handle graceful shutdown\n const cleanup = async(): Promise<void> => {\n if (session) {\n try {\n await session.logout();\n process.stderr.write('Logged out from Solid pod\\n');\n } catch (error: any) {\n process.stderr.write(`Logout error: ${error.message}\\n`);\n }\n }\n };\n\n process.on('SIGINT', () => {\n cleanup().then(() => process.exit(0)).catch(() => process.exit(1));\n });\n\n process.on('SIGTERM', () => {\n cleanup().then(() => process.exit(0)).catch(() => process.exit(1));\n });\n\n await server.start().catch((error) => {\n process.stderr.write(`Server error: ${error.message}\\n`);\n if (error.stack) {\n process.stderr.write(`${error.stack}\\n`);\n }\n return cleanup().finally(() => process.exit(1));\n });\n })().catch((error) => {\n process.stderr.write(`Initialization error: ${error.message}\\n`);\n if (error.stack) {\n process.stderr.write(`${error.stack}\\n`);\n }\n process.exit(1);\n });\n}\n"]}
package/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './BinHelpersSolid';
package/lib/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./BinHelpersSolid"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC","sourcesContent":["export * from './BinHelpersSolid';\n"]}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@comunica/mcp-sparql-solid",
3
+ "version": "1.0.0",
4
+ "description": "An MCP server for executing SPARQL queries over Solid data pods with authentication support",
5
+ "license": "MIT",
6
+ "funding": {
7
+ "type": "opencollective",
8
+ "url": "https://opencollective.com/comunica-association"
9
+ },
10
+ "homepage": "https://comunica.dev/",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/comunica/comunica-feature-mcp.git",
14
+ "directory": "engines/mcp-sparql-solid"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/comunica/comunica-feature-mcp/issues"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "agentic",
22
+ "comunica",
23
+ "sparql",
24
+ "solid",
25
+ "authentication",
26
+ "engine",
27
+ "query",
28
+ "update",
29
+ "sparql engine",
30
+ "sparql query",
31
+ "sparql update",
32
+ "sparql 1.1",
33
+ "sparql 1.2"
34
+ ],
35
+ "sideEffects": false,
36
+ "main": "lib/index.js",
37
+ "typings": "lib/index",
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "bin": {
42
+ "comunica-mcp-sparql-solid": "bin/mcp.js"
43
+ },
44
+ "files": [
45
+ "bin/**/*.d.ts",
46
+ "bin/**/*.js",
47
+ "bin/**/*.js.map",
48
+ "lib/**/*.d.ts",
49
+ "lib/**/*.js",
50
+ "lib/**/*.js.map"
51
+ ],
52
+ "scripts": {
53
+ "build": "yarn run build:ts",
54
+ "build:ts": "node \"../../node_modules/typescript/bin/tsc\""
55
+ },
56
+ "dependencies": {
57
+ "@comunica/query-sparql-solid": "^5.0.1",
58
+ "@comunica/utils-mcp": "^1.0.0",
59
+ "@rubensworks/solid-client-authn-isomorphic": "^2.0.0",
60
+ "@types/yargs": "^17.0.0",
61
+ "solid-node-interactive-auth": "^1.0.2",
62
+ "yargs": "^17.7.2"
63
+ },
64
+ "gitHead": "8a35a73d61cf1066bb1181761884d84d3b932932"
65
+ }