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
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ärtyp: "verifiable-mcp+jws". structuredContentär byte-identisk medwrapper.payload— inget injiceras. De deprecerade v0.1-fältenprovenanceochsignatureligger som syskonfält påresult, aldrig inutistructuredContent.- 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].textrespektivecontents[0].text) serveras med och jämför motcontent_digesti wrappern. - Signerade fel: wrapperns payload är
{ id: <request id>, error: { code, message, data? } }. Felwrappern bäriat,payload,payload_digestochprovenance— ingetcontent_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_updatedoch exakt ett rättighetsfältrights: "per author; not Creative Commons". Ingetcontent_hash. - Sökvägen
/.well-known/mcp.jsonfö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
signatureochprovenancedubbelsä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.