lantern-connect 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -12
- package/package.json +2 -4
- package/src/index.js +8 -37
- package/src/auth.js +0 -171
package/README.md
CHANGED
|
@@ -23,9 +23,6 @@ lantern-connect
|
|
|
23
23
|
|
|
24
24
|
# Local development with ngrok
|
|
25
25
|
lantern-connect --mcp-url https://your-ngrok-url.ngrok-free.dev/mcp
|
|
26
|
-
|
|
27
|
-
# Custom Lantern instance
|
|
28
|
-
lantern-connect --lantern-url https://your-lantern.com --mcp-url https://api.your-lantern.com/mcp
|
|
29
26
|
```
|
|
30
27
|
|
|
31
28
|
## Options
|
|
@@ -33,14 +30,13 @@ lantern-connect --lantern-url https://your-lantern.com --mcp-url https://api.you
|
|
|
33
30
|
| Option | Description | Default |
|
|
34
31
|
|--------|-------------|---------|
|
|
35
32
|
| `--mcp-url <url>` | MCP server URL | `https://mcp.onlantern.com/mcp` |
|
|
36
|
-
| `--lantern-url <url>` | Lantern web URL for authentication | `https://onlantern.com` |
|
|
37
33
|
| `--help, -h` | Show help message | |
|
|
38
34
|
|
|
39
35
|
## What it does
|
|
40
36
|
|
|
41
37
|
1. **Detects** installed AI tools (Claude Desktop, Claude Code, Gemini CLI, Cursor)
|
|
42
|
-
2. **
|
|
43
|
-
3. **
|
|
38
|
+
2. **Configures** each detected tool to connect to Lantern's MCP server
|
|
39
|
+
3. **Each tool authenticates** with Lantern on first use (via OAuth)
|
|
44
40
|
|
|
45
41
|
## Supported Tools
|
|
46
42
|
|
|
@@ -54,7 +50,7 @@ lantern-connect --lantern-url https://your-lantern.com --mcp-url https://api.you
|
|
|
54
50
|
## After Installation
|
|
55
51
|
|
|
56
52
|
1. **Fully quit and reopen** your AI tools (Cmd+Q on macOS)
|
|
57
|
-
2. **
|
|
53
|
+
2. **Authenticate** when prompted by each tool on first use
|
|
58
54
|
3. Start using Lantern:
|
|
59
55
|
- Say "save to lantern" to export a conversation
|
|
60
56
|
- Say "list my lantern conversations" to see your library
|
|
@@ -63,16 +59,15 @@ lantern-connect --lantern-url https://your-lantern.com --mcp-url https://api.you
|
|
|
63
59
|
## Local Development
|
|
64
60
|
|
|
65
61
|
```bash
|
|
66
|
-
# Start your local Lantern backend and
|
|
62
|
+
# Start your local Lantern backend and MCP server
|
|
67
63
|
cd lantern && npm run dev
|
|
68
|
-
cd lantern/frontend && npm run dev
|
|
69
64
|
|
|
70
|
-
# Start ngrok to expose
|
|
71
|
-
ngrok http
|
|
65
|
+
# Start ngrok to expose MCP server (required for Claude Desktop)
|
|
66
|
+
ngrok http 3002
|
|
72
67
|
|
|
73
68
|
# Run the CLI with your ngrok URL
|
|
74
69
|
cd lantern-connect
|
|
75
|
-
node bin/lantern-connect.js --mcp-url https://your-ngrok-url.ngrok-free.dev/mcp
|
|
70
|
+
node bin/lantern-connect.js --mcp-url https://your-ngrok-url.ngrok-free.dev/mcp
|
|
76
71
|
```
|
|
77
72
|
|
|
78
73
|
## Resetting / Uninstall
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lantern-connect",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI installer to connect AI tools (Claude, Gemini, Cursor) to Lantern",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,7 +34,5 @@
|
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": ">=18.0.0"
|
|
36
36
|
},
|
|
37
|
-
"dependencies": {
|
|
38
|
-
"open": "^10.1.0"
|
|
39
|
-
}
|
|
37
|
+
"dependencies": {}
|
|
40
38
|
}
|
package/src/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { detectTools, hasAnyTools } from './detect.js'
|
|
2
|
-
import { authenticate } from './auth.js'
|
|
3
2
|
import { configureClaudeDesktop } from './configure/claude-desktop.js'
|
|
4
3
|
import { configureClaudeCode } from './configure/claude-code.js'
|
|
5
4
|
import { configureGeminiCli } from './configure/gemini-cli.js'
|
|
6
5
|
import { configureCursor } from './configure/cursor.js'
|
|
7
6
|
|
|
7
|
+
const DEFAULT_MCP_URL = 'https://mcp.onlantern.com/mcp'
|
|
8
|
+
|
|
8
9
|
const configurators = {
|
|
9
10
|
claudeDesktop: configureClaudeDesktop,
|
|
10
11
|
claudeCode: configureClaudeCode,
|
|
@@ -15,24 +16,19 @@ const configurators = {
|
|
|
15
16
|
function parseArgs() {
|
|
16
17
|
const args = process.argv.slice(2)
|
|
17
18
|
const options = {
|
|
18
|
-
mcpUrl:
|
|
19
|
-
lanternUrl: null,
|
|
19
|
+
mcpUrl: DEFAULT_MCP_URL,
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
for (let i = 0; i < args.length; i++) {
|
|
23
23
|
if (args[i] === '--mcp-url' && args[i + 1]) {
|
|
24
24
|
options.mcpUrl = args[i + 1]
|
|
25
25
|
i++
|
|
26
|
-
} else if (args[i] === '--lantern-url' && args[i + 1]) {
|
|
27
|
-
options.lanternUrl = args[i + 1]
|
|
28
|
-
i++
|
|
29
26
|
} else if (args[i] === '--help' || args[i] === '-h') {
|
|
30
27
|
console.log(`
|
|
31
28
|
Usage: lantern-connect [options]
|
|
32
29
|
|
|
33
30
|
Options:
|
|
34
31
|
--mcp-url <url> MCP server URL (default: https://mcp.onlantern.com/mcp)
|
|
35
|
-
--lantern-url <url> Lantern web URL (default: https://onlantern.com)
|
|
36
32
|
--help, -h Show this help message
|
|
37
33
|
`)
|
|
38
34
|
process.exit(0)
|
|
@@ -76,26 +72,7 @@ export async function main() {
|
|
|
76
72
|
process.exit(1)
|
|
77
73
|
}
|
|
78
74
|
|
|
79
|
-
// Step 2:
|
|
80
|
-
console.log(' 🔐 Authenticating with Lantern...')
|
|
81
|
-
|
|
82
|
-
let authResult
|
|
83
|
-
try {
|
|
84
|
-
authResult = await authenticate({
|
|
85
|
-
lanternUrl: options.lanternUrl,
|
|
86
|
-
mcpUrl: options.mcpUrl,
|
|
87
|
-
})
|
|
88
|
-
} catch (err) {
|
|
89
|
-
console.log('')
|
|
90
|
-
console.log(` ❌ Authentication failed: ${err.message}`)
|
|
91
|
-
console.log('')
|
|
92
|
-
process.exit(1)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
console.log(` ✓ Logged in as ${authResult.email}`)
|
|
96
|
-
console.log('')
|
|
97
|
-
|
|
98
|
-
// Step 3: Configure each detected tool
|
|
75
|
+
// Step 2: Configure each detected tool
|
|
99
76
|
console.log(' 📝 Configuring...')
|
|
100
77
|
console.log('')
|
|
101
78
|
|
|
@@ -109,7 +86,7 @@ export async function main() {
|
|
|
109
86
|
if (!configurator) continue
|
|
110
87
|
|
|
111
88
|
try {
|
|
112
|
-
const result = configurator(
|
|
89
|
+
const result = configurator(options.mcpUrl)
|
|
113
90
|
configured.push({ name: tool.name, path: result })
|
|
114
91
|
console.log(` ✓ ${tool.name}`)
|
|
115
92
|
} catch (err) {
|
|
@@ -120,20 +97,14 @@ export async function main() {
|
|
|
120
97
|
|
|
121
98
|
console.log('')
|
|
122
99
|
|
|
123
|
-
// Step
|
|
100
|
+
// Step 3: Summary
|
|
124
101
|
if (configured.length > 0) {
|
|
125
102
|
console.log(' 🎉 Done!')
|
|
126
103
|
console.log('')
|
|
127
104
|
console.log(' Next steps:')
|
|
128
105
|
console.log(' 1. Fully quit and reopen your AI tools (Cmd+Q on macOS)')
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (detected.claudeDesktop?.found) {
|
|
132
|
-
console.log(' 2. In Claude Desktop: Settings → Connectors → click "lantern" to authenticate')
|
|
133
|
-
console.log(' 3. Say "save to lantern" to export a conversation')
|
|
134
|
-
} else {
|
|
135
|
-
console.log(' 2. Say "save to lantern" to export a conversation')
|
|
136
|
-
}
|
|
106
|
+
console.log(' 2. Each tool will prompt you to authenticate on first use')
|
|
107
|
+
console.log(' 3. Say "save to lantern" to export a conversation')
|
|
137
108
|
console.log('')
|
|
138
109
|
}
|
|
139
110
|
|
package/src/auth.js
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { createServer } from 'http'
|
|
2
|
-
import { URL } from 'url'
|
|
3
|
-
import open from 'open'
|
|
4
|
-
|
|
5
|
-
const CALLBACK_PORT = 8765
|
|
6
|
-
const DEFAULT_LANTERN_URL = process.env.LANTERN_URL || 'https://onlantern.com'
|
|
7
|
-
const DEFAULT_MCP_URL = process.env.MCP_URL || 'https://mcp.onlantern.com/mcp'
|
|
8
|
-
|
|
9
|
-
function createSuccessHtml(email) {
|
|
10
|
-
return `
|
|
11
|
-
<!DOCTYPE html>
|
|
12
|
-
<html>
|
|
13
|
-
<head>
|
|
14
|
-
<meta charset="UTF-8">
|
|
15
|
-
<title>Lantern Connected</title>
|
|
16
|
-
<style>
|
|
17
|
-
body {
|
|
18
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
19
|
-
display: flex;
|
|
20
|
-
align-items: center;
|
|
21
|
-
justify-content: center;
|
|
22
|
-
min-height: 100vh;
|
|
23
|
-
margin: 0;
|
|
24
|
-
background: #0a0a0a;
|
|
25
|
-
color: #fafafa;
|
|
26
|
-
}
|
|
27
|
-
.container {
|
|
28
|
-
text-align: center;
|
|
29
|
-
padding: 2rem;
|
|
30
|
-
}
|
|
31
|
-
.icon {
|
|
32
|
-
font-size: 4rem;
|
|
33
|
-
margin-bottom: 1rem;
|
|
34
|
-
}
|
|
35
|
-
h1 {
|
|
36
|
-
font-size: 1.5rem;
|
|
37
|
-
margin-bottom: 0.5rem;
|
|
38
|
-
}
|
|
39
|
-
p {
|
|
40
|
-
color: #a1a1aa;
|
|
41
|
-
margin-bottom: 1.5rem;
|
|
42
|
-
}
|
|
43
|
-
.close-note {
|
|
44
|
-
font-size: 0.875rem;
|
|
45
|
-
color: #71717a;
|
|
46
|
-
}
|
|
47
|
-
</style>
|
|
48
|
-
</head>
|
|
49
|
-
<body>
|
|
50
|
-
<div class="container">
|
|
51
|
-
<div class="icon">✓</div>
|
|
52
|
-
<h1>Connected to Lantern</h1>
|
|
53
|
-
<p>Logged in as ${email}</p>
|
|
54
|
-
<p class="close-note">You can close this window and return to your terminal.</p>
|
|
55
|
-
</div>
|
|
56
|
-
</body>
|
|
57
|
-
</html>
|
|
58
|
-
`
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function createErrorHtml(message) {
|
|
62
|
-
return `
|
|
63
|
-
<!DOCTYPE html>
|
|
64
|
-
<html>
|
|
65
|
-
<head>
|
|
66
|
-
<meta charset="UTF-8">
|
|
67
|
-
<title>Lantern - Error</title>
|
|
68
|
-
<style>
|
|
69
|
-
body {
|
|
70
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
71
|
-
display: flex;
|
|
72
|
-
align-items: center;
|
|
73
|
-
justify-content: center;
|
|
74
|
-
min-height: 100vh;
|
|
75
|
-
margin: 0;
|
|
76
|
-
background: #0a0a0a;
|
|
77
|
-
color: #fafafa;
|
|
78
|
-
}
|
|
79
|
-
.container {
|
|
80
|
-
text-align: center;
|
|
81
|
-
padding: 2rem;
|
|
82
|
-
}
|
|
83
|
-
.icon {
|
|
84
|
-
font-size: 4rem;
|
|
85
|
-
margin-bottom: 1rem;
|
|
86
|
-
}
|
|
87
|
-
h1 {
|
|
88
|
-
font-size: 1.5rem;
|
|
89
|
-
margin-bottom: 0.5rem;
|
|
90
|
-
color: #ef4444;
|
|
91
|
-
}
|
|
92
|
-
p {
|
|
93
|
-
color: #a1a1aa;
|
|
94
|
-
}
|
|
95
|
-
</style>
|
|
96
|
-
</head>
|
|
97
|
-
<body>
|
|
98
|
-
<div class="container">
|
|
99
|
-
<div class="icon">✗</div>
|
|
100
|
-
<h1>Connection Failed</h1>
|
|
101
|
-
<p>${message}</p>
|
|
102
|
-
</div>
|
|
103
|
-
</body>
|
|
104
|
-
</html>
|
|
105
|
-
`
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export async function authenticate(options = {}) {
|
|
109
|
-
const lanternUrl = options.lanternUrl || DEFAULT_LANTERN_URL
|
|
110
|
-
const mcpUrlOverride = options.mcpUrl || DEFAULT_MCP_URL
|
|
111
|
-
|
|
112
|
-
return new Promise((resolve, reject) => {
|
|
113
|
-
const server = createServer((req, res) => {
|
|
114
|
-
const url = new URL(req.url, `http://localhost:${CALLBACK_PORT}`)
|
|
115
|
-
|
|
116
|
-
if (url.pathname === '/callback') {
|
|
117
|
-
const token = url.searchParams.get('token')
|
|
118
|
-
const mcpUrl = url.searchParams.get('mcp_url') || mcpUrlOverride
|
|
119
|
-
const email = url.searchParams.get('email')
|
|
120
|
-
const error = url.searchParams.get('error')
|
|
121
|
-
|
|
122
|
-
if (error) {
|
|
123
|
-
res.writeHead(200, { 'Content-Type': 'text/html' })
|
|
124
|
-
res.end(createErrorHtml(error))
|
|
125
|
-
server.close()
|
|
126
|
-
reject(new Error(error))
|
|
127
|
-
return
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (!token) {
|
|
131
|
-
res.writeHead(200, { 'Content-Type': 'text/html' })
|
|
132
|
-
res.end(createErrorHtml('Missing token'))
|
|
133
|
-
server.close()
|
|
134
|
-
reject(new Error('Missing token in callback'))
|
|
135
|
-
return
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
res.writeHead(200, { 'Content-Type': 'text/html' })
|
|
139
|
-
res.end(createSuccessHtml(email || 'unknown'))
|
|
140
|
-
|
|
141
|
-
server.close()
|
|
142
|
-
resolve({ token, mcpUrl, email })
|
|
143
|
-
} else {
|
|
144
|
-
res.writeHead(404)
|
|
145
|
-
res.end('Not found')
|
|
146
|
-
}
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
server.listen(CALLBACK_PORT, '127.0.0.1', () => {
|
|
150
|
-
const authUrl = new URL(`${lanternUrl}/auth/cli`)
|
|
151
|
-
authUrl.searchParams.set('callback_port', CALLBACK_PORT)
|
|
152
|
-
authUrl.searchParams.set('mcp_url', mcpUrlOverride)
|
|
153
|
-
console.log(` Opening browser...`)
|
|
154
|
-
open(authUrl.toString())
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
server.on('error', (err) => {
|
|
158
|
-
if (err.code === 'EADDRINUSE') {
|
|
159
|
-
reject(new Error(`Port ${CALLBACK_PORT} is already in use. Please close any other lantern-connect instances.`))
|
|
160
|
-
} else {
|
|
161
|
-
reject(err)
|
|
162
|
-
}
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
// Timeout after 5 minutes
|
|
166
|
-
setTimeout(() => {
|
|
167
|
-
server.close()
|
|
168
|
-
reject(new Error('Authentication timed out. Please try again.'))
|
|
169
|
-
}, 5 * 60 * 1000)
|
|
170
|
-
})
|
|
171
|
-
}
|