install app

This commit is contained in:
柴田貴司 2025-09-22 21:54:08 +09:00
parent 3fea8a5834
commit 785a1dfe15
5 changed files with 403 additions and 3 deletions

4
.gitignore vendored
View file

@ -16,6 +16,10 @@ build/
.env.test.local
.env.production.local
# TickTick MCP configuration (contains sensitive auth data)
.ticktick-mcp/
config.json
# IDE files
.vscode/
.idea/

162
MCP-INSTALL.md Normal file
View 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
View 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);
});

View file

@ -1,10 +1,11 @@
{
"name": "@marketing-shibata50/ticktick-mcp-server",
"version": "1.0.0",
"name": "ticktick-mcp-server-interactive",
"version": "1.2.0",
"description": "Model Context Protocol server for TickTick task management integration with AI assistants like Claude",
"main": "dist/index.js",
"bin": {
"ticktick-mcp-server": "dist/index.js"
"ticktick-mcp-server-interactive": "dist/index.js",
"ticktick-mcp-install": "install-mcp.js"
},
"type": "module",
"scripts": {
@ -13,6 +14,7 @@
"start": "node dist/index.js",
"demo": "node dist/index.js --demo",
"setup": "node dist/index.js --setup",
"install-mcp": "node install-mcp.js",
"test": "jest",
"lint": "eslint src/**/*.ts",
"format": "prettier --write src/**/*.ts",
@ -44,6 +46,8 @@
"license": "MIT",
"files": [
"dist/",
"install-mcp.js",
"MCP-INSTALL.md",
"README.md",
"AUTHENTICATION.md",
"TESTING.md",

View file

@ -6,6 +6,12 @@ import { ConfigManager } from './config/config-manager.js';
import { InteractiveSetup } from './setup/interactive-setup.js';
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
if (process.argv.includes('--setup') || process.argv.includes('--configure')) {
console.error('🔧 TickTick MCP Server セットアップを開始します...\n');