MCP

Signerat MCP-endpoint för AI-agenter.

Hela SSWC-boken 2010 är tillgänglig som ett MCP-verktygsset. Varje svar på ett tools/call är signerat med Ed25519 så att en agent kan bevisa att texten kommer härifrån och inte har manipulerats.

Endpoint

https://sswcboken.se/api/mcp

Server card (inkl. publik nyckel): /.well-known/mcp.json

Verktyg

server_info
Metadata: dataset, counts, licensposition, signeringsalgoritm.
search_texter
Hybridsökning (semantisk + svensk fulltext) över alla 181 bidrag PLUS författarmatchning (name/handle_2010/now_summary/notes). Svaret har en 'forfattare'-array före textträffarna — så aktuella namn hittas även om bylinen är från 2010.
get_text
En text ordagrant (body verbatim från 2010) via slug eller nr, med figurer, teman, textens drömmar och ev. svar.
list_texter
Paginerad lista över texter.
get_forfattare
Författardossier (då/nu) plus deras texter.
list_forfattare
Paginerad roster över alla författare, sorterad sv-SE. Namn, handle_2010, kind, status_2026, in_memoriam, died_year, text_nrs.
list_drommar
Drömscoreboard: 181 verdicts (slog_in / muterade / dog / oppen).
list_teman
9 tematiska kluster med counts primär/sekundär.
get_tema
Ett tema och alla dess texter (primära först).

Resources: sswc://text/{nr} och sswc://forfattare/{slug} (resources/list + resources/read, signerade som tools/call).

Designval: inget get_drom-verktyg — en dröm hör alltid ihop med sin text och nås via get_text (inkluderar textens drömmar) eller list_drommar.

Exempelanrop

curl -s https://sswcboken.se/api/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'
curl -s https://sswcboken.se/api/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
curl -s https://sswcboken.se/api/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
       "params":{"name":"search_texter","arguments":{"q":"demokrati","limit":5}}}'
curl -s https://sswcboken.se/api/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call",
       "params":{"name":"get_tema","arguments":{"slug":"demokrati-makt"}}}'

Publik nyckel

Ed25519, kid ln2Y6OsJnhuUnXiHeKOiLTCKIlJOpk9PwDA3EVpYZp4 (RFC 7638 JWK-thumbprint; tidigare kortade ln2Y6OsJnhuUnXiH listas kvar under övergången — samma nyckel). Hämtas från /.well-known/sswcboken-mcp-public-key.json eller /.well-known/mcp.json.

{
  "kty": "OKP",
  "crv": "Ed25519",
  "x": "_XTbAAUHZSw9umaO-adqh11fn2hkts8EKOQ9-eFAiyA",
  "kid": "ln2Y6OsJnhuUnXiHeKOiLTCKIlJOpk9PwDA3EVpYZp4",
  "alg": "EdDSA",
  "use": "sig"
}

Tillitslager v0.2.1 — så verifierar du ett svar

Spec: org.jardenberg/verifiable-mcp, spec_version 0.2.1 (kuvertets spec-fält bär versionssträngen "0.2.1"). Varje tools/call och resources/read bär ett kuvert i result._meta["org.jardenberg/verifiable-mcp"] med spec, spec_version, alg, kid, signed: "wrapper" och jws. JSON-RPC-fel bär samma kuvert i error.data["org.jardenberg/verifiable-mcp"].

  • Signaturen täcker en wrapper: { iat, payload, payload_digest, content_digest, provenance }. JWS protected header bär typ: "verifiable-mcp+jws".
  • structuredContent är byte-identisk med wrapper.payload — inget injiceras. De deprecerade v0.1-fälten provenance och signature ligger som syskonfält på result, aldrig inuti structuredContent.
  • Båda digesterna ligger inuti den signerade wrappern. Värden som speglas utanför JWS:en är bekvämlighet — aldrig säkerhetsbärande.
  • Kanonisering: RFC 8785 (JCS) via testat bibliotek — inte prosa om sorterade nycklar.
  • Content binding sker per digest: hasha de exakta bytes textarmen (content[0].text respektive contents[0].text) serveras med och jämför mot content_digest i wrappern.
  • Signerade fel: wrapperns payload är { id: <request id>, error: { code, message, data? } }. Felwrappern bär iat, payload, payload_digest och provenance — inget content_digest, eftersom ingen textarm serveras för fel. Ogiltiga argument ger JSON-RPC-kod -32602.
  • Provenance (spec §5): server_operator, publisher, canonical_origin, canonical_url, dataset_version, last_updated och exakt ett rättighetsfält rights: "per author; not Creative Commons". Inget content_hash.
  • Sökvägen /.well-known/mcp.json följer SEP-2127, som ännu inte är fryst uppströms — sökvägen kan ändras. Både server-kortet och den dedikerade nyckelfilen serveras.
  • Övergång: de gamla v0.1-fälten signature och provenance dubbelsänds och tas bort i v0.3.
# 1. Hämta publik nyckel (JWK, Ed25519)
curl -s https://sswcboken.se/.well-known/sswcboken-mcp-public-key.json | jq .jwks
# 2. Anropa ett verktyg och plocka ut kuvertet
RESP=$(curl -s https://sswcboken.se/api/mcp -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"server_info","arguments":{}}}')
echo "$RESP" | jq -r '.result._meta["org.jardenberg/verifiable-mcp"].jws'
# (fel: kuvertet ligger i .error.data["org.jardenberg/verifiable-mcp"])
# 3. Verifiera JWS:en med nyckeln (protected header typ: "verifiable-mcp+jws").
#    Payloaden är RFC 8785-kanonisk JSON av
#    { iat, payload, payload_digest, content_digest, provenance }.
# 4. Kontrollera digesterna MOT WRAPPERN (inte mot _meta):
#    sha256(canonicalize(wrapper.payload)) == wrapper.payload_digest
#    sha256(<exakta bytes i result.content[0].text>) == wrapper.content_digest
# 5. structuredContent är byte-identisk med wrapper.payload:
#    canonicalize(result.structuredContent) == canonicalize(wrapper.payload)

Rättigheter: Per-författare upphovsrätt 2010. INTE Creative Commons. Återpublicerad i delningens anda. Invändningar tas emot på joakim@jardenberg.com och rättas inom 24 timmar.

Dela vidare

LinkedInBlueskyX