Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Solid

БесплатноНе проверен

MCP server for the Solid protocol enabling AI models to read, write, search, and manage resources in Solid pods.

GitHubEmbed

Описание

MCP server for the Solid protocol enabling AI models to read, write, search, and manage resources in Solid pods.

README

A Model Context Protocol (MCP) server that exposes a Solid pod to MCP clients (Claude Desktop and other MCP hosts) as Resources and Tools.

Pod URLs map 1:1 to MCP resources, and four pod-scope-guarded tools — solid_list, solid_read, solid_search, solid_write — let an agent browse, read, search, and (opt-in) write pod data over an injectable authenticated Solid fetch. The server holds no bespoke crypto: you supply the authenticated (Solid-OIDC / DPoP) fetch, so token handling stays in vetted upstream libraries.

⚠️ Experimental, AI-agent-generated. Part of the @jeswr Solid app suite. Read-only by default; review before granting write access to a real pod.

What you get

  • Resources — every in-pod URL is an MCP resource (the resource uri is the pod url). Containers are returned as a JSON listing, RDF resources as Turtle, and anything else as text or base64 bytes. A list callback browses the pod root.
  • Tools
    Tool Args Semantics
    solid_list { container } List a container's typed children (url, name, isContainer, type, mimeType, size, modified). readOnlyHint.
    solid_read { url } Read a resource — Turtle for RDF, text or base64 otherwise. Fails closed (401/403). readOnlyHint.
    solid_search { query, scope? } Client-side search: best-effort Type-Index discovery + a bounded recursive container scan, matching url/name and RDF literal values. No server FTS. readOnlyHint.
    solid_write { url, content, contentType } PUT a resource. Disabled unless readOnly:false. destructiveHint.

Install

npm install github:jeswr/solid-mcp#main

The package commits a self-contained dist/ (with @jeswr/fetch-rdf inlined via esbuild), so it installs and imports directly from a GitHub branch under ignore-scripts=true with no build step. npm publish is a deferred migration (see Roadmap).

Auth model (the seam)

The server takes an injectable authenticated fetch and a podRoot:

import { createSolidMcpServer } from "@jeswr/solid-mcp";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = createSolidMcpServer({
  fetch: session.fetch, // an authenticated Solid-OIDC / DPoP fetch you provide
  podRoot: "https://alice.pod.example/",
  webId: "https://alice.pod.example/profile/card#me", // optional, enables Type-Index search
  readOnly: true, // DEFAULT — set false to enable solid_write
});

await server.connect(new StdioServerTransport());

SolidMcpConfig:

interface SolidMcpConfig {
  fetch: typeof fetch;   // authenticated Solid fetch (server holds no credentials)
  podRoot: string;       // absolute http(s) container URL ending in "/"
  webId?: string;        // optional, for Type-Index-driven search
  readOnly?: boolean;    // default true (writes disabled)
}

Read-only by default; writes are opt-in

solid_write is disabled unless you create the server with readOnly: false. When read-only, the tool returns an isError result (it never throws out of the handler), so a client gets a clear "write disabled" message rather than a crash.

Pod-scope / SSRF guard

Every Resource read and every Tool call is confined to podRoot. A URL is rejected (with a pod-scope violation error) unless its canonical form is within the pod root — this is the SSRF / capability boundary that stops an agent from using a tool to reach an arbitrary origin or to escape the pod root via .. path traversal. The check itself is @jeswr/guarded-fetch's consolidated pod-scope guard (assertWithinPodScope / createPodScopedFetch): a segment-boundary same-origin path-prefix check on the WHATWG-normalised, canonical URL (so encoded and dot-segment escapes are resolved away first, and every redirect hop is re-checked, not just the initial URL) — wrapped here so its errors keep this package's pod-scope violation: message prefix.

CLI (M1)

The solid-mcp bin reads configuration from the environment and connects over stdio:

Env var Required Notes
SOLID_MCP_POD_ROOT yes absolute http(s) container URL ending in /
SOLID_MCP_WEBID no enables Type-Index search
SOLID_MCP_READONLY no default "true"; set "false" to enable writes
SOLID_MCP_CLIENT_ID / _SECRET / _OIDC_ISSUER / _TOKEN_URL no reserved for M2

M1 auth scope: a bundled headless client-credentials login is not part of M1. If the client-credentials env vars are present, the CLI prints a clear message and falls back to an unauthenticated globalThis.fetch (works for public resources; protected resources fail closed). For an authenticated session today, import createSolidMcpServer programmatically and pass your own authenticated fetch. Bundled headless login is a Roadmap (M2) item.

Claude Desktop config

Add to claude_desktop_config.json (mcpServers):

{
  "mcpServers": {
    "solid": {
      "command": "npx",
      "args": ["solid-mcp"],
      "env": {
        "SOLID_MCP_POD_ROOT": "https://alice.pod.example/",
        "SOLID_MCP_WEBID": "https://alice.pod.example/profile/card#me",
        "SOLID_MCP_READONLY": "true"
      }
    }
  }
}

RDF discipline

The package parses RDF only via @jeswr/fetch-rdf

  • @solid/object (container listings via ContainerDataset), and serialises with n3.Writer. It never hand-builds or hand-parses RDF.

Anti-silo / typed data

Typed pod data is read through the suite's shared RDF shapes (Activity Streams 2.0, schema.org, @jeswr/solid-task-model, …), so an agent reads the same shapes the suite apps write — a task created in solid-issues, a contact in the Pod Manager, a bookmark in a pod-app are all the same graph. This is the integration-targets contract: agent access and app access share one data model rather than per-app silos.

Public API

import {
  createSolidMcpServer,
  type SolidMcpConfig,
  // pod operations (programmatic / testing):
  listContainer, readResource, readRdf, search, writeResource,
  // auth helpers + scope guard:
  normalizePodRoot, requirePodScopedUrl, podScopedUrlOrUndefined, writesEnabled,
  // types:
  type PodChild, type ReadResult, type ReadRdfResult, type SearchMatch, type SearchOptions,
} from "@jeswr/solid-mcp";

The authoritative, diffable snapshot of the whole public surface lives in etc/solid-mcp.api.md (generated by API Extractor). npm run api:check fails on any drift and runs in CI; after an intended API change, regenerate + commit the report with npm run api:report.

Roadmap (M2)

  • Streamable-HTTP transport (in addition to stdio).
  • Per-platform client configs (Cline, Open WebUI, LibreChat MCP server, OpenClaw, …).
  • Bundled headless client-credentials login so the CLI can run authenticated without a programmatic embed.
  • Deeper typed-data tools (task / contact / bookmark / calendar shape-aware read + write) over @jeswr/solid-task-model and the suite shapes.

Development

npm run lint                      # biome + check:lockfile-transport
npm run typecheck                 # tsc --noEmit
npm test                          # vitest
npm run build                     # tsc → dist/
npm run check:dist                # guard the committed dist/ against src/ drift
npm run check:lockfile-transport  # guard package-lock.json against the SSH git transport (#78: npm install rewrites @jeswr github: deps to git+ssh, breaking npm ci)
npm run fix:lockfile-transport    # the FIX half of the #78 guard — normalizes an SSH-rewritten lockfile back to HTTPS; run after any npm install/update, before committing

Any npm install / npm update re-triggers the #78 rewrite (npm recomputes every git-dependency resolved URL as SSH on ANY lockfile regen, even one triggered by an unrelated bump — this is why it recurs on Dependabot PRs here even when the bump is unrelated to @jeswr/fetch-rdf). A repo-local git config insteadOf does not prevent it (it only changes what the git binary does when actually invoked, not what npm writes into the lockfile). npm run fix:lockfile-transport is the durable fix: run it after any install/update, then check:lockfile-transport (or lint) passes and the lockfile stays committable over HTTPS. Dependabot PRs are additionally auto-fixed by .github/workflows/normalize-dependabot-lockfile.yml, which pushes a normalizing commit onto the PR branch if Dependabot's own regenerated lockfile needs it.

License

MIT © Jesse Wright

from github.com/jeswr/solid-mcp

Установка Solid

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/jeswr/solid-mcp

FAQ

Solid MCP бесплатный?

Да, Solid MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Solid?

Нет, Solid работает без API-ключей и переменных окружения.

Solid — hosted или self-hosted?

Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.

Как установить Solid в Claude Desktop, Claude Code или Cursor?

Открой Solid на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Solid with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории ai