Skip to content

Resource types

A resource is an instance of one of these types. What a type serves decides where xixo uses it; what it accepts, and up to what size, decides whether a file may be placed in it. A type with fields can be attached from the app or declared in config/resources.yml; one without is made by xixo or a sign-in flow.

Generated from the code by ./dev reference. CI fails when this page and the code disagree.

Type Serves Syncs
s3 storage yes
filesystem storage yes
webdav storage yes
caldav — yes
carddav — yes
imap — yes
rss — yes
web browser
openai-compatible inference
oauth-google integration
database storage yes
search search
curl fetch
mcp tools
github — yes
notion — yes
slack — yes
microsoft-graph integration yes
git — yes
weather weather
places places
tailnet transport
feedback feedback

Object storage. One bucket over the S3 API. AWS, R2, B2, Wasabi, MinIO and Garage all answer it.

Serves storage
Accepts */*
Up to —
Syncs yes
Connected through masks no
Reached through a transport yes
Attached from the app yes
Field Label Kind Required Held Asked when Help
endpoint Endpoint string yes
region Region string
prefix Prefix string Left off, the whole bucket is walked.
force_path_style Address the bucket by path boolean On for MinIO and Garage. Off for AWS’ own endpoints.
access_key_id Access key string yes encrypted
secret_access_key Secret key string yes encrypted
Command Arguments
list prefix: string? continuation_token: string?
get key: string version_id: string?
keep key: string
put key: string body: bytes

A directory. A directory on the machine running xixo, inside this tenant’s own directory under a root the server was started with. A relative path is taken from there.

Serves storage
Accepts */*
Up to —
Syncs yes
Connected through masks no
Reached through a transport no
Attached from the app yes
Field Label Kind Required Held Asked when Help
root Directory string yes
prefix Prefix string Left off, the whole directory is walked.
Command Arguments
list prefix: string? limit: integer?
get key: string
keep key: string
put key: string body: bytes

WebDAV. A WebDAV collection — Nextcloud, ownCloud, or anything else speaking it.

