silverbullet.md

  1# SilverBullet MCP Server Instructions
  2
  3You are connected to a SilverBullet instance via its Runtime API. SilverBullet is a creative coding knowledge management tool with an embedded Lua scripting language called Space Lua.
  4
  5## Available Tools
  6
  7- **execute_lua**: Run Space Lua scripts. Use for reading/writing pages, querying data, and all Space Lua operations.
  8- **screenshot**: Capture current viewport as a PNG image.
  9- **console_logs**: Retrieve recent console log entries. Useful for debugging.
 10
 11## Space Lua Essentials
 12
 13Space Lua is a custom Lua implementation embedded in SilverBullet. Key differences from standard Lua:
 14
 15- **camelCase** for all variables and functions (not snake_case)
 16- No coroutines (not supported)
 17- No `_ENV` (planned, not yet available)
 18- `print()` output is swallowed in Runtime API — use `return` to send results back
 19- `query[[...]]` is LIQ (Lua Integrated Query), a SQL/LINQ-inspired query syntax embedded in Lua
 20
 21## Page Operations
 22
 23```lua
 24-- Read a page
 25local content = space.readPage("MyPage")
 26
 27-- Write a page
 28space.writePage("MyPage", "# Hello\n\nContent here")
 29
 30-- Delete a page
 31space.deletePage("MyPage")
 32
 33-- Check if a page exists
 34if space.pageExists("MyPage") then
 35  -- ...
 36end
 37
 38-- List all pages
 39local pages = space.listPages()
 40
 41-- Get page metadata
 42local meta = space.getPageMeta("MyPage")
 43-- meta.name, meta.lastModified
 44```
 45
 46## Querying with LIQ
 47
 48LIQ (`query[[...]]`) is the primary way to search and filter data:
 49
 50```lua
 51-- Find pages tagged #task
 52local tasks = query[[
 53  from p = index.tag "task"
 54  select p.name
 55]]
 56
 57-- Filter by frontmatter
 58local projects = query[[
 59  from p = index.tag "page"
 60  where p.status == "active"
 61  order by p.lastModified desc
 62  select p.name
 63  limit 10
 64]]
 65
 66-- Count items in a group
 67local counts = query[[
 68  from p = index.tag "tag"
 69  group by p.name
 70  select { name = name, count = #group }
 71]]
 72```
 73
 74## File/Document Operations
 75
 76```lua
 77-- List all files
 78local files = space.listFiles()
 79
 80-- Read a file (returns bytes as string)
 81local data = space.readFile("image.png")
 82
 83-- Write a file
 84space.writeFile("data.json", jsonString)
 85
 86-- Read a specific section
 87local section = space.readRef("MyPage#Introduction")
 88```
 89
 90## Common Patterns
 91
 92### Working with Frontmatter
 93
 94SilverBullet pages can have YAML frontmatter. Query against indexed tags and frontmatter fields:
 95
 96```lua
 97local pages = query[[
 98  from p = index.tag "page"
 99  where p.priority == "high"
100  select { name = p.name, priority = p.priority }
101]]
102```
103
104### Working with Tasks
105
106```lua
107local tasks = query[[
108  from t = index.tag "task"
109  where t.state == "todo"
110  order by t.lastModified desc
111  select { name = t.name, page = t.page }
112]]
113```
114
115### Links and References
116
117```lua
118-- Find pages that link to a specific page
119local links = query[[
120  from l = index.tag "link"
121  where l.toPage == "TargetPage"
122  select l.fromPage
123]]
124```
125
126### Combining Lua and LIQ
127
128```lua
129-- Multi-step workflow
130local pages = query[[
131  from p = index.tag "page"
132  where p.name:startsWith("Project/")
133  select p.name
134]]
135
136for _, p in ipairs(pages) do
137  local content = space.readPage(p.name)
138  -- process content
139  space.writePage(p.name, updatedContent)
140end
141
142return pages
143```
144
145## Important Notes
146
147- Always `return` values from lua_script — `print()` output is not captured
148- The `X-Timeout` header controls execution timeout (1-21600 seconds, default 120)
149- Use `space.readRef("Page#Header")` to read specific sections
150- Use explicit variable binding in LIQ: `from p = ...` (not bare `from ...`)
151- Namespace your functions: `myPlugin = myPlugin or {}; function myPlugin.doThing() ... end`
152- Use `-- priority: N` comments to control script load order (higher = earlier)