I wanted a way to use various AI's to review my novel and add keywords, give summaries, and other various manual tasks that were hard to do at scale inside the application. Keep in mind, this is entire opensource and not supported by the vendor. It is only as good as what calls the vendor exposes to the users.
Ulysses MCP Server
An MCP (Model Context Protocol) server that enables AI assistants to interact with the Ulysses writing application on macOS.
Blog
Building Ulysses Mcp From Frustration To A Smarter Writing Workflow
Overview
This MCP server provides comprehensive tools to automate Ulysses via its x-callback-url API, allowing AI assistants like Claude, Cline, and other MCP-compatible clients to:
- 📝 Create and manage sheets - Create new documents with content
- 📁 Organize with groups - Create and manage folder structures
- ✏️ Add content - Insert or append text to existing sheets
- 🏷️ Attach metadata - Add notes, keywords, and images to sheets
- 📖 Read content - Extract sheet contents and metadata (requires authorization)
- 🧭 Navigate - Open specific sheets, groups, or special sections
- 🔧 Modify - Move, copy, rename, and delete items (requires authorization)
Prerequisites
- macOS (Ulysses is Mac/iOS only)
- Ulysses installed
- Node.js 18.0.0 or higher
- An MCP-compatible client (Claude Desktop, Cline, etc.)
Installation
Using npm
npm install ulysses-mcp
From Source
git clone https://github.com/sonofagl1tch/ulysses-mcp.git
cd ulysses-mcp
npm install
npm run build
Building the Helper App
⚠️ IMPORTANT: The helper app binary is not included in this repository for security reasons. You must build it locally after installation.
After installation, you need to build the helper app (required for callback operations):
npm run build-helper
This creates a small macOS application that handles callbacks from Ulysses. The helper app:
- Runs automatically when needed (you don't need to start it manually)
- Registers a custom URL scheme (
ulysses-mcp-callback://) - Enables operations that require callbacks (authorization, reading content, etc.)
- Should never be committed to version control (already in .gitignore)
For more details, see Helper App Documentation.
Configuration
For Claude Desktop
Add to your Claude Desktop configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"ulysses": {
"command": "node",
"args": ["/path/to/ulysses-mcp/build/index.js"]
}
}
}
For Cline (VS Code Extension)
Add to Cline's MCP settings:
macOS: ~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json
{
"mcpServers": {
"ulysses": {
"disabled": false,
"autoApprove": [],
"type": "stdio",
"command": "node",
"args": ["/path/to/ulysses-mcp/build/index.js"]
}
}
}
For Other MCP Clients
Refer to your client's documentation for adding MCP servers via stdio transport.
Available Tools
The server provides 23 tools organized into the following categories:
Content Creation
ulysses_new_sheet- Create a new sheet with contentulysses_new_group- Create a new group (folder)
Content Modification
ulysses_insert- Insert/append text to existing sheetsulysses_attach_note- Attach notes to sheetsulysses_attach_keywords- Add keywords (tags)ulysses_attach_image- Attach images (base64)
Navigation
ulysses_open- Open specific sheet or groupulysses_open_all- Open "All" sectionulysses_open_recent- Open "Last 7 Days"ulysses_open_favorites- Open "Favorites"
Information & Authorization
ulysses_get_version- Get Ulysses and API versionulysses_authorize- Request library access (required for reading)ulysses_read_sheet- Read sheet contents (requires auth)ulysses_get_item- Get sheet/group info (requires auth)ulysses_get_root_items- Get library structure (requires auth)
Advanced Operations (Require Authorization)
ulysses_move- Move sheets/groupsulysses_copy- Copy sheets/groupsulysses_trash- Move items to trashulysses_set_group_title- Rename groupsulysses_set_sheet_title- Change sheet titlesulysses_remove_keywords- Remove keywordsulysses_update_note- Update existing notesulysses_remove_note- Remove notes
Usage Examples
Creating a New Sheet
// Create a daily journal entry
{
"tool": "ulysses_new_sheet",
"arguments": {
"text": "# Journal Entry - October 23, 2025\n\nToday I...",
"group": "/Journal",
"format": "markdown"
}
}
Adding Keywords
// Tag a sheet for organization
{
"tool": "ulysses_attach_keywords",
"arguments": {
"id": "sheet-identifier-here",
"keywords": "Draft,Blog,Technical"
}
}
Reading Content (Requires Authorization)
// First, authorize
{
"tool": "ulysses_authorize",
"arguments": {
"appname": "My AI Assistant"
}
}
// After approving in Ulysses, use the token to read
{
"tool": "ulysses_read_sheet",
"arguments": {
"id": "sheet-identifier-here",
"text": "YES",
"access_token": "your-access-token"
}
}
Getting Sheet Identifiers
Sheet and group identifiers are required for many operations. Here's how to get them:
On Mac
- Select a sheet in the sheet list
- Press ⌘C (command-C) to copy its identifier
- Or: Hold ⌥ (option/alt) while right-clicking → "Copy Callback Identifier"
On iOS/iPadOS
- Touch and hold a sheet
- Select "Share" → "Share Shortcuts Identifier" → "Copy"
- For groups: Tap
…button → Share → Share Shortcuts Identifier
Identifiers look like: H8zLAmc1I0njH-0Ql-3YGQ
Authorization
Some operations (reading content, destructive changes) require authorization:
- Use the
ulysses_authorizetool with your app name - Approve the authorization request in Ulysses
- Copy the provided access token
- Use the token in subsequent operations that require it
Access tokens persist until revoked in Ulysses preferences.
Security
⚠️ PRIVACY WARNING: While this MCP server is completely local and private, your AI assistant may send data to cloud services depending on your configuration:
- Cloud AI (Claude Desktop, ChatGPT, etc.): Your writing may be sent to their servers
- Local AI (Ollama, LM Studio): Stays completely local ✅
For sensitive content, use local-only AI models. See Privacy Documentation for details.
Access Token Handling
⚠️ IMPORTANT SECURITY WARNINGS:
- Access tokens provide full access to your Ulysses library. Treat them like passwords.
- Never commit tokens to version control or share them publicly.
- Store tokens securely if you need to persist them between sessions.
- Revoke tokens you no longer need via Ulysses → Preferences → Privacy.
- Rate limiting: Destructive operations are limited to 10 per minute to prevent accidental damage.
Input Validation
This server implements comprehensive input validation:
- Required parameters are validated for presence and non-empty values
- Text inputs have reasonable length limits (1MB for content, 100KB for notes)
- Enum values are validated against allowed options
- All actions are validated against a whitelist
- Command injection is prevented via secure command execution
Security Features
- ✅ Command injection protection using
execFileinstead ofexec - ✅ Input validation on all parameters
- ✅ Action whitelist validation
- ✅ Rate limiting on destructive operations
- ✅ Sanitized error messages
- ✅ No sensitive data exposure in logs
Reporting Security Issues
If you discover a security vulnerability, please email sonofagl1tch@pebcakconsulting.com or open a security advisory on GitHub. Do not open public issues for security vulnerabilities.
Use Cases
Content Creation Workflows
- Blog Writing: Generate posts with AI and save to Ulysses
- Daily Journaling: Auto-create dated entries
- Note Taking: Quick capture with AI assistance
- Research Organization: Structure research with AI help
Content Management
- Batch Tagging: Organize content with keywords
- Content Review: Analyze sheets programmatically
- Library Organization: Automate structure and filing
- Backup & Archive: Export content systematically
AI-Assisted Writing
- Content Generation: AI writes, saves to Ulysses
- Editing Assistance: Read, suggest, update content
- Research Integration: Fetch and incorporate research
- Outline Expansion: Turn briefs into full articles
Limitations & Future Enhancements
Current Limitations
The MCP server is limited by the capabilities of the Ulysses x-callback-url API. Some features available in the Ulysses GUI are not currently available via the API:
Not Currently Supported:
- ❌ Search functionality - Cannot search across sheets by content or metadata
- ❌ Statistics - Cannot retrieve word counts, character counts, or reading time
- ❌ Export operations - Cannot export sheets to PDF, DOCX, or other formats
- ❌ Publishing - Cannot publish directly to WordPress, Medium, or other platforms
- ❌ Goals and targets - Cannot set or retrieve writing goals
- ❌ Sheet history - Cannot access revision history or version control
- ❌ Filters - Cannot filter sheets by date, keywords, or other criteria
- ❌ Favorites management - Cannot mark/unmark sheets as favorites via API
- ❌ Theme/appearance - Cannot control Ulysses appearance or editor settings
Feature Request Submitted
A feature request has been submitted to Ulysses to expand the x-callback-url API with additional capabilities. If you'd like to see more features, consider:
- Voting on the feature request (link TBD when available)
- Contacting Ulysses support to express interest in API expansion
- Sharing use cases that would benefit from enhanced API access
Workarounds
For some limitations, partial workarounds exist:
- Statistics: Read sheet content and calculate locally
- Search: Use
get-root-itemswithrecursive=YESand filter locally - Export: Read content and export using external tools
Potential Future Enhancements
If the Ulysses API is expanded, this MCP server could potentially support:
- 🔮 Full-text search across the library
- 🔮 Export sheets to various formats
- 🔮 Retrieve writing statistics and analytics
- 🔮 Manage writing goals and targets
- 🔮 Access revision history
- 🔮 Advanced filtering and sorting
- 🔮 Publishing integrations
Note: These enhancements depend on Ulysses expanding their x-callback-url API. The MCP server is designed to be easily updated when new API capabilities become available.
📚 Documentation
For detailed information about architecture, security, privacy, and authentication, see the comprehensive documentation in the docs/ directory:
- Architecture - System architecture, data flows, and technical details
- Authentication - Authorization model, access tokens, and security
- Privacy & Security - Privacy guarantees, security features, and verification
- Documentation Index - Complete documentation overview
Development
Building
npm run build
Watching for Changes
npm run watch
Testing with MCP Inspector
npm run inspector
Project Structure
ulysses-mcp/
├── src/
│ └── index.ts # Main server implementation
├── build/ # Compiled JavaScript output
├── package.json
├── tsconfig.json
├── README.md
└── LICENSE
API Reference
This server implements Ulysses x-callback-url API version 3.
For detailed API documentation:
Troubleshooting
Server Not Connecting
- Verify Ulysses is installed on your Mac
- Check the build path in your MCP configuration
- Rebuild the server:
npm run build - Restart your MCP client
Authorization Issues
- Run
ulysses_authorizeto get a new token - Approve the request in Ulysses when prompted
- Copy and save the access token
- Check token hasn't been revoked in Ulysses preferences
Sheet Identifiers Not Working
- Verify the 22-character identifier format
- Ensure the sheet still exists in Ulysses
- Note: External folder identifiers may change if items move
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Disclaimer
This is an unofficial tool and is not affiliated with or endorsed by Ulysses GmbH & Co. KG. Ulysses is a trademark of Ulysses GmbH & Co. KG.
Acknowledgments
- Ulysses - For creating an excellent writing application with a powerful automation API
- Model Context Protocol - For providing the framework to connect AI assistants with tools
- Anthropic - For Claude and the MCP initiative
Support
- Issues: GitHub Issues
- Ulysses Support: ulysses.app/support
- MCP Documentation: modelcontextprotocol.io
Made with ❤️ for the Ulysses and AI community