install app
This commit is contained in:
parent
3fea8a5834
commit
785a1dfe15
5 changed files with 403 additions and 3 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -16,6 +16,10 @@ build/
|
||||||
.env.test.local
|
.env.test.local
|
||||||
.env.production.local
|
.env.production.local
|
||||||
|
|
||||||
|
# TickTick MCP configuration (contains sensitive auth data)
|
||||||
|
.ticktick-mcp/
|
||||||
|
config.json
|
||||||
|
|
||||||
# IDE files
|
# IDE files
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
|
|
|
||||||
162
MCP-INSTALL.md
Normal file
162
MCP-INSTALL.md
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
# TickTick MCP Server - Claude Code CLI Integration
|
||||||
|
|
||||||
|
## 🚀 Quick Install
|
||||||
|
|
||||||
|
### Method 1: Git Clone Installation (Recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone https://github.com/marketing-shibata50/ticktick-mcp.git
|
||||||
|
cd ticktick-mcp/ticktick-mcp-server
|
||||||
|
|
||||||
|
# Install dependencies and build
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Run automatic setup
|
||||||
|
node install-mcp.js
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
- ✅ Clone the complete project with all dependencies
|
||||||
|
- ✅ Build from source for maximum compatibility
|
||||||
|
- ✅ Run interactive setup wizard
|
||||||
|
- ✅ Configure `.mcp.json` and Claude Code CLI settings
|
||||||
|
|
||||||
|
### Method 2: NPM Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install and configure TickTick MCP for Claude Code CLI
|
||||||
|
npx ticktick-mcp-install
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: NPM installation may have dependency issues. Git clone method is more reliable.
|
||||||
|
|
||||||
|
### Method 3: Manual Installation
|
||||||
|
|
||||||
|
1. **Create `.mcp.json` in your project root:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"ticktick": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["ticktick-mcp-server-interactive"]
|
||||||
|
},
|
||||||
|
"ticktick-demo": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["ticktick-mcp-server-interactive", "--demo"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Update `.claude/settings.local.json`:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"enableAllProjectMcpServers": true,
|
||||||
|
"enabledMcpjsonServers": ["ticktick", "ticktick-demo"],
|
||||||
|
"permissions": {
|
||||||
|
"allow": ["mcp__ticktick__*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 Usage
|
||||||
|
|
||||||
|
### Start Claude Code CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd your-project-directory
|
||||||
|
claude
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test TickTick Integration
|
||||||
|
|
||||||
|
```
|
||||||
|
TickTick MCPサーバーが利用可能か確認して
|
||||||
|
```
|
||||||
|
|
||||||
|
### TickTick Commands
|
||||||
|
|
||||||
|
```
|
||||||
|
今日のタスクを表示して
|
||||||
|
新しいタスク「コードレビュー」を追加して
|
||||||
|
プロジェクト一覧を見せて
|
||||||
|
期限切れのタスクを確認して
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Configuration Options
|
||||||
|
|
||||||
|
### 1. NPM Package (Production)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ticktick": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["ticktick-mcp-server-interactive"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Demo Mode (No Authentication)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ticktick-demo": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["ticktick-mcp-server-interactive", "--demo"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Local Development
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ticktick-local": {
|
||||||
|
"command": "node",
|
||||||
|
"args": ["/path/to/ticktick-mcp-server/dist/index.js"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ First-Time Setup
|
||||||
|
|
||||||
|
### For Real TickTick Integration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Setup authentication (only needed once)
|
||||||
|
npx ticktick-mcp-server-interactive --setup
|
||||||
|
```
|
||||||
|
|
||||||
|
### For Demo/Testing
|
||||||
|
|
||||||
|
Use the `ticktick-demo` configuration - no setup required!
|
||||||
|
|
||||||
|
## 📋 Troubleshooting
|
||||||
|
|
||||||
|
### MCP Server Not Recognized
|
||||||
|
|
||||||
|
1. Check `.mcp.json` syntax
|
||||||
|
2. Restart Claude Code CLI
|
||||||
|
3. Verify settings in `.claude/settings.local.json`
|
||||||
|
|
||||||
|
### Authentication Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Re-run setup
|
||||||
|
npx ticktick-mcp-server-interactive --setup
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test NPM package
|
||||||
|
npx ticktick-mcp-server-interactive --version
|
||||||
|
|
||||||
|
# Test demo mode
|
||||||
|
npx ticktick-mcp-server-interactive --demo
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎉 Success!
|
||||||
|
|
||||||
|
Once installed, you can manage your TickTick tasks directly from Claude Code CLI using natural language!
|
||||||
224
install-mcp.js
Normal file
224
install-mcp.js
Normal file
|
|
@ -0,0 +1,224 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import readline from 'readline';
|
||||||
|
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout
|
||||||
|
});
|
||||||
|
|
||||||
|
function question(prompt) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
rl.question(prompt, (answer) => {
|
||||||
|
resolve(answer.trim());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function findProjectRoot() {
|
||||||
|
let currentDir = process.cwd();
|
||||||
|
|
||||||
|
while (currentDir !== path.dirname(currentDir)) {
|
||||||
|
// Check for common project indicators
|
||||||
|
const indicators = ['.git', 'package.json', '.claude', 'pyproject.toml', 'Cargo.toml'];
|
||||||
|
const hasIndicator = indicators.some(indicator =>
|
||||||
|
fs.existsSync(path.join(currentDir, indicator))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasIndicator) {
|
||||||
|
return currentDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDir = path.dirname(currentDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return process.cwd(); // Fallback to current directory
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
console.log('🚀 TickTick MCP Server Installation Tool');
|
||||||
|
console.log('=====================================\n');
|
||||||
|
|
||||||
|
const projectRoot = findProjectRoot();
|
||||||
|
console.log(`📁 Project root detected: ${projectRoot}\n`);
|
||||||
|
|
||||||
|
const mcpJsonPath = path.join(projectRoot, '.mcp.json');
|
||||||
|
let mcpConfig = {};
|
||||||
|
|
||||||
|
// Load existing .mcp.json if it exists
|
||||||
|
if (fs.existsSync(mcpJsonPath)) {
|
||||||
|
try {
|
||||||
|
const content = fs.readFileSync(mcpJsonPath, 'utf8');
|
||||||
|
mcpConfig = JSON.parse(content);
|
||||||
|
console.log('✅ Found existing .mcp.json file');
|
||||||
|
} catch (error) {
|
||||||
|
console.log('⚠️ Found .mcp.json but could not parse it. Creating backup...');
|
||||||
|
fs.copyFileSync(mcpJsonPath, `${mcpJsonPath}.backup`);
|
||||||
|
console.log(` Backup saved as: .mcp.json.backup`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('📝 Creating new .mcp.json file');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mcpConfig.mcpServers) {
|
||||||
|
mcpConfig.mcpServers = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n🔧 TickTick MCP Server Configuration Options:');
|
||||||
|
console.log('1. NPM Package (recommended for end users)');
|
||||||
|
console.log('2. Demo Mode (no authentication required)');
|
||||||
|
console.log('3. Local Development (for developers)');
|
||||||
|
console.log('4. All of the above');
|
||||||
|
|
||||||
|
const choice = await question('\nSelect option (1-4): ');
|
||||||
|
|
||||||
|
const configs = {
|
||||||
|
npm: {
|
||||||
|
name: 'ticktick',
|
||||||
|
config: {
|
||||||
|
command: 'npx',
|
||||||
|
args: ['ticktick-mcp-server-interactive']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
demo: {
|
||||||
|
name: 'ticktick-demo',
|
||||||
|
config: {
|
||||||
|
command: 'npx',
|
||||||
|
args: ['ticktick-mcp-server-interactive', '--demo']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
local: {
|
||||||
|
name: 'ticktick-local',
|
||||||
|
config: {
|
||||||
|
command: 'node',
|
||||||
|
args: [path.join(projectRoot, 'ticktick-mcp-server/dist/index.js')]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (choice) {
|
||||||
|
case '1':
|
||||||
|
mcpConfig.mcpServers[configs.npm.name] = configs.npm.config;
|
||||||
|
console.log('✅ Added NPM package configuration');
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
mcpConfig.mcpServers[configs.demo.name] = configs.demo.config;
|
||||||
|
console.log('✅ Added demo mode configuration');
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
const localPath = await question(`Local path (default: ${configs.local.config.args[0]}): `);
|
||||||
|
if (localPath) {
|
||||||
|
configs.local.config.args[0] = localPath;
|
||||||
|
}
|
||||||
|
mcpConfig.mcpServers[configs.local.name] = configs.local.config;
|
||||||
|
console.log('✅ Added local development configuration');
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
mcpConfig.mcpServers[configs.npm.name] = configs.npm.config;
|
||||||
|
mcpConfig.mcpServers[configs.demo.name] = configs.demo.config;
|
||||||
|
mcpConfig.mcpServers[configs.local.name] = configs.local.config;
|
||||||
|
console.log('✅ Added all configurations');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log('❌ Invalid choice. Exiting...');
|
||||||
|
rl.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write .mcp.json
|
||||||
|
try {
|
||||||
|
fs.writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
||||||
|
console.log(`\n💾 Successfully updated: ${mcpJsonPath}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`❌ Failed to write .mcp.json: ${error.message}`);
|
||||||
|
rl.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check and update Claude settings
|
||||||
|
const claudeDir = path.join(projectRoot, '.claude');
|
||||||
|
const settingsPath = path.join(claudeDir, 'settings.local.json');
|
||||||
|
|
||||||
|
if (fs.existsSync(settingsPath)) {
|
||||||
|
console.log('\n🔍 Checking Claude Code settings...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const settingsContent = fs.readFileSync(settingsPath, 'utf8');
|
||||||
|
const settings = JSON.parse(settingsContent);
|
||||||
|
|
||||||
|
let updated = false;
|
||||||
|
|
||||||
|
// Enable all project MCP servers
|
||||||
|
if (!settings.enableAllProjectMcpServers) {
|
||||||
|
settings.enableAllProjectMcpServers = true;
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add enabled servers
|
||||||
|
if (!settings.enabledMcpjsonServers) {
|
||||||
|
settings.enabledMcpjsonServers = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const newServers = Object.keys(mcpConfig.mcpServers);
|
||||||
|
newServers.forEach(server => {
|
||||||
|
if (!settings.enabledMcpjsonServers.includes(server)) {
|
||||||
|
settings.enabledMcpjsonServers.push(server);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add permissions
|
||||||
|
if (!settings.permissions) {
|
||||||
|
settings.permissions = { allow: [], deny: [], ask: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!settings.permissions.allow.includes('mcp__ticktick__*')) {
|
||||||
|
settings.permissions.allow.push('mcp__ticktick__*');
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updated) {
|
||||||
|
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
||||||
|
console.log('✅ Updated Claude Code settings');
|
||||||
|
} else {
|
||||||
|
console.log('✅ Claude Code settings are already configured');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.log('⚠️ Could not update Claude Code settings automatically');
|
||||||
|
console.log(' Please add the following to your .claude/settings.local.json:');
|
||||||
|
console.log(' "enableAllProjectMcpServers": true,');
|
||||||
|
console.log(' "enabledMcpjsonServers": ' + JSON.stringify(Object.keys(mcpConfig.mcpServers)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('\n📋 Claude Code settings not found. Manual setup required:');
|
||||||
|
console.log(' Create .claude/settings.local.json with:');
|
||||||
|
console.log(' {');
|
||||||
|
console.log(' "enableAllProjectMcpServers": true,');
|
||||||
|
console.log(' "enabledMcpjsonServers": ' + JSON.stringify(Object.keys(mcpConfig.mcpServers)));
|
||||||
|
console.log(' }');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n🎉 Installation Complete!');
|
||||||
|
console.log('========================');
|
||||||
|
console.log('\nNext steps:');
|
||||||
|
console.log('1. Start Claude Code CLI from this directory:');
|
||||||
|
console.log(` cd ${projectRoot}`);
|
||||||
|
console.log(' claude');
|
||||||
|
console.log('\n2. Test TickTick integration:');
|
||||||
|
console.log(' "TickTick MCPサーバーが利用可能か確認して"');
|
||||||
|
console.log('\n3. For first-time setup (if using real TickTick):');
|
||||||
|
console.log(' npx ticktick-mcp-server-interactive --setup');
|
||||||
|
console.log('\n4. To test with demo data:');
|
||||||
|
console.log(' Use the ticktick-demo server configuration');
|
||||||
|
|
||||||
|
rl.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch(error => {
|
||||||
|
console.error('❌ Installation failed:', error);
|
||||||
|
rl.close();
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
10
package.json
10
package.json
|
|
@ -1,10 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "@marketing-shibata50/ticktick-mcp-server",
|
"name": "ticktick-mcp-server-interactive",
|
||||||
"version": "1.0.0",
|
"version": "1.2.0",
|
||||||
"description": "Model Context Protocol server for TickTick task management integration with AI assistants like Claude",
|
"description": "Model Context Protocol server for TickTick task management integration with AI assistants like Claude",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"ticktick-mcp-server": "dist/index.js"
|
"ticktick-mcp-server-interactive": "dist/index.js",
|
||||||
|
"ticktick-mcp-install": "install-mcp.js"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
@ -13,6 +14,7 @@
|
||||||
"start": "node dist/index.js",
|
"start": "node dist/index.js",
|
||||||
"demo": "node dist/index.js --demo",
|
"demo": "node dist/index.js --demo",
|
||||||
"setup": "node dist/index.js --setup",
|
"setup": "node dist/index.js --setup",
|
||||||
|
"install-mcp": "node install-mcp.js",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"lint": "eslint src/**/*.ts",
|
"lint": "eslint src/**/*.ts",
|
||||||
"format": "prettier --write src/**/*.ts",
|
"format": "prettier --write src/**/*.ts",
|
||||||
|
|
@ -44,6 +46,8 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"files": [
|
"files": [
|
||||||
"dist/",
|
"dist/",
|
||||||
|
"install-mcp.js",
|
||||||
|
"MCP-INSTALL.md",
|
||||||
"README.md",
|
"README.md",
|
||||||
"AUTHENTICATION.md",
|
"AUTHENTICATION.md",
|
||||||
"TESTING.md",
|
"TESTING.md",
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,12 @@ import { ConfigManager } from './config/config-manager.js';
|
||||||
import { InteractiveSetup } from './setup/interactive-setup.js';
|
import { InteractiveSetup } from './setup/interactive-setup.js';
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
// Check for version command
|
||||||
|
if (process.argv.includes('--version') || process.argv.includes('-v')) {
|
||||||
|
console.log('1.0.0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for setup command
|
// Check for setup command
|
||||||
if (process.argv.includes('--setup') || process.argv.includes('--configure')) {
|
if (process.argv.includes('--setup') || process.argv.includes('--configure')) {
|
||||||
console.error('🔧 TickTick MCP Server セットアップを開始します...\n');
|
console.error('🔧 TickTick MCP Server セットアップを開始します...\n');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue