Skip to main content
Glama
projectwizards

Merlin Project MCP Extension

Official
README.md
# Merlin Project MCP Extension

Read-only MCP access to the project documents open in [Merlin Project](https://www.projectwizards.net)
on your Mac, packaged as a Claude Desktop Extension (`.mcpb`).

Ask about your plan, search activities, resources, assignments, risks, issues and attachments,
and pull cost, work or earned-value figures over any date range — without leaving Merlin Project.
The extension only ever reads: it never changes, saves or deletes anything in your documents. You
choose which open document Claude may see at the start of each chat, via the MCP access popover
in Merlin Project's toolbar.

## Requirements

- macOS
- [Merlin Project](https://www.projectwizards.net) installed, running, and with MCP access
  enabled for the document you want Claude to read
- Node.js 18 or newer (Claude Desktop supplies its own runtime)

## Install

Build the extension archive from source, then open the resulting `MerlinProject.mcpb` with
Claude Desktop, which will offer to install it:

```sh
npm install
npm run pack        # writes MerlinProject.mcpb
```

Merlin Project does not need to be running when you install the extension — Claude will see the
full tool list either way, and connects to the app as soon as it is launched.

## How it works

Merlin Project is sandboxed and runs its MCP server inside the app, listening on a Unix domain
socket in its App Group container. This extension is the bridge between that socket and the
stdio transport Claude Desktop speaks:

    Claude  ⇄  stdio  ⇄  extension server  ⇄  extension client (cached)  ⇄  socket  ⇄  Merlin Project

- `tools/list` / `resources/list` are answered locally from `server/catalog.json`, so Claude sees
  the full tool metadata even when Merlin Project isn't running.
- `tools/call` / `resources/read` are forwarded to the live in-app server over the socket at
  `~/Library/Group Containers/9R6P9VZV27.net.projectwizards.merlinproject.mcp/mcp.sock`
  (overridable via `MERLIN_MCP_SOCKET`, surfaced in Claude Desktop as the extension's "Socket
  Path Override" setting; leave it empty outside of testing). Because `sockaddr_un` caps socket paths at
  104 bytes — which the absolute container path exceeds for long account names — the shim
  `chdir`s into the container and connects via the relative file name.
- When Merlin Project isn't reachable, tool calls return a structured "not running" message
  telling the agent to ask you to launch the app. The extension retries the connect on every
  call, so it picks up the running app on the next request — no restart of Claude needed. It
  deliberately never launches Merlin Project by itself.
- The extension advertises the live server's identity when Merlin Project is up at session start,
  and forwards the agent's real `clientInfo` on the socket handshake, so the app's connected-tools
  popover shows "Claude" rather than the extension.

The tools themselves — `list_open_documents`, `set_current_document`, `get_schema_types`,
`get_objects`, `find_objects`, `count_objects`, `list_related`, `get_media` and
`get_time_phased_values` — are implemented inside Merlin Project, not here. This repository
contains only the bridge.

A Swift build of the same bridge ships with Merlin Project for use outside Claude Desktop. The
two are behavior-identical and are kept in sync; the file headers here name their Swift
counterparts. Unlike the Swift build, this one holds no App Group entitlement and simply
constructs the container path directly, which works for unsandboxed processes.

## Files

- `manifest.json` — MCPB manifest (`server.type: "node"`).
- `server/index.js` — entry point; stdio-facing MCP server.
- `server/bridge.js` — connection cache, socket transport, forwarding logic.
- `server/catalog.json` — generated snapshot of the live server's `tools/list` /
  `resources/list`. **Do not edit by hand.**
- `scripts/generate-catalog.js` — regenerates `server/catalog.json` from a running build.
- `scripts/test-e2e.js` — end-to-end tests (live forwarding, app-down fallback, mid-session
  recovery).

## Development

```sh
npm install                  # once, and after dependency changes
npm run generate-catalog     # after the app's tool metadata changes; needs Merlin Project running
npm test                     # phase A needs Merlin Project running; B and C are self-contained
npm run pack                 # builds MerlinProject.mcpb
```

Merlin Project itself is the single source of truth for tool and resource metadata:
`server/catalog.json` is generated by asking a running app for its `tools/list` and
`resources/list` and snapshotting the responses verbatim. It is committed so that packaging the
extension needs no running app. Regenerate it and re-pack whenever the app's tool metadata
changes.

## License

MIT — see [LICENSE](LICENSE).