SmSn Server - synchrony/smsn GitHub Wiki
SmSn follows a client-server pattern in which there are multiple potential clients, and a single server application called SmSn Server. This page assumes that you have already started SmSn server, and contains details on communicating with it.
SmSn Server runs as a standalone Java application and listens on WebSocket port 8182 by default; connect to ws://localhost:8182/smsn.
The following is a simple program in Python (suitable for a Jupyter Notebook) which you can use to experiment with SmSn's WebSocket communication:
import asyncio
import websockets
import json
def toRequestJson(action_json):
return {
"op":"eval",
"processor":"session",
"args":{
"language":"smsn",
"session":"undefined",
"gremlin":json.dumps(action_json)}}
async def issueSmSnRequest(actionJson, callback):
serverUrl = "ws://localhost:8182/smsn"
try:
async with websockets.connect(serverUrl) as websocket:
jsonString = json.dumps(toRequestJson(actionJson))
# Send the JSON string to the WebSocket server
await websocket.send(jsonString)
# Receive and print the response from the WebSocket server
response = await websocket.recv()
responseJson = json.loads(response)
if responseJson["status"]["code"] == 200:
callback(json.loads(responseJson["result"]["data"][0]))
else:
print("Error status:")
print(responseJson["status"])
callback(response)
except Exception as e:
print(f"An error occurred: {e}")
def printResult(result):
print(f"Result from SmSn server: {result}")
async def smsnSearch(searchTerm, callback=printResult):
actionJson = {
"action":"net.fortytwo.smsn.server.actions.Search",
"filter":{
"minSource":"private",
"defaultSource":"private",
"minWeight":0.0,
"defaultWeight":0.5},
"titleCutoff":100,
"style":"forward",
"queryType":"FullText",
"query":searchTerm,
"height":1}
await issueSmSnRequest(actionJson, lambda r: callback(r["view"]["children"]))
Now apply the above to a search term, e.g.
await smsnSearch("*hello*")
Available Actions
The server supports the following action classes in net.fortytwo.smsn.server.actions:
| Action | Description |
|---|---|
Search |
Full-text search by title |
GetView |
Get a tree view of a note and its children |
UpdateView |
Update notes from a tree view |
SetProperties |
Set properties on a note |
FindRoots |
Find notes with no parents |
FindIsolatedNotes |
Find notes with no parents or children |
RemoveIsolatedNotes |
Delete isolated notes |
FindDuplicates |
Find notes with duplicate titles |
GetHistory |
Get VCS commit history |
Ping |
Health check |
GetConfiguration |
Get server configuration |
See the Installation guide for setup instructions.
Authentication
SmSn Server supports optional authentication to control access to your knowledge base. When enabled, clients must provide a secret token to gain full access; otherwise they are treated as anonymous users with limited permissions.
Configuration
Add an authentication section to your smsn.yaml:
authentication:
enabled: true
token: "your-secret-token-here"
publicSources:
- public
- universal
| Field | Description |
|---|---|
enabled |
Set to true to enable authentication (default: false) |
token |
Secret token that clients must provide for full access |
publicSources |
List of source names that anonymous users can read |
Connecting with Authentication
To authenticate, include the token as a query parameter when connecting:
ws://localhost:8182/smsn?token=your-secret-token-here
Without a valid token (or with authentication.enabled: false), the connection is treated as anonymous.
Permission Model
| Operation | Authenticated | Anonymous |
|---|---|---|
| Read from any source | ✓ | ✗ |
| Read from public sources | ✓ | ✓ |
| Search (all sources) | ✓ | ✗ |
| Search (public sources only) | ✓ | ✓ |
| Write operations (SetProperties, UpdateView, etc.) | ✓ | ✗ |
| Import/Export | ✓ | ✗ |
Security Considerations
- Use TLS in production: The token is sent in the URL query string. Without TLS, it can be intercepted. Use a reverse proxy (nginx, Caddy) to terminate TLS.
- Bind to localhost: If not using a reverse proxy, consider binding the server to
127.0.0.1instead of0.0.0.0to prevent remote access. - Keep tokens secret: Treat the token like a password. Don't commit it to version control.
Example: Reverse Proxy with Caddy
For secure public access, use Caddy as a reverse proxy:
smsn.yourdomain.com {
reverse_proxy /smsn localhost:8182
}
Caddy automatically obtains and renews TLS certificates. Clients connect via:
wss://smsn.yourdomain.com/smsn?token=your-secret-token-here