Serves storage
Accepts */*
Up to —
Syncs yes
Connected through masks no
Reached through a transport yes
Attached from the app yes
Field Label Kind Required Held Asked when Help
url Collection URL string yes
prefix Prefix string Left off, the whole collection is walked.
username Username string encrypted
password Password string encrypted
Command Arguments
list prefix: string? limit: integer?
get key: string
keep key: string
put key: string body: bytes

Calendars. A CalDAV collection. Only the events in it are catalogued.

Serves —
Accepts —
Up to —
Syncs yes
Connected through masks no
Reached through a transport yes
Attached from the app yes
Field Label Kind Required Held Asked when Help
url Collection URL string yes
prefix Prefix string Left off, the whole collection is walked.
username Username string encrypted
password Password string encrypted
Command Arguments
list prefix: string? limit: integer?
get key: string
keep key: string

Contacts. A CardDAV collection. Only the cards in it are catalogued.

Serves —
Accepts —
Up to —
Syncs yes
Connected through masks no
Reached through a transport yes
Attached from the app yes
Field Label Kind Required Held Asked when Help
url Collection URL string yes
prefix Prefix string Left off, the whole collection is walked.
username Username string encrypted
password Password string encrypted
Command Arguments
list prefix: string? limit: integer?
get key: string
keep key: string

A mailbox. One IMAP mailbox. Messages are catalogued, and their attachments become items of their own.

Serves —
Accepts —
Up to —
Syncs yes
Connected through masks no
Reached through a transport yes
Attached from the app yes
Field Label Kind Required Held Asked when Help
host Server string yes
port Port integer Left off, 993 with TLS and 143 without.
ssl Over TLS boolean
mailbox Mailbox string
username Username string yes encrypted
password Password string yes encrypted
Command Arguments
list limit: integer?
get uid: integer
search query: string

A feed. An RSS or Atom feed. Each entry becomes an item.

Serves —
Accepts —
Up to —
Syncs yes
Connected through masks no
Reached through a transport yes
Attached from the app yes
Field Label Kind Required Held Asked when Help
url Feed URL string yes
Command Arguments
list limit: integer?
get id: string

The web. What renders an address into a page you keep. One is enough for a tenant — snapshots go to your default storage.

Serves browser
Accepts —
Up to —
Syncs no
Connected through masks no
Reached through a transport no
Attached from the app yes
Field Label Kind Required Held Asked when Help
width Render width integer How wide the window is when the page is taken.
Command Arguments
snapshot url: string width: integer? full_page: boolean?
list limit: integer?
get url: string

A model backend. Anything speaking the OpenAI chat API — ollama, LM Studio, llama.cpp, vLLM, or a hosted one. Name a model for each role you want it to serve.

Serves inference
Accepts —
Up to —
Syncs no
Connected through masks no
Reached through a transport yes
Attached from the app yes
Field Label Kind Required Held Asked when Help
base_url Base URL string yes
models.fast Fast model string Short summaries and titles.
models.smart Smart model string Longer reasoning.
models.vision Vision model string Anything that has to look at an image.
models.agent Agent model string What a feed drives. It has to call tools.
models.embedding Embedding model string What search compares meaning with. Its vectors have to be the width the index was built for.
embedding_prefixes.query Query prefix string Put before a search when it is embedded. Left off, xixo uses what nomic-embed-text, e5, mxbai and bge were trained with, and nothing for any other model.
embedding_prefixes.document Document prefix string Put before what is catalogued when it is embedded. Left off, as above.
routine_effort Effort on routine work choice of `` none minimal low medium high How hard a reasoning model thinks while filing what arrives. Sent as reasoning_effort. Ollama takes none, and OpenAI minimal or low.
ask_effort Effort on questions choice of `` minimal low medium high model How hard a reasoning model thinks before it answers a question. Sent as reasoning_effort. Left at none, it answers without thinking, several times sooner.
time_allowed Time per ask integer Minutes an ask answered by this backend starts with when its item sets no timeout. An agent asks for more as it needs it. Left off, two minutes.
api_key API key string encrypted Left off where the backend wants none.
Command Arguments
models —

Google Drive. Connected through masks with your Google account. masks keeps the tokens and hands xixo a fresh one when it needs it, so no secret is ever typed into xixo.

Serves integration
Accepts —
Up to —
Syncs no
Connected through masks yes
Reached through a transport no
Attached from the app yes

None.

Command Arguments
list query: string? folder: string? page_token: string? limit: integer?
get id: string
Serves storage
Accepts */*
Up to 64 MB
Syncs yes
Connected through masks no
Reached through a transport no
Attached from the app no
Command Arguments
list prefix: string?
get key: string
put key: string body: bytes

Web search. Somewhere to look when the answer is not in the catalog. Exa, Brave and Tavily each want the same three fields. Results are read and reasoned over; nothing found this way is kept.

Serves search
Accepts —
Up to —
Syncs no
Connected through masks no
Reached through a transport yes
Attached from the app yes
Field Label Kind Required Held Asked when Help
provider Provider string yes exa, brave or tavily.
endpoint Endpoint string Left off, the provider’s own.
api_key API key string yes encrypted
Command Arguments
search query: string limit: integer?

Fetch a page. Reads one address over HTTP, the way curl would, so an agent can read a page a search turned up. Private and local addresses are refused, and nothing it reads is kept unless something chooses to keep it.

Serves fetch
Accepts —
Up to —
Syncs no
Connected through masks no
Reached through a transport yes
Attached from the app yes

None.

Command Arguments
get url: string

An MCP server. Somebody else’s tools, offered beside the catalog’s own. Checking it asks what it can do; its tools then answer under this resource’s key, so two servers can both have a search without colliding.

Serves tools
Accepts —
Up to —
Syncs no
Connected through masks no
Reached through a transport yes
Attached from the app yes
Field Label Kind Required Held Asked when Help
url Address string yes
auth Authentication choice of none bearer basic header masks
provider Provider in masks string yes auth is masks The key masks knows this server’s authorization server by. Attaching sends you to masks to connect your account, and xixo never sees a password or a pasted token.
token Bearer token string yes encrypted auth is bearer Sent as Authorization: Bearer.
username Username string yes encrypted auth is basic
password Password string yes encrypted auth is basic
header_name Header string yes auth is header
header_value Value string yes encrypted auth is header Sent as it is typed, on every request.
Command Arguments
tools —
call name: string arguments: json?

GitHub. Issues and pull requests from the repositories you name, each one an item with its body and its discussion.

Serves —
Accepts —
Up to —
Syncs yes
Connected through masks no
Reached through a transport no
Attached from the app yes
Field Label Kind Required Held Asked when Help
token Access token string yes encrypted A personal access token with read access to the repositories below.
repos Repositories string yes One owner/name per line, or separated by commas.
state Which ones string open, closed, or all. all by default.
Command Arguments
list repo: string? limit: integer?
get key: string
keep key: string

Notion. Every page the integration has been shared with, each one an item carrying its text. Pages are shared with an integration from Notion, not from here.

Serves —
Accepts —
Up to —
Syncs yes
Connected through masks no
Reached through a transport no
Attached from the app yes
Field Label Kind Required Held Asked when Help
token Internal integration secret string yes encrypted From the integration’s page under Notion’s settings.
query Only pages matching string Left empty, every shared page is catalogued.
Command Arguments
list query: string? limit: integer?
get id: string
keep id: string

Slack. Threads from the channels the app has been invited to, each one an item. A bot token reads what it was invited to and nothing else.

Serves —
Accepts —
Up to —
Syncs yes
Connected through masks no
Reached through a transport no
Attached from the app yes
Field Label Kind Required Held Asked when Help
token Bot token string yes encrypted Needs channels:read, channels:history and users:read. A bot still has to be invited to each channel.
channels Only these channels string One name per line. Left empty, every channel the bot is in is catalogued.
Command Arguments
list channel: string? limit: integer?
get key: string
keep key: string

OneDrive. Connected through masks with your Microsoft account. masks keeps the tokens and hands xixo a fresh one when it needs it, so no secret is ever typed into xixo.

Serves integration
Accepts —
Up to —
Syncs yes
Connected through masks yes
Reached through a transport no
Attached from the app yes
Field Label Kind Required Held Asked when Help
folder Only under this folder string A path within the drive. Left empty, the whole drive is catalogued.
Command Arguments
list folder: string? limit: integer?
get id: string
keep id: string

A git repository. Every file at the tip of one branch, each one an item. The clone is shallow and bare — the history is not the catalogue.

Serves —
Accepts —
Up to —
Syncs yes
Connected through masks no
Reached through a transport yes
Attached from the app yes
Field Label Kind Required Held Asked when Help
url Repository URL string yes
ref Branch string The default branch unless you name another.
token Access token string encrypted Only for a private repository. It travels through an askpass helper, never in the URL or the command line.
Command Arguments
list prefix: string? limit: integer?
get path: string
keep path: string

Weather. Current conditions and the forecast for any place, looked up when asked. Open-Meteo answers without a key for personal use; a key from its paid plan is used when one is given. Attach more than one to keep several providers or keys.

Serves weather
Accepts —
Up to —
Syncs no
Connected through masks no
Reached through a transport no
Attached from the app yes
Field Label Kind Required Held Asked when Help
provider Provider choice of open-meteo
units Units choice of metric imperial
api_key API key string encrypted Left off, the free service answers, which is for non-commercial use.
Command Arguments
forecast place: string? latitude: number? longitude: number? days: integer?

Places. Addresses, coordinates, and what is nearby, from OpenStreetMap. It answers without a key: Nominatim finds a place and names coordinates, and Overpass finds what is around them. The public servers ask for a light touch, so point it at your own for heavy use.

Serves places
Accepts —
Up to —
Syncs no
Connected through masks no
Reached through a transport no
Attached from the app yes
Field Label Kind Required Held Asked when Help
provider Provider choice of openstreetmap
search_url Search server string A Nominatim server. Left off, the public one, which allows about one request a second.
nearby_url Nearby server string An Overpass API interpreter. Left off, the public one.
photos Name where photos were taken boolean Sends the coordinates in each photo’s EXIF to the search server, so a photo is catalogued by the place it was taken.
Command Arguments
find query: string limit: integer?
reverse latitude: number longitude: number
nearby kind: string place: string? latitude: number? longitude: number? radius: integer?
Serves transport
Accepts —
Up to —
Syncs no
Connected through masks no
Reached through a transport no
Attached from the app no

Feedback. Takes any question no tool here can answer, answers none of them, and keeps each as a note in the /feedback feed: what was asked, what it was for, and what would have helped. That feed reviews them every week and proposes what to change.

Serves feedback
Accepts —
Up to —
Syncs no
Connected through masks no
Reached through a transport no
Attached from the app yes

None.

Command Arguments
ask question: string context: string? wanted: string?