Skip to main content
Glama
OpenRhyme

openrhyme-mcp

Official
by OpenRhyme

openrhyme-mcp

A thin Model Context Protocol server that exposes the timeline captured by the OpenRhyme engine to any agent — Claude, local models, your own scripts — over stdio.

Status: MVP implemented on this branch — a stdio MCP server exposing the engine's raw event timeline and app-allowlist controls, tested against a fixture store and a fake engine binary. The engine it depends on (OpenRhyme/OpenRhyme) has its Part 1 (capture) complete. Pending: dogfooding against a live engine capture; richer retrieval (sessions, search, embeddings) is future work.

What it is, and is not

OpenRhyme is a local-first, open-source "Computer History" for macOS: a Swift daemon reads your activity through the accessibility API, stores it in tiered SQLite, and compacts it without any bundled model. This repository is the agent-facing door to that data. It:

  • speaks MCP over stdio, so any agent host (Claude Desktop, Claude Code, …) can spawn it;

  • reads the engine's SQLite tiers read-only;

  • shells out to the openrhyme CLI (openrhyme <cmd> --json) for control commands;

  • contains no capture logic, holds no macOS permissions, and makes no network calls.

Everything stays on your machine. The agent host that spawns this server is the trust boundary — it sees exactly what the tools return, nothing more.

Related MCP server: riven-mcp

How the pieces fit

 openrhyme daemon (Swift, launchd)  ──writes──▶  ~/Library/Application Support/OpenRhyme/*.sqlite
                                                              │
                                                   read-only  │        `openrhyme … --json`
                                                              ▼                 │
                          agent host ──stdio──▶  openrhyme-mcp (this repo) ─────┘

The full process topology, the CLI/JSON contract, and the store layout are specified in the engine repo: docs/engine-interface.md. That document is the contract this server implements; it is not duplicated here.

Tools & resources

MCP tool

Returns

events(since, until, kinds, app, limit, max_value_chars)

raw events in a time window: {"events": [...], "count": n}

status()

engine trust/daemon/store status, plus this server's schema and db info

apps()

the capture allowlist and currently running apps

allow_app(bundle_id) / deny_app(bundle_id)

add/remove an app from the capture allowlist, by bundle identifier

MCP resource

Contents

openrhyme://events/recent

the last 15 minutes of raw events, as JSON Lines

Richer retrieval (sessions, full-text search, embeddings) is future work, not yet built.

Development

Requires Python 3.12+ and uv.

make sync        # uv sync --all-groups
make check       # ruff + mypy (strict) + pytest
uv run openrhyme-mcp   # serve on stdio (Ctrl-C to stop)

Tests run in-process against a fixture database and a fake openrhyme script; they never need the real engine or a macOS permission. CI runs on Ubuntu and macOS 26.

Using it with an agent

With the engine built (../OpenRhyme, make build) and on PATH — or pointed to via OPENRHYME_BIN:

claude mcp add openrhyme -- uv run --directory /path/to/openrhyme-mcp openrhyme-mcp

Then ask: "What was I doing between 2 and 3 pm?" — the model calls events(since="…", until="…"). Tools: events, status, apps, allow_app, deny_app; resource: openrhyme://events/recent. Environment: OPENRHYME_DATA_DIR (engine data dir), OPENRHYME_BIN (engine binary).

License

MIT — see LICENSE.

Available Tools

5 tools
allow_appA

Add an app to the capture allowlist by bundle identifier (e.g. com.apple.Safari). Takes effect within a few seconds; the daemon reloads its config on each heartbeat.

ParametersJSON Schema
NameRequiredDescriptionDefault
bundle_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral burden. It adds the key detail that changes take effect within seconds due to a daemon heartbeat reload, which is useful operational context. It does not disclose permissions, error cases, or list overwrite behavior, but the provided timing detail is meaningful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler: the first states the action and parameter, the second provides behavioral context. Every word earns its place, and the most important information leads.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one required parameter) and an output schema, the description covers the essential purpose, parameter, and effect. It omits explicit reference to deny_app, but the core details needed to invoke the tool are present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains that the bundle_id is the app identifier and supplies a concrete example ('com.apple.Safari'), adding value beyond the schema's generic 'Bundle Id' label. For a single-parameter tool this is sufficient.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Add') and resource ('capture allowlist'), and identifies the parameter as a bundle identifier with an example. This clearly differentiates the tool from its sibling deny_app and makes its function immediately obvious.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states what the tool does but does not explicitly mention when to use it versus alternatives like deny_app. The sibling context implies a complementary relationship, but the description itself offers no direct usage guidance or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

appsC

The capture allowlist and the currently running apps (with bundle identifiers, whether each is allowlisted, and whether it is an Electron app).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It only describes the data content and does not state that this is a read-only operation, whether any side effects occur, or if special permissions are needed. The passive phrasing 'The capture allowlist...' leaves the action implicit, offering no explicit behavioral transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that packs meaningful details (allowlist, bundle identifiers, allowlisted status, Electron app flag) without redundancy. It is front-loaded and compact, though a verb would make it structurally clearer as an action description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (no parameters) and the existence of an output schema, the description provides adequate insight into the returned content. However, it lacks any mention of when or why an agent would use this tool relative to its siblings, and it does not clarify whether this is a snapshot or a live listing, leaving moderate ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and an empty input schema, so by the rubric the baseline 4 applies. The description has no parameter-related content to add, but with no parameters there is nothing missing; the baseline is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies the resource ('capture allowlist and the currently running apps') and enumerates specific attributes (bundle identifiers, allowlist status, Electron flag), but lacks an explicit verb such as 'list' or 'get'. It is clear what the tool returns, but the absence of a verb weakens the action clarity and does not distinguish it strongly from sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus its siblings (events, status, allow_app, deny_app). The description does not mention alternatives, exclusions, or any specific contexts that would prompt an agent to call this tool over others. Usage must be inferred entirely from the name and content.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deny_appA

Remove an app from the capture allowlist by bundle identifier.

ParametersJSON Schema
NameRequiredDescriptionDefault
bundle_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It declares the action is to remove (mutation), but does not disclose consequences like reversibility, persistence, whether permissions are required, impact on actively-captured sessions, or any side effects. For a destructive operation, this is a notable gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence with no filler. The most important functional details (action, resource, scope, key) are all included, and it deliberately omits anything superfluous.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simple nature (one parameter, no nested objects) and an existing output schema, the description covers the essential invocation information. It lacks a note about whether the operation is reversible or how to confirm the result, but for a tool of this simplicity, the description is sufficient for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has a single 'bundle_id' parameter with no schema-native description (0% coverage). The tool description explicitly explains it as 'bundle identifier,' which gives meaning to the parameter beyond the parameter name, providing the necessary context for the agent to supply it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Remove'), a target resource ('an app from the capture allowlist'), and the key ('by bundle identifier'), making it unambiguous and distinct from the sibling tool allow_app, which would add an app instead.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no explicit guidance on when to use this tool versus staying on the fate delta of the sibling allow_app, nor does it mention conditions or alternatives. The context of being in an allowlist implies it should be used when revoking access, but this is only implicit and not spelled out in the description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eventsA

Raw activity events between since and until, oldest first.

Returns {"events": [...rows...], "count": N}; each row's keys are the event columns (bundle_id, app_name, window_title, kind, value, ...) and a local-ISO "time" field. Read result["events"] for the rows.

Times accept 2h / 30m / 1d (that long ago), unix seconds, or ISO-8601. kinds filters by event kind (e.g. app.activated, window.focused, context.snapshot, element.value_changed); app by bundle identifier. value/selected_text are cut to max_value_chars (0 = full text). limit ≤ 2000.

ParametersJSON Schema
NameRequiredDescriptionDefault
appNo
kindsNo
limitNo
sinceYes
untilNo
max_value_charsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden, and it does an excellent job. It discloses the return shape ({

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured into clear paragraphs and each sentence serves a purpose: explaining scope, return format, time formats, filtering options, and truncation behavior. No fluff or redundancy. The key behavioral details are front-loaded at the beginning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the six parameters (one required), the fact that there's no output schema, and no annotations, the description is exceptionally complete. It explains what the tool returns in full, how to handle the output, how to specify a time range, and all options. An agent has enough to call this tool correctly without misunderstanding. Combined with a clear output shape, it is adequate for any reasonably cautious agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the schema description coverage is 0%, the description completely compensates. For each parameter, it explains the meaning and format (e.g., `since`, `until` accepting duration strings like `2h` or ISO-8601, `kinds` as an array of strings like `app.activated`, and `value*/selected_text` being truncated). The description is more informative than the schema itself, making parameter usage unambiguous.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: returning raw activity events between a time range, oldest first. It specifies the resource (raw activity events), the verb (returns), and the ordering. It distinguishes itself from siblings by being the only one that retrieves raw event data; the siblings (such as status, apps) are clearly different purposes. The description is specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains how to use the tool, including time formats, filters (kinds, app), and constraints (max_value_chars, limit). While it doesn't explicitly say 'use this when you need raw events instead of status or app lists', the extensive parameter and return-format guidance implicitly makes the usage context highly clear, and the sibling names suggest different resources. The absence of explicit 'when not to use' is minor given the clarity of the alternatives via the schema and names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

statusA

Engine status (trust, daemon liveness, event count, allowlist) plus this server's view: supported schema, database path and whether it exists.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It lists output fields but does not explicitly state that this is a read-only, non-mutating operation, nor does it mention permissions or side effects. The description focuses on content, not behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that packs in all relevant information without any redundancy. It is front-loaded with the core 'engine status' and then lists the server view items efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has no parameters and an output schema exists, the description fully covers what the tool does and what it returns. There is nothing an agent needs to call it correctly that is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the input schema is automatically fully covered. The description adds context about what the status includes, and with no parameters to document, a baseline of 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states what the tool exposes: engine status (trust, daemon liveness, event count, allowlist) plus server view details. It names the specific resource and scope, distinguishing it from siblings like events and apps, though it lacks an explicit verb like 'get' or 'retrieve'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage context is implied by the tool name and description: it is a status/health check. However, there is no explicit guidance on when to prefer this over siblings, no exclusions, and no alternative suggestions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 5 tool updatesv0.1.0
    • First observedallow_app
    • First observedapps
    • First observeddeny_app
    • First observedevents
    • First observedstatus

TDQS

A3.9/5.0
Disambiguation5/5

Each tool has a clearly distinct role: events queries captured activity data, status reports engine/server state, apps lists the allowlist and running apps, and allow_app/deny_app make targeted allowlist changes. There is no functional overlap between any of these tools.

Naming Consistency4/5

The read-only tools use noun-style names (events, status, apps) while the mutations use verb_noun style (allow_app, deny_app). This is fairly predictable and readable, though not as uniform as a single verb_noun convention throughout.

Tool Count5/5

Five tools is well-scoped for this server's purpose: querying activity events, checking engine status, listing apps, and managing the allowlist. Each tool earns its place without the surface feeling bloated or thin.

Completeness5/5

The core workflows are fully covered: retrieve activity data, inspect engine health, view the allowlist, and add or remove apps from it. Since events are an append-only raw log, update/delete operations are not expected here, so there are no obvious gaps.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    This MCP server exposes Riven's chat, research, council, and usage capabilities as tools over stdio, enabling any MCP-compatible client to interact with Riven directly.
    4
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Search and read locally-recorded meeting transcripts over stdio. Read-only, no network. Exposes list_sessions, get_session, and search_transcripts to any MCP client.
    7
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/OpenRhyme/openrhyme-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server