Skip to content

Commit 6d91eb2

Browse files
committed
Refactor jxa scripts to accept a CLI flag with the path to scripts, else attempt
auto-detection. Update the docs accordingly Co-authored-by: Claude v2.0.24 + Claude Sonnet 4.5, with the prompt: ``` Convert golang modules in @internal/ to use a command line flag which specifies the path for `jxa` scripts. Update @*.md to set the flag to the jxa scripts as an MCP args parameter ```
1 parent bded3b6 commit 6d91eb2

File tree

6 files changed

+91
-8
lines changed

6 files changed

+91
-8
lines changed

CLAUDE.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ scripts/ # JXA automation scripts
6464
### Running
6565
- `make run` - Run the server directly with `go run`
6666
- `./bin/mcp-omnifocus` - Run the compiled binary
67+
- `./bin/mcp-omnifocus -scripts /path/to/scripts` - Run with explicit scripts path
6768

6869
### Testing JXA Scripts
6970
Scripts can be tested independently:
@@ -91,7 +92,29 @@ All tools are registered in `cmd/mcp-omnifocus/main.go` in the `registerTools()`
9192
## Important Implementation Notes
9293

9394
### Script Path Resolution
94-
The client automatically detects the JXA scripts directory by checking multiple locations in this order:
95+
96+
The server supports two ways to specify the scripts directory:
97+
98+
#### 1. Command Line Flag (Recommended)
99+
Use the `-scripts` flag to explicitly specify the path:
100+
```bash
101+
./bin/mcp-omnifocus -scripts /path/to/scripts
102+
```
103+
104+
This is the recommended approach for MCP configurations:
105+
```json
106+
{
107+
"mcpServers": {
108+
"omnifocus": {
109+
"command": "/path/to/mcp-omnifocus",
110+
"args": ["-scripts", "/path/to/scripts"]
111+
}
112+
}
113+
}
114+
```
115+
116+
#### 2. Auto-Detection (Fallback)
117+
If the `-scripts` flag is not provided, the client automatically detects the JXA scripts directory by checking multiple locations in this order:
95118
1. Scripts directory next to the binary (release package layout)
96119
2. Scripts directory one level up (for bin/mcp-omnifocus structure)
97120
3. Homebrew installation path (`../share/mcp-omnifocus/scripts/`)

QUICKSTART.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ This creates the executable at `bin/mcp-omnifocus`.
3737
{
3838
"mcpServers": {
3939
"omnifocus": {
40-
"command": "/absolute/path/to/mcp-omnifocus/bin/mcp-omnifocus"
40+
"command": "/absolute/path/to/mcp-omnifocus/bin/mcp-omnifocus",
41+
"args": ["-scripts", "/absolute/path/to/mcp-omnifocus/scripts"]
4142
}
4243
}
4344
}
@@ -48,12 +49,15 @@ This creates the executable at `bin/mcp-omnifocus`.
4849
{
4950
"mcpServers": {
5051
"omnifocus": {
51-
"command": "/Users/conall/Documents/GitHub/mcp-omnifocus/bin/mcp-omnifocus"
52+
"command": "/Users/conall/Documents/GitHub/mcp-omnifocus/bin/mcp-omnifocus",
53+
"args": ["-scripts", "/Users/conall/Documents/GitHub/mcp-omnifocus/scripts"]
5254
}
5355
}
5456
}
5557
```
5658

59+
**Note**: The `-scripts` argument is optional. If omitted, the server will auto-detect the scripts directory, but specifying it explicitly is more reliable.
60+
5761
3. Save the file and restart Claude Desktop.
5862

5963
### 3. Grant Permissions

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ Edit your Claude Desktop config file (usually at `~/Library/Application Support/
7676
{
7777
"mcpServers": {
7878
"omnifocus": {
79-
"command": "/Users/YOUR_USERNAME/mcp-servers/omnifocus/mcp-omnifocus"
79+
"command": "/Users/YOUR_USERNAME/mcp-servers/omnifocus/mcp-omnifocus",
80+
"args": ["-scripts", "/Users/YOUR_USERNAME/mcp-servers/omnifocus/scripts"]
8081
}
8182
}
8283
}
@@ -87,13 +88,16 @@ Edit your Claude Desktop config file (usually at `~/Library/Application Support/
8788
{
8889
"mcpServers": {
8990
"omnifocus": {
90-
"command": "/absolute/path/to/mcp-omnifocus/bin/mcp-omnifocus"
91+
"command": "/absolute/path/to/mcp-omnifocus/bin/mcp-omnifocus",
92+
"args": ["-scripts", "/absolute/path/to/mcp-omnifocus/scripts"]
9193
}
9294
}
9395
}
9496
```
9597

96-
Replace the path with the actual location where you installed or built the binary.
98+
Replace the paths with the actual locations where you installed or built the binary and scripts.
99+
100+
**Note:** The `-scripts` argument is optional. If not provided, the server will attempt to auto-detect the scripts directory. However, explicitly specifying the path is recommended for reliability.
97101

98102
## Available Tools
99103

cmd/mcp-omnifocus/main.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"encoding/json"
5+
"flag"
56
"fmt"
67
"log"
78

@@ -16,8 +17,17 @@ const (
1617
)
1718

1819
func main() {
20+
// Define command line flags
21+
scriptsPath := flag.String("scripts", "", "Path to the JXA scripts directory (if not specified, auto-detection is used)")
22+
flag.Parse()
23+
1924
// Create OmniFocus client
20-
ofClient := omnifocus.NewClient()
25+
var ofClient *omnifocus.Client
26+
if *scriptsPath != "" {
27+
ofClient = omnifocus.NewClientWithPath(*scriptsPath)
28+
} else {
29+
ofClient = omnifocus.NewClient()
30+
}
2131

2232
// Create MCP server
2333
s := server.NewMCPServer(

internal/omnifocus/client.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,21 @@ type Client struct {
1515
scriptsDir string
1616
}
1717

18-
// NewClient creates a new OmniFocus client
18+
// NewClient creates a new OmniFocus client with auto-detected scripts directory
1919
func NewClient() *Client {
2020
scriptsDir := findScriptsDir()
2121
return &Client{
2222
scriptsDir: scriptsDir,
2323
}
2424
}
2525

26+
// NewClientWithPath creates a new OmniFocus client with a specified scripts directory path
27+
func NewClientWithPath(scriptsPath string) *Client {
28+
return &Client{
29+
scriptsDir: scriptsPath,
30+
}
31+
}
32+
2633
// GetScriptsDir returns the path to the scripts directory
2734
// This is primarily used for testing and debugging
2835
func (c *Client) GetScriptsDir() string {

internal/omnifocus/client_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,38 @@ func TestNewClient(t *testing.T) {
7272

7373
t.Logf("Client initialized with scriptsDir: %s", client.scriptsDir)
7474
}
75+
76+
func TestNewClientWithPath(t *testing.T) {
77+
// Test with a custom path
78+
customPath := "/custom/path/to/scripts"
79+
client := NewClientWithPath(customPath)
80+
81+
if client == nil {
82+
t.Fatal("NewClientWithPath returned nil")
83+
}
84+
85+
if client.scriptsDir != customPath {
86+
t.Errorf("Client scriptsDir = %s, want %s", client.scriptsDir, customPath)
87+
}
88+
89+
t.Logf("Client initialized with custom scriptsDir: %s", client.scriptsDir)
90+
91+
// Test with the actual scripts directory
92+
actualScriptsDir := findScriptsDir()
93+
client2 := NewClientWithPath(actualScriptsDir)
94+
95+
if client2 == nil {
96+
t.Fatal("NewClientWithPath returned nil for actual scripts dir")
97+
}
98+
99+
if client2.scriptsDir != actualScriptsDir {
100+
t.Errorf("Client scriptsDir = %s, want %s", client2.scriptsDir, actualScriptsDir)
101+
}
102+
103+
// Verify the GetScriptsDir method returns the correct value
104+
if client2.GetScriptsDir() != actualScriptsDir {
105+
t.Errorf("GetScriptsDir() = %s, want %s", client2.GetScriptsDir(), actualScriptsDir)
106+
}
107+
108+
t.Logf("Client initialized with actual scriptsDir: %s", client2.scriptsDir)
109+
}

0 commit comments

Comments
 (0)