integrate with solstone
your journal runs an MCP server. this page covers how to connect an agent to it or build something on it: what it offers, what you as the owner control, and where the code lives.
at a glance
- what it is
- a Model Context Protocol server inside your journal. any MCP client can use it.
- address
/mcpon whichever route you turn on. on the journal's own computer:http://127.0.0.1:7659/mcp- protocol
- MCP 2025-03-26 over Streamable HTTP. POST JSON-RPC and get JSON back.
initializereturns anMcp-Session-Id, and DELETE ends the session. - sign-in
- OAuth 2.1 hosted by the journal (PKCE S256), or a key you create for a script
- offers
- 9 tools. no resources, no prompts, no event stream, no stdio.
- writes
- only the agent's own notes. an agent can't add to, change or delete anything else in your journal.
connect an agent
- pick where the agent runs. in your journal, open agents and choose connect an agent. the route decides the address:
the agent runs address default on the journal's computer http://127.0.0.1:7659/mcpon on your wifi or VPN https://<private address>:7660/mcpoff. uses a certificate from your journal's own authority, which the agents page offers for download. anywhere, through solstone.me https://<8 characters>.solstone.me/mcpoff. $5/yr. the relay passes encrypted bytes through, and the journal holds the certificate. anywhere, at your own domain https://<your domain>/mcpoff. the journal gets its own certificate. needs a CAA record. - make a pairing code for that route. it's 8 characters, works once, and expires after 10 minutes. until a code is open, the journal won't answer a sign-in from anyone.
- add the address to your agent:
agent add it then sign in Claude Code claude mcp add --transport http journal <address>type /mcp, choose journalCodex codex mcp add journal --url <address>codex mcp login journalGemini CLI gemini mcp add --transport http journal <address>/mcp auth journalClaude on the web add a custom connector in Claude's settings, with your solstone.me or own-domain address connect it from there any other MCP client add an HTTP server at the address it should find the OAuth sign-in on its own - approve it. your browser opens a page served by your journal. choose what the agent may see (next section), enter the code, and connect.
what you control
every connection gets its own grant. you choose it when you approve the agent, and you can change it later in agents or with the solstone journal mcp commands.
| policy | your choices |
|---|---|
| how much of your journal | your whole journal: everything now and anything added later, including facets you create later. only the facets you choose: just those facets, as they grow. facets you create later aren't included. |
| what kinds of material | any of three: transcripts: what was said in your recordings and imports, as text. never the audio or the screen frames. entities: the people, places and projects your journal knows, and what it has noted about them. facets: facet names and descriptions, and the activities, events and summaries filed in them. |
| its own notes | always on. every connection can save notes, and recall only the ones it saved. other agents can find them through search if their grant covers them. you can read and delete them in your journal. |
| where it connects from | a signed-in agent only works at the route it was paired on. turn a route off in agents and nothing reaches your journal that way. |
| how long it lasts | a signed-in agent has to pair again 30 days after pairing. a script key lasts until you revoke it. |
| changing your mind | change what it may see, rename a key, or disconnect it. its activity (which tools it called and with what, when, how it ended and which entries it got back, as links, never a copy) stays in your journal. |
how a grant shapes what the agent sees
- a tool that needs a kind you didn't grant is left out of the agent's tool list
- the
facetandcategoryarguments only list what you granted, so the agent is never told about a facet it can't read - every call is checked again when it arrives, so narrowing a grant takes effect at once
for example, with transcripts only, limited to two facets, the agent is offered search like this. the facet values are the journal's ids for those facets, not their names:
{
"name": "search",
"title": "search the journal",
"annotations": { "title": "search the journal", "readOnlyHint": true, "openWorldHint": false },
"inputSchema": {
"type": "object",
"additionalProperties": false,
"properties": {
"query": { "type": "string" },
"category": { "type": "string", "enum": ["transcripts"] },
"facet": { "type": "string", "enum": ["3f1c2a9e-7b4d-4e8a-9c21-5d6e0f4b7a13", "b82e4d10-1c5f-4a7e-8d3b-2f9a6c0e5d84"] },
…
}
}
}
tools
all nine. "needs" is the kind you must grant before the tool is offered. days are YYYYMMDD or YYYY-MM-DD, and every list takes a limit of 1–100.
| tool | what it does | needs | inputs |
|---|---|---|---|
search | search what this connection may see: summaries of conversations and work sessions, activities, imported documents, calendar events, and notes on people and projects. leave out the query to list what a day holds. | transcripts | query, day / day_from / day_to, category, facet, cursor |
fetch | read the full text of a search result | transcripts | reference (required) |
list_transcripts | list transcript segments with their times, newest days first | transcripts | day, time_from / time_to (HH:MM), facet, cursor |
get_transcript | read what was said in one segment, word for word | transcripts | reference (required), cursor |
list_entities | list the people, projects and other entities this connection may see | entities | facet |
get_entity | read what the journal has noted about one entity: its type, description, the last day it came up, and notes | entities | reference (required) |
list_facets | list the facets this connection may see | nothing | |
save_memory | save a note of the agent's own, up to 32 KB. the only tool that writes. retrying with the same operation_id and content saves it once. | nothing | content, operation_id (both required) |
recall_memory | read back this connection's own notes. leave out the query to browse. | nothing | query, day / day_from / day_to, continuation, limit 1–20 |
the full input schemas, and the descriptions the agent itself reads, are in registry.rs. your agent sees the same thing when it calls tools/list.
build an integration
a script on the journal's computer: use a key
create a key, then grant it what it needs. a new key can only use its own notes until you grant it more.
solstone journal mcp token create --label my-script solstone journal mcp permission set --token my-script --category transcripts --category entities # or: transcripts from one facet only solstone journal mcp permission set --token my-script --category transcripts --facet work
keys work at the journal's own computer and through solstone.me. the wifi or VPN and own-domain routes take signed-in agents only. token list and token revoke --label manage them, and permission show / clear manage grants.
then talk to it like any MCP server:
# start a session, and keep the Mcp-Session-Id header it returns
curl -si http://127.0.0.1:7659/mcp \
-H "Authorization: Bearer $JOURNAL_KEY" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"my-script","version":"1"}}}'
# see what this key may use
curl -s http://127.0.0.1:7659/mcp -H "Authorization: Bearer $JOURNAL_KEY" \
-H "Content-Type: application/json" -H "Mcp-Session-Id: $SESSION" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# call a tool
curl -s http://127.0.0.1:7659/mcp -H "Authorization: Bearer $JOURNAL_KEY" \
-H "Content-Type: application/json" -H "Mcp-Session-Id: $SESSION" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search","arguments":{"query":"lease renewal"}}}'
# end the session
curl -s -X DELETE http://127.0.0.1:7659/mcp -H "Authorization: Bearer $JOURNAL_KEY" -H "Mcp-Session-Id: $SESSION"
an app or agent other people install: use OAuth
your client signs in the way the agents above do. each route hosts its own sign-in:
- discovery
/.well-known/oauth-protected-resource, then/.well-known/oauth-authorization-server- registration
POST /register: dynamic client registration, or a client ID metadata document (your ownhttps://URL asclient_id)- authorization
/authorizewith PKCE S256 and theresourcefrom the protected-resource metadata. public clients only, no client secrets.- tokens
POST /token,authorization_codeandrefresh_token. access tokens last 1 hour. refresh tokens rotate on every use, and reusing an old one revokes the grant.- scopes
- none. the owner picks the grant on the consent page, and your client discovers the result through
tools/list. - redirects
- loopback (
localhostor127.0.0.1, any port), or the exact callback of a hosted agent the journal recognises. the list
design for it: /register and /authorize answer 403 until the owner has a pairing code open, so tell the owner to make one first. the grant ends 30 days after pairing however often you refresh, so handle a failed refresh by asking them to pair again.
limits
| limit | |
|---|---|
| pairing code | 8 characters · one use · 10 minutes · one route · one open at a time |
| wrong codes | 5 per sign-in attempt. 20 from one source lock the code until you make a new one. |
| sessions | 16 per agent · end after 30 minutes idle |
| open connections | 256 at once (64 on the wifi or VPN and own-domain routes) |
| request body | 200 KB |
| one saved note | 32,768 bytes |
| one recall page | 20 notes · 65,536 bytes |
read the source
the server is open source. if you're building against it, or you want your agent to understand it, start here:
| what | where |
|---|---|
| the MCP server | core/crates/solstone-core-mcp-endpoint |
| the tools, their schemas, and how a grant filters them | src/registry.rs · tool code in src/tools/ |
| grants: whole journal, facets, kinds | src/permissions.rs |
| sign-in: pairing, OAuth, redirects | src/oauth/ · the written reference, docs/MCP_OAUTH.md |
routes, keys and the solstone journal mcp commands | docs/SOLCLI.md |
to have your agent read it, give it this: read https://github.com/solpbc/solstone-journal/tree/main/core/crates/solstone-core-mcp-endpoint and docs/MCP_OAUTH.md, then help me connect to my journal.
early days. found something that doesn't match what your journal does? tell us.