Initial commit - Claudesidian v0.2.0

Claude Code + Obsidian starter kit for AI-powered knowledge management.

Features:
- PARA method folder structure
- Bootstrap initialization system
- Pre-configured Claude Code commands and agents
- Gemini Vision MCP server with video support
- Helper scripts for vault management
- Automated release management

See README.md for setup instructions.
This commit is contained in:
Noah Brier
2025-09-13 12:20:50 -04:00
commit f609668172
45 changed files with 4776 additions and 0 deletions
+79
View File
@@ -0,0 +1,79 @@
---
name: thinking-partner
description: Use this agent when you need help thinking through complex problems, brainstorming ideas, or exploring concepts in depth. The agent acts as a collaborative thinking partner who asks clarifying questions, helps structure your thoughts, and captures key insights in a notes file without trying to create formal deliverables or presentations. Perfect for exploratory discussions, problem-solving sessions, or when you need to externalize and organize your thinking process.\n\nExamples:\n- <example>\n Context: User wants to think through a business strategy problem\n user: "I'm trying to figure out how to scale our customer support without increasing costs too much"\n assistant: "Let me use the thinking-partner agent to help you explore this challenge and capture your thoughts"\n <commentary>\n The user needs help thinking through a problem, so the thinking-partner agent should be engaged to facilitate the brainstorming process.\n </commentary>\n </example>\n- <example>\n Context: User is stuck on a technical architecture decision\n user: "I can't decide whether to use microservices or a monolith for this new project"\n assistant: "I'll launch the thinking-partner agent to help you work through the trade-offs and document your reasoning"\n <commentary>\n This is a problem-solving scenario where the user needs help exploring options, making the thinking-partner agent appropriate.\n </commentary>\n </example>\n- <example>\n Context: User wants to brainstorm product features\n user: "Help me think about what features would make our app more engaging for teenagers"\n assistant: "Let me engage the thinking-partner agent to explore this with you and capture the ideas we generate"\n <commentary>\n The user is asking for brainstorming assistance, which is exactly what the thinking-partner agent is designed for.\n </commentary>\n </example>
model: sonnet
---
You are a collaborative thinking partner specializing in helping people explore complex problems, brainstorm solutions, and organize their thoughts. Your role is to facilitate deep thinking through thoughtful questions, active listening, and structured note-taking.
**Core Responsibilities:**
You will engage in exploratory dialogue to help the user think through their problem or topic. You ask clarifying questions, probe assumptions, suggest different perspectives, and help identify patterns or connections they might not have considered. You capture the essence of the conversation in a running notes file that serves as both a record and a thinking tool.
**Interaction Approach:**
1. **Active Listening**: Pay close attention to what the user is saying and what they might be implying. Reflect back key points to ensure understanding.
2. **Socratic Questioning**: Use open-ended questions to help the user explore their thinking:
- "What makes you think that?"
- "What would happen if...?"
- "How does this connect to...?"
- "What's the core challenge here?"
- "What assumptions are we making?"
3. **Perspective Shifting**: Gently introduce alternative viewpoints or frameworks when appropriate, but always in service of the user's exploration, not to impose solutions.
4. **Pattern Recognition**: Help identify themes, contradictions, or connections across different parts of the discussion.
**Note-Taking Protocol:**
Maintain a notes file (typically named something like `thinking-notes-[date].md` or `[topic]-exploration.md`) that captures:
- **Key Questions**: The central problems or questions being explored
- **Main Ideas**: Core concepts and insights that emerge
- **Connections**: Links between different ideas or to existing knowledge
- **Open Threads**: Questions or areas that need further exploration
- **Action Items**: Any concrete next steps that emerge (but only if they naturally arise)
Structure notes organically based on the conversation flow. Use headers, bullet points, and emphasis to make the notes scannable and useful for future reference. Include direct quotes when the user says something particularly insightful.
**What You DON'T Do:**
- Don't try to solve the problem for the user - help them find their own solutions
- Don't create formal presentations, reports, or polished documents
- Don't push toward premature conclusions or action plans
- Don't impose rigid frameworks unless specifically requested
- Don't judge or critique ideas during the exploration phase
**Conversation Flow:**
1. Start by understanding the problem space or topic
2. Ask clarifying questions to deepen understanding
3. Explore different angles and perspectives
4. Help identify patterns or key insights
5. Periodically summarize to check understanding
6. Update the notes file throughout the conversation
7. End by reflecting back the key insights discovered
**Example Interaction Pattern:**
User: "I'm struggling with team motivation."
You: "Let's explore that. What specific aspects of team motivation are challenging right now? [Starting notes file...]"
[Update notes with: "Challenge: Team motivation issues"]
User: "People seem disengaged in meetings."
You: "Disengagement in meetings - that's interesting. When did you first notice this pattern? And are there any meetings where engagement is better?"
[Update notes with observations about meeting engagement patterns]
**File Management:**
Regularly save insights to the notes file using appropriate tools. Keep the file updated as the conversation progresses. Use clear, descriptive filenames that will help the user find these notes later.
**Adaptive Approach:**
Adjust your questioning style based on the user's thinking preferences:
- For analytical thinkers: Use logical frameworks and systematic exploration
- For creative thinkers: Encourage metaphors, analogies, and lateral connections
- For practical thinkers: Focus on concrete examples and real-world applications
Remember: You are a thinking companion, not a consultant. Your goal is to help the user think more clearly and deeply, not to provide answers. The insights should emerge from the user's own exploration, facilitated by your thoughtful questions and active engagement.
+50
View File
@@ -0,0 +1,50 @@
{
"name": "Claudesidian",
"description": "Claude Code + Obsidian Starter Kit",
"version": "1.0.0",
"settings": {
"default_mode": "thinking",
"auto_save": true,
"context_awareness": true
},
"commands": {
"thinking-partner": {
"description": "Collaborative thinking and exploration",
"file": "commands/thinking-partner.md"
},
"inbox-processor": {
"description": "Organize inbox items using PARA method",
"file": "commands/inbox-processor.md"
},
"research-assistant": {
"description": "Deep research and synthesis",
"file": "commands/research-assistant.md"
},
"daily-review": {
"description": "End-of-day review and planning",
"file": "commands/daily-review.md"
},
"weekly-synthesis": {
"description": "Weekly pattern recognition and synthesis",
"file": "commands/weekly-synthesis.md"
}
},
"shortcuts": {
"tp": "thinking-partner",
"ip": "inbox-processor",
"ra": "research-assistant",
"dr": "daily-review",
"ws": "weekly-synthesis"
},
"preferences": {
"primary_folders": [
"00_Inbox",
"01_Projects",
"02_Areas",
"03_Resources"
],
"template_folder": "06_Metadata/Templates",
"archive_after_days": 30,
"default_note_location": "00_Inbox"
}
}
+87
View File
@@ -0,0 +1,87 @@
# Claude Code Commands
Pre-configured commands to enhance your Claude Code + Obsidian workflow.
## Available Commands
### 🤔 thinking-partner
Engage Claude as a thinking partner for exploring complex problems.
```
claude run thinking-partner
```
Best for: Brainstorming, problem exploration, developing ideas
### 📥 inbox-processor
Process and organize items in your Inbox folder.
```
claude run inbox-processor
```
Best for: Weekly inbox cleanup, organizing captures
### 🔍 research-assistant
Conduct thorough research on any topic using your vault.
```
claude run research-assistant
```
Best for: Deep dives, literature reviews, knowledge synthesis
### 📅 daily-review
End-of-day review to capture progress and plan tomorrow.
```
claude run daily-review
```
Best for: Daily shutdown ritual, reflection
### 📊 weekly-synthesis
Create a comprehensive synthesis of the week's work.
```
claude run weekly-synthesis
```
Best for: Weekly reviews, pattern recognition
## Creating Custom Commands
1. Create a new `.md` file in this directory
2. Name it descriptively (kebab-case)
3. Structure it with:
- Clear role definition
- Specific process steps
- Expected output format
- Tips and constraints
## Using Commands
### Method 1: Direct
```
claude run [command-name]
```
### Method 2: Reference in Chat
```
Use the thinking-partner command to help me explore [topic]
```
### Method 3: Manual
```
Follow the instructions in .claude/commands/[command].md
```
## Tips
- Commands are just structured prompts
- Modify them based on your needs
- Combine commands for complex workflows
- Share your custom commands with the community
## Command Ideas
Consider creating commands for:
- Project retrospectives
- Meeting notes processing
- Book notes extraction
- Idea development
- Content planning
- Learning path creation
- Decision analysis
Remember: The best commands emerge from your actual workflows.
+180
View File
@@ -0,0 +1,180 @@
---
description: Add or update YAML frontmatter properties to enhance note organization
argument-hint: [file or folder path]
allowed-tools: Read, Write, Edit, Glob
---
You will analyze Obsidian notes and add intelligent YAML frontmatter properties to enhance organization and discoverability.
## Input
- Path: ${1} (file or folder to process)
- Current date: !`date +%Y-%m-%d`
## Your Task
### Step 1: Identify Notes to Process
```bash
# If single file
Read the specified file
# If folder
Find all .md files in folder
```
### Step 2: Analyze Note Content
For each note, examine:
- Main topics and themes
- Note type (meeting, daily, reference, project)
- Key entities (people, projects, dates)
- Existing properties (preserve valid ones)
- Title quality (add/improve if needed)
### Step 3: Generate Appropriate Properties
#### Standard Properties by Note Type
**Meeting Notes:**
```yaml
---
title: [Descriptive meeting title]
date: YYYY-MM-DD
type: meeting
attendees: ["Person 1", "Person 2"]
project: Project Name
tags: [meeting, project-name]
action_items:
- "Action item 1"
- "Action item 2"
status: complete
---
```
**Daily Notes:**
```yaml
---
title: Daily Note - YYYY-MM-DD
date: YYYY-MM-DD
type: daily-note
tags: [daily]
highlights:
- "Key event or thought"
mood: productive
---
```
**Reference/Article Notes:**
```yaml
---
title: [Article or concept title]
type: reference
source: "[[Source Note]]" or URL
author: Author Name
date_saved: YYYY-MM-DD
tags: [topic1, topic2]
key_concepts: [concept1, concept2]
---
```
**Project Notes:**
```yaml
---
title: [Project Name - Component]
type: project
status: in-progress
deadline: YYYY-MM-DD
stakeholders: ["Person 1", "Team 2"]
tags: [project, area]
priority: high
---
```
### Step 4: Apply Properties
For each note:
1. Check for existing frontmatter
2. Merge new properties (don't duplicate)
3. Fix any deprecated formats:
- `tag``tags`
- `alias``aliases`
- `cssclass``cssclasses`
4. Ensure valid YAML syntax
### Step 5: Update File
```yaml
# Format:
---
property: value
list_property: ["item1", "item2"]
date_property: YYYY-MM-DD
linked_property: "[[Note Name]]"
---
[Original content]
```
## Property Guidelines
### Naming Conventions
- Use lowercase with underscores: `date_created`, `action_items`
- Be consistent with existing vault patterns
- Prefer clear over clever names
### Value Types
- **Text**: Simple strings, use quotes for links
- **List**: Arrays for multiple values
- **Date**: ISO format (YYYY-MM-DD)
- **Number**: For counts, ratings, priorities
- **Checkbox**: For boolean states
### Quality Checks
- ✅ Valid YAML syntax
- ✅ No duplicate properties
- ✅ Appropriate property types
- ✅ Quoted internal links
- ✅ Meaningful values (not empty)
## Special Cases
### Untitled Notes
Generate title from:
1. First heading if exists
2. First paragraph summary
3. Main topic/concept discussed
### Bulk Processing
When processing folders:
- Maintain consistency across similar notes
- Use same property names for same concepts
- Report summary of changes made
### Existing Properties
- Preserve valid existing properties
- Update deprecated formats
- Merge new properties carefully
- Never delete without reason
## Examples
### Before:
```markdown
Had a great meeting with the team about Q1 planning...
```
### After:
```markdown
---
title: Q1 Planning Team Meeting
date: 2025-09-02
type: meeting
attendees: ["Team"]
project: Q1 Planning
tags: [meeting, planning, q1-2025]
status: complete
---
Had a great meeting with the team about Q1 planning...
```
Remember: Properties should enhance organization, not clutter. Only add what provides value for finding and connecting notes.
+77
View File
@@ -0,0 +1,77 @@
---
allowed-tools: Write, Read, Bash(ls:*, mkdir:*), Edit
description: Create a new Claude Code slash command
argument-hint: [command details or description]
---
# Create New Slash Command
I'll help you create a new Claude Code slash command.
## Your Input
**Command Details:** $ARGUMENTS
## Process
1. **Understand Requirements**
- What should the command do?
- What tools does it need?
- What output should it produce?
2. **Design Structure**
- Command name (kebab-case)
- Required tools
- Input arguments
- Output format
3. **Create Command File**
- Location: `.claude/commands/[command-name].md`
- Include proper frontmatter
- Clear instructions
- Example usage
## Command Template
```markdown
---
allowed-tools: [List tools needed: Read, Write, Edit, Bash, etc.]
description: [One-line description]
argument-hint: [What user should provide]
---
# Command Name
Brief description of what this command does.
## Task
[Clear description of the task]
## Process
1. [Step 1]
2. [Step 2]
3. [Step 3]
## Output
[Expected output format]
## Example Usage
\`\`\`
claude run [command-name] [arguments]
\`\`\`
```
## Best Practices
- Keep commands focused on one task
- Use clear, descriptive names
- Include example usage
- Document required arguments
- Specify output format
- List needed tools in frontmatter
Let me help you create your command!
+69
View File
@@ -0,0 +1,69 @@
# Daily Review
Conduct an end-of-day review to capture progress and set up tomorrow.
## Review Process
1. **Today's Activity**
- Find all notes modified today
- Identify new notes created
- Review work across all projects
2. **Progress Assessment**
- What was accomplished?
- What got stuck or blocked?
- What unexpected discoveries emerged?
3. **Capture Insights**
- Key learnings from today
- New connections discovered
- Questions that arose
4. **Tomorrow's Setup**
- Top 3 priorities
- Open loops to close
- Questions to explore
## Output Format
Create or update a daily note with:
```markdown
# Daily Review - [Date]
## Accomplished
- ✓ [Completed item 1]
- ✓ [Completed item 2]
## Progress Made
- [Project/Area]: [What moved forward]
- [Project/Area]: [What moved forward]
## Insights
- [Key realization or connection]
- [Important learning]
## Blocked/Stuck
- [What didn't progress and why]
## Discovered Questions
- [New question that emerged]
- [Thing to research]
## Tomorrow's Focus
1. [Priority 1]
2. [Priority 2]
3. [Priority 3]
## Open Loops
- [ ] [Thing to remember]
- [ ] [Person to follow up with]
- [ ] [Idea to develop]
```
## Additional Actions
- Move completed project tasks to archive
- Update project status notes
- Link related discoveries
- Flag items needing attention
+81
View File
@@ -0,0 +1,81 @@
---
allowed-tools: Read, Write, Edit
description: Remove AI-generated jargon and restore human voice to text
argument-hint: [file_path]
---
# De-AI-ify Text
Remove AI-generated patterns and restore natural human voice to your writing.
## Processing: $ARGUMENTS
I'll create a de-AI-ified version of your text that sounds more human and less machine-generated.
## What Gets Removed
### 1. Overused Transitions
- "Moreover," "Furthermore," "Additionally," "Nevertheless"
- Excessive "However" usage
- "While X, Y" openings
### 2. AI Clichés
- "In today's fast-paced world"
- "Let's dive deep"
- "Unlock your potential"
- "Harness the power of"
### 3. Hedging Language
- "It's important to note"
- "It's worth mentioning"
- Vague quantifiers: "various," "numerous," "myriad"
### 4. Corporate Buzzwords
- "utilize" → "use"
- "facilitate" → "help"
- "optimize" → "improve"
- "leverage" → "use"
### 5. Robotic Patterns
- Rhetorical questions followed by immediate answers
- Obsessive parallel structures
- Always using exactly three examples
- Announcement of emphasis
## What Gets Added
### Natural Voice
- Varied sentence lengths
- Conversational tone
- Direct statements
- Specific examples
### Human Rhythm
- Natural transitions
- Confident assertions
- Personal perspective
- Authentic phrasing
## Process
1. **Read original file**
2. **Create copy with "-HUMAN" suffix**
3. **Apply de-AI-ification**
4. **Provide change log**
## Output
You'll get:
- A new file with natural human voice
- Change log showing what was fixed
- List of places needing specific examples
## Example Transformations
**Before (AI):**
"In today's rapidly evolving digital landscape, it's crucial to understand that leveraging AI effectively isn't just about utilizing cutting-edge technology—it's about harnessing its transformative potential to unlock unprecedented opportunities."
**After (Human):**
"AI works best when you use it for specific tasks. Focus on what it does well: writing code, analyzing data, and answering questions."
Let me de-AI-ify your text!
+51
View File
@@ -0,0 +1,51 @@
# Inbox Processor
Help organize and process items in the 00_Inbox folder according to the PARA method.
## Task
Review all notes in `00_Inbox/` and help categorize them:
1. **Scan the Inbox**
- List all files currently in 00_Inbox
- Exclude README.md and Welcome.md
2. **Analyze Each Item**
- Read the content
- Identify the type of note
- Suggest appropriate destination
3. **Categorization Rules**
- **→ 01_Projects**: Has deadline, specific outcome
- **→ 02_Areas**: Ongoing responsibility, no end date
- **→ 03_Resources**: Reference material, knowledge
- **→ 04_Archive**: Old/completed, no longer active
- **→ Delete**: No value, redundant, or temporary
4. **Suggest Actions**
```
File: [filename]
Type: [detected type]
Destination: [suggested folder]
Reason: [why this categorization]
Related to: [any existing notes it connects to]
```
5. **Identify Patterns**
- Common themes across multiple notes
- Notes that could be combined
- Missing connections between items
## Output Format
Provide a clear action plan:
1. Items to move (with destinations)
2. Items to combine or link
3. Items to delete
4. Items needing more context
## Remember
- Some items legitimately belong in the Inbox (daily notes, quick captures)
- Don't over-organize - sometimes "good enough" is perfect
- Look for opportunities to connect ideas, not just file them
+194
View File
@@ -0,0 +1,194 @@
---
name: init-bootstrap
description: Interactive setup wizard that helps new users create a personalized CLAUDE.md file based on their Obsidian workflow preferences
allowed-tools: [Read, Write, MultiEdit, Bash, Task]
argument-hint: "(optional) path to existing vault or 'new' for fresh setup"
---
# Initialize Bootstrap Configuration
This command helps you create a personalized CLAUDE.md configuration file by asking questions about your Obsidian workflow and preferences.
## Task
Read the CLAUDE-BOOTSTRAP.md template and interactively gather information about the user's:
- Existing vault structure (if any)
- Workflow preferences
- Note-taking style
- Organization methods
- Specific requirements
Then generate a customized CLAUDE.md file tailored to their needs.
## Process
1. **Initial Environment Setup**
- Check for package.json and run `pnpm install` if needed
- Verify core dependencies are installed
- Check git status and initialize if needed
- Create base folder structure (00_Inbox through 06_Metadata)
2. **Check Existing Configuration**
- Look for existing CLAUDE.md
- If exists, ask if they want to update or start fresh
- Check for CLAUDE-BOOTSTRAP.md template
3. **Gather Vault Information**
- Ask if they have an existing vault or starting new
- If existing, explore current folder structure
- Document any custom organization patterns
4. **Ask Configuration Questions**
- "Do you follow the PARA method or have a different organization system?"
- "What are your main use cases? (research, writing, project management, knowledge base, daily notes)"
- "Do you use any specific plugins or tools with Obsidian?"
- "What's your preferred naming convention for files?"
- "Do you work with attachments frequently? (images, PDFs, etc.)"
- "Do you use git for version control?"
- "Any specific websites or resources you reference often?"
- "Do you have any specific writing style preferences?"
- "Are there any workflows or patterns you want Claude to follow?"
5. **Optional MCP Server Setup**
- Ask: "Would you like to set up Gemini Vision for analyzing images and PDFs?"
- If yes:
- Guide to get API key from https://aistudio.google.com/apikey
- Help add to shell profile (.zshrc, .bashrc, etc.)
- Run `claude mcp add --scope project gemini-vision node .claude/mcp-servers/gemini-vision.mjs`
- Configure .mcp.json with API key
- Test the connection with a sample command
6. **Generate Custom Configuration**
- Start with CLAUDE-BOOTSTRAP.md as base
- Add user-specific sections:
- Custom folder structure
- Personal workflows
- Preferred tools and scripts
- Specific guidelines
- MCP configuration if set up
- Include their websites/resources if provided
- Add any custom naming conventions
7. **Create Supporting Files**
- Generate initial folder structure if new vault
- Create README files for main folders
- Create 05_Attachments/Organized/ directory
- Set up .gitignore if using git (include .mcp.json, node_modules)
- Create initial templates if requested
- Make initial git commit if repository was initialized
8. **Run Test Commands**
- Execute `pnpm vault:stats` to verify scripts work
- Test attachment commands if folders exist
- Test MCP tools if configured
- Verify git is tracking files correctly
9. **Provide Next Steps**
- Summary of what was created and configured
- Quick start guide specific to their setup
- List of available commands they can use
- Test commands to verify everything works
- Suggestions for first tasks based on their use cases
- How to modify configuration later
## Example Output
```markdown
# Your Obsidian Vault Configuration
Generated on: [Date]
Based on your preferences for: [main use cases]
Setup completed with: ✅ Dependencies ✅ Folder structure ✅ Git initialized
## Your Custom Folder Structure
[Their specific structure with explanations]
## Your Workflows
### Daily Routine
[Based on their answers]
### Project Management
[Their specific approach]
## Your Preferences
### File Naming
- Pattern: [their convention]
- Examples: [specific examples]
### Tools & Scripts
[Relevant scripts for their workflow]
## MCP Servers (if configured)
### Gemini Vision
- Status: ✅ Configured and tested
- API Key: Set in .mcp.json
- Test with: `Use gemini-vision to analyze [image path]`
## Available Commands
### Vault Management
- `pnpm vault:stats` - Show vault statistics
- `pnpm attachments:list` - List unprocessed attachments
- `pnpm attachments:organized` - Count organized files
### Claude Commands
- `claude run thinking-partner` - Collaborative thinking mode
- `claude run daily-review` - Review your day
- `claude run init-bootstrap` - Re-run this setup
## Quick Start
1. [Personalized first step]
2. [Next action based on their goals]
3. [Specific to their workflow]
## Setup Summary
✅ Dependencies installed (pnpm install)
✅ Folder structure created
✅ Git repository initialized
✅ CLAUDE.md personalized
[✅ MCP Gemini Vision configured - if set up]
[✅ First commit made - if git was initialized]
```
## Interactive Example
```
User: claude run init-bootstrap
Assistant: Welcome! I'll help you set up your personalized Obsidian + Claude configuration.
First, let me set up your environment...
[Runs pnpm install to install dependencies]
[Creates folder structure if missing]
[Checks git status]
✅ Dependencies installed
✅ Core folders created
✅ Git repository ready
Now let me ask you a few questions to customize your setup:
1. **What will you primarily use this vault for?**
(research, writing, project management, daily notes, knowledge base, or combination?)
User: I'll use it for research and writing, plus managing client projects
Assistant: Great! I'll configure your vault for research, writing, and client project management.
[Continues with questions...]
Would you like to set up Gemini Vision for analyzing images and PDFs? This requires a Google API key.
User: Yes, that sounds useful
Assistant: Excellent! Here's how to get your API key:
1. Go to https://aistudio.google.com/apikey
2. Click "Create API Key"
3. Copy the key (starts with AIzaSy...)
Once you have it, paste it here and I'll configure everything for you.
+120
View File
@@ -0,0 +1,120 @@
---
name: release
description: Automatically bump version, update changelog, commit, tag, and push a new release based on recent changes
allowed-tools: [Read, Write, Edit, MultiEdit, Bash, Grep]
argument-hint: "(optional) 'major', 'minor', 'patch', or leave blank for auto-detection"
---
# Release Command
Automates the entire release process: analyzes recent commits to determine version bump type, updates version in package.json, moves unreleased changelog entries to the new version, commits everything, creates a git tag, and pushes to GitHub.
## Task
1. Analyze recent commits since last tag to determine version bump type
2. Update version in package.json
3. Move "Unreleased" entries in CHANGELOG.md to the new version section
4. Commit the changes
5. Create an annotated git tag
6. Push commits and tags to GitHub
## Process
1. **Check Prerequisites**
- Ensure on main/master branch
- Check for uncommitted changes
- Verify CHANGELOG.md and package.json exist
- Get current version from package.json
2. **Determine Version Bump**
- If argument provided (major/minor/patch), use that
- Otherwise, analyze commits since last tag:
- Look for "BREAKING CHANGE" or "!" = major bump
- Look for "feat:" = minor bump
- Look for "fix:", "docs:", "chore:" = patch bump
- Calculate new version number
3. **Update Files**
- Update version in package.json
- Move "Unreleased" section in CHANGELOG.md to new version section
- Add comparison links for the new version
- Create new empty "Unreleased" section
4. **Git Operations**
- Stage changes: `git add package.json CHANGELOG.md`
- Commit: `git commit -m "chore: release v{version}"`
- Create annotated tag: `git tag -a v{version} -m "Release v{version}"`
- Push commits: `git push`
- Push tags: `git push --tags`
5. **Provide Next Steps**
- Show link to create GitHub release
- Remind to add release notes from changelog
## Version Bump Rules
### Semantic Versioning (MAJOR.MINOR.PATCH)
**MAJOR** (1.0.0 → 2.0.0):
- Breaking changes
- Commits with "BREAKING CHANGE" in body
- Commits with "!" after type (e.g., "feat!:")
**MINOR** (1.0.0 → 1.1.0):
- New features (backward compatible)
- Commits starting with "feat:"
**PATCH** (1.0.0 → 1.0.1):
- Bug fixes and minor changes
- Commits with "fix:", "docs:", "style:", "refactor:", "test:", "chore:"
## Example Usage
```bash
# Auto-detect version bump from commits
claude run release
# Force specific version bump
claude run release patch
claude run release minor
claude run release major
# Example output:
# 📦 Current version: 0.1.0
# 🔍 Analyzing commits since last release...
#
# Found commits:
# - feat: add video support to Gemini Vision
# - docs: update README with setup instructions
# - fix: correct attachment link handling
#
# ✨ Detected version bump: MINOR (new features added)
# 📝 New version: 0.2.0
#
# ✅ Updated package.json
# ✅ Updated CHANGELOG.md
# ✅ Committed changes
# ✅ Created tag v0.2.0
# ✅ Pushed to GitHub
#
# 🎉 Release v0.2.0 complete!
#
# Next steps:
# 1. Go to https://github.com/user/repo/releases/new?tag=v0.2.0
# 2. Add release notes from CHANGELOG.md
# 3. Publish the release
```
## Error Handling
- If not on main branch: "Please switch to main branch first"
- If uncommitted changes: "Please commit or stash changes first"
- If no changes since last release: "No changes to release"
- If version already exists: "Version X.X.X already exists"
## Safety Features
- Dry run mode: Show what would happen without making changes
- Confirmation prompt before pushing
- Validation of version format
- Check for existing tags before creating
+65
View File
@@ -0,0 +1,65 @@
# Research Assistant
Conduct thorough research on topics by searching the vault and synthesizing findings.
## Process
1. **Initial Search**
- Search the entire vault for the topic
- Identify all relevant notes
- Note gaps in existing knowledge
2. **Deep Dive**
- Read all relevant notes thoroughly
- Extract key insights and quotes
- Identify contradictions or tensions
- Map connections between ideas
3. **Synthesis**
- Create a summary of findings
- Highlight patterns and themes
- Note questions that remain unanswered
- Suggest areas for further research
## Output Structure
```markdown
# Research Summary: [Topic]
## Existing Knowledge
- What's already in the vault
- Key insights from previous work
## Key Themes
1. Theme 1
- Supporting notes: [[note1]], [[note2]]
- Key insight: ...
2. Theme 2
- Supporting notes: [[note3]], [[note4]]
- Key insight: ...
## Contradictions/Tensions
- Where ideas conflict
- Unresolved questions
## Gaps
- What's missing
- What to research next
## Connections
- Related topics: [[topic1]], [[topic2]]
- Surprising links: ...
## Recommended Next Steps
1. Specific research needed
2. Questions to explore
3. Experiments to try
```
## Tips
- Cast a wide net initially, then focus
- Look for surprising connections
- Don't ignore contradictions - they're often where insights live
- Always suggest concrete next actions
+37
View File
@@ -0,0 +1,37 @@
# Thinking Partner
You are a collaborative thinking partner specializing in helping people explore complex problems. Your role is to facilitate thinking through careful questioning and exploration, not to rush toward solutions.
## Core Behaviors
1. **Ask before answering** - Lead with questions that help clarify and deepen understanding
2. **Track insights** - Maintain a running log of key discoveries and connections
3. **Resist solutioning** - Stay in exploration mode until explicitly asked to move forward
4. **Connect ideas** - Help identify patterns and relationships across different notes
5. **Surface assumptions** - Gently challenge implicit beliefs and assumptions
## Workflow
When engaged as a thinking partner:
1. Start by understanding the topic or challenge
2. Search the vault for relevant existing notes
3. Ask 3-5 clarifying questions
4. As the conversation develops:
- Take notes on key insights
- Identify connections to other ideas
- Track open questions
- Note potential directions to explore
5. Periodically summarize what's emerging
## Key Prompts You Might Use
- "What's behind that thought?"
- "How does this connect to [other concept] you mentioned?"
- "What would the opposite look like?"
- "What's the real challenge here?"
- "What are we not considering?"
## Remember
The goal is not to have answers but to help discover them. Your value is in the quality of exploration, not the speed of resolution.
+92
View File
@@ -0,0 +1,92 @@
# Weekly Synthesis
Create a comprehensive synthesis of the week's work and thinking.
## Analysis Process
1. **Gather Week's Work**
- All notes created this week
- All notes modified this week
- Projects that saw activity
2. **Identify Patterns**
- Recurring themes
- Common challenges
- Breakthrough moments
- Energy patterns (what energized vs drained)
3. **Synthesize Learning**
- Key insights that emerged
- How thinking evolved
- Connections discovered
- Questions answered and raised
4. **Assess Progress**
- Projects advanced
- Areas maintained
- Resources added
- Items archived
## Output Format
Create a weekly synthesis note:
```markdown
# Weekly Synthesis - Week of [Date]
## Week at a Glance
- Notes created: [X]
- Projects active: [List]
- Major accomplishments: [List]
## Key Themes
### Theme 1: [Name]
- Where it appeared: [contexts]
- Why it matters: [significance]
- Next actions: [what to do]
### Theme 2: [Name]
- Where it appeared: [contexts]
- Why it matters: [significance]
- Next actions: [what to do]
## Major Insights
1. [Insight with context]
2. [Insight with context]
## Progress by Project
### [Project Name]
- What advanced:
- What's blocked:
- Next week's focus:
## Questions Emerged
- [Question 1 - and why it matters]
- [Question 2 - and why it matters]
## Energy Audit
- What gave energy:
- What drained energy:
- What to adjust:
## Connections Made
- [Note A] ←→ [Note B]: [Why significant]
- [Concept X] ←→ [Concept Y]: [New understanding]
## Next Week's Intentions
1. [Primary focus]
2. [Secondary focus]
3. [Thing to explore]
## To Process
- Inbox items: [count]
- Orphaned notes: [list]
- Missing connections: [identified]
```
## Follow-up Actions
- Archive completed projects
- Clean up inbox
- Update project status
- Plan next week's focus
@@ -0,0 +1,285 @@
# Gemini Vision MCP Server - Quick Start Guide
**For getting Gemini Vision working on a new machine in under 5 minutes**
## Prerequisites Check
Run these commands to verify you have everything needed:
```bash
node --version # Should be v22+
pnpm --version # Should be installed
claude --version # Claude Code should be installed
```
If any are missing:
- Node.js: Install from [nodejs.org](https://nodejs.org/) (v22+)
- pnpm: `npm install -g pnpm`
- Claude Code: Download from [claude.ai/code](https://claude.ai/code)
## Step 1: Get Your Gemini API Key
1. Go to [https://aistudio.google.com/apikey](https://aistudio.google.com/apikey)
2. Click "Create API Key"
3. Copy the key (starts with `AIzaSy...`)
## Step 2: Set Up Environment Variable
### For Linux/macOS with Bash:
```bash
echo 'export GEMINI_API_KEY="your-actual-api-key-here"' >> ~/.bashrc
source ~/.bashrc
echo $GEMINI_API_KEY # Verify it shows your key
```
### For Linux/macOS with Zsh:
```bash
echo 'export GEMINI_API_KEY="your-actual-api-key-here"' >> ~/.zshrc
source ~/.zshrc
echo $GEMINI_API_KEY # Verify it shows your key
```
### For Windows PowerShell:
```powershell
[System.Environment]::SetEnvironmentVariable('GEMINI_API_KEY', 'your-key-here', 'User')
# Restart PowerShell
$env:GEMINI_API_KEY # Verify it shows your key
```
## Step 3: Install Dependencies
**⚠️ CRITICAL: This step MUST be done before adding the MCP server!**
Navigate to your Obsidian vault:
```bash
cd ~/dev/02_Areas/Obsidian # Or wherever your vault is
```
Install the required dependencies:
```bash
# Install npm packages (REQUIRED - do this first!)
pnpm install
# This installs:
# - @google/generative-ai (Gemini API client)
# - @modelcontextprotocol/sdk (MCP server framework)
# - Other dependencies from package.json
```
**Common Error Fix**: If you see `Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@modelcontextprotocol/sdk'`, you forgot to run `pnpm install`!
**To hide node_modules from Obsidian** (optional but recommended):
1. Open Obsidian
2. Go to Settings → Files & Links → Excluded files
3. Click "Manage"
4. Add `node_modules/` to the list
5. Optionally also add: `pnpm-lock.yaml`, `.gitignore`
This keeps your vault clean while using standard Node.js module resolution.
## Step 4: Register the MCP Server
**For project-scoped installation (recommended for team use):**
```bash
# Add server to project (creates .mcp.json file)
claude mcp add --scope project gemini-vision node .claude/mcp-servers/gemini-vision.mjs
```
**For user-scoped installation (personal use across all projects):**
```bash
# Add server to your user config
claude mcp add --scope user gemini-vision node .claude/mcp-servers/gemini-vision.mjs
```
After adding, you'll need to edit the `.mcp.json` file to add your API key:
```json
{
"mcpServers": {
"gemini-vision": {
"type": "stdio",
"command": "node",
"args": [".claude/mcp-servers/gemini-vision.mjs"],
"env": {
"GEMINI_API_KEY": "your-api-key-here"
}
}
}
}
```
**IMPORTANT**:
- The command must be run from the Obsidian vault root directory
- You MUST have run `pnpm install` first
- The `.mcp.json` file is gitignored for security
## Step 5: Verify It's Working
1. **Open a NEW Claude Code window** (critical - must be new):
```bash
cd ~/dev/Obsidian
claude
```
2. **Check the server is connected**:
Type `/mcp` in Claude
You should see:
```
gemini-vision ✔ connected
```
3. **Test with an actual command**:
```
Use gemini-vision to extract text from 05 Attachments/[any-image.png]
```
## Troubleshooting
### "gemini-vision failed" or not showing in /mcp
1. **MOST COMMON ISSUE - Dependencies not installed**:
```bash
# If you see: Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@modelcontextprotocol/sdk'
# Run this:
pnpm install
```
Then reconnect the MCP server in Claude Code.
2. **Check API key is configured**:
- For project-scoped: Check `.mcp.json` has your API key in the env section
- For user-scoped: Check `~/.claude.json` has your API key
- The key should be in the format: `"GEMINI_API_KEY": "AIzaSy..."`
3. **Test server can run directly**:
```bash
export GEMINI_API_KEY="your-api-key-here"
node .claude/mcp-servers/gemini-vision.mjs
```
Should show: "🚀 Gemini Vision MCP Server running"
Press Ctrl+C to exit.
4. **Re-add the server (for project scope)**:
```bash
claude mcp remove gemini-vision --scope project
claude mcp add --scope project gemini-vision node .claude/mcp-servers/gemini-vision.mjs
# Then edit .mcp.json to add your API key
```
4. **Check logs**:
```bash
# Find log directory
ls ~/Library/Caches/claude-cli-nodejs/*/mcp-logs-gemini-vision/
# Or on Linux:
ls ~/.cache/claude-cli-nodejs/*/mcp-logs-gemini-vision/
# View latest log
tail -f [log-directory]/*.txt
```
### "Cannot find module" errors
1. **Verify package.json exists**:
```bash
cat package.json
```
Should show @google/generative-ai and @modelcontextprotocol/sdk
2. **Reinstall dependencies**:
```bash
rm -rf node_modules pnpm-lock.yaml
pnpm install
```
3. **Check node_modules was created**:
```bash
ls node_modules/@google/generative-ai
```
### Server runs but tools don't work
1. **Test API key directly**:
```bash
curl "https://generativelanguage.googleapis.com/v1beta/models?key=$GEMINI_API_KEY"
```
Should return a list of models, not an error.
2. **Check file paths**:
- Use absolute paths from vault root
- Example: `05 Attachments/image.png` not `./05 Attachments/image.png`
## Available Tools
Once working, you can use these in Claude:
### Image Analysis
```
# Analyze an image
Use gemini-vision to analyze 05 Attachments/screenshot.png
# Extract text (OCR)
Use gemini-vision to extract text from 05 Attachments/document.jpg
# Compare images
Use gemini-vision to compare image1.png and image2.png
# Suggest a filename
Use gemini-vision to suggest a filename for IMG_1234.jpg
# Analyze multiple images
Use gemini-vision to analyze multiple: image1.png, image2.png, image3.png
```
### Video Analysis (NEW!)
```
# Analyze a local video file
Use gemini-vision to analyze video 05 Attachments/video.mp4
# Analyze a YouTube video
Use gemini-vision to analyze YouTube video https://www.youtube.com/watch?v=VIDEO_ID
# Custom video analysis prompt
Use gemini-vision to analyze video file.mp4 and extract all visible text
```
**Note:** Video processing may take 30-60 seconds as files need to reach ACTIVE state before analysis. The server will automatically wait and show progress updates.
### Supported Formats
**Images:** JPG, JPEG, PNG, GIF, BMP, WebP
**Videos:** MP4, AVI, MOV, WebM, MKV, WMV, FLV, 3GP, M4V
**Documents:** PDF, TXT, DOC, DOCX, ODT, RTF
**Special:** YouTube URLs (direct support without download)
## Quick Reinstall (If Already Set Up Once)
If you've already set up the API key in your shell profile:
```bash
cd ~/dev/Obsidian
git pull
pnpm install
claude mcp add gemini-vision \
--scope local \
--env GEMINI_API_KEY=$GEMINI_API_KEY \
-- node .claude/mcp-servers/gemini-vision.mjs
```
Then open a new Claude window and test.
## File Locations
- **Server code**: `.claude/mcp-servers/gemini-vision.mjs`
- **Dependencies**: `package.json`
- **This guide**: `07 Readme/GEMINI_VISION_QUICK_START.md`
- **Detailed docs**: `07 Readme/GEMINI_VISION_INSTALLATION.md`
- **Development guide**: `07 Readme/MCP_DEVELOPMENT_GUIDE.md`
## Need Help?
1. Check the troubleshooting section above
2. Verify all prerequisites are installed
3. Make sure you're in the Obsidian vault root directory
4. Ensure the API key is properly set in your environment
---
*Last tested: September 2025*
+104
View File
@@ -0,0 +1,104 @@
# MCP Servers
Model Context Protocol servers extend Claude Code's capabilities.
## Gemini Vision MCP
Adds powerful image and document analysis capabilities using Google's Gemini model.
### Features
- **Image Analysis**: Describe, analyze, and extract text from images
- **Document Processing**: Analyze PDFs and documents
- **Multi-Image Comparison**: Compare multiple images at once
- **OCR**: Extract text from images
- **Smart Filename Suggestions**: Generate descriptive filenames for images
### Setup
1. **Get a Gemini API Key**
- Visit: https://aistudio.google.com/apikey
- Create a free API key
2. **Add to Environment**
```bash
# Add to ~/.zshrc or ~/.bashrc
export GEMINI_API_KEY='your-key-here'
# Reload shell
source ~/.zshrc
```
3. **Install Dependencies**
```bash
pnpm install
```
4. **Test Setup**
```bash
pnpm test-gemini
```
### Available Commands
Once configured, these commands become available in Claude Code:
- `mcp__gemini-vision__analyze_image` - Analyze a single image
- `mcp__gemini-vision__analyze_multiple` - Compare multiple images
- `mcp__gemini-vision__extract_text` - OCR text extraction
- `mcp__gemini-vision__compare_images` - Compare two images
- `mcp__gemini-vision__suggest_image_filename` - Generate descriptive filename
- `mcp__gemini-vision__analyze_document` - Analyze PDFs and documents
### Usage Examples
**Analyze Screenshot**
```
Analyze the image at 05_Attachments/screenshot.png
and tell me what it contains.
```
**Process Multiple Images**
```
Compare all images in 05_Attachments/Organized/
and identify common themes.
```
**Extract Text**
```
Extract all text from the PDF at
05_Attachments/document.pdf
```
**Rename Images**
```
Suggest better names for all images
in 05_Attachments/ based on their content.
```
### Troubleshooting
**"GEMINI_API_KEY not found"**
- Make sure you've added the key to your shell profile
- Restart your terminal and Claude Code
**"File not found"**
- Use absolute paths or paths relative to vault root
- Check file permissions
**Rate Limits**
- Free tier: 15 requests per minute
- Consider upgrading for heavy usage
## Adding More MCPs
1. Place MCP server file in `.claude/mcp-servers/`
2. Add configuration to Claude settings
3. Document setup here
4. Add usage examples
## Resources
- [MCP Documentation](https://modelcontextprotocol.io)
- [Gemini API Docs](https://ai.google.dev)
- [Claude Code MCP Guide](https://claude.ai/docs/mcp)
+430
View File
@@ -0,0 +1,430 @@
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
ListToolsRequestSchema,
CallToolRequestSchema
} from "@modelcontextprotocol/sdk/types.js";
import { GoogleGenerativeAI } from "@google/generative-ai";
import { GoogleAIFileManager } from "@google/generative-ai/server";
import fs from "fs/promises";
import path from "path";
import os from "os";
const apiKey = process.env.GEMINI_API_KEY;
if (!apiKey) {
console.error("❌ GEMINI_API_KEY environment variable is required");
console.error("");
console.error("To fix this:");
console.error("");
console.error("1. Get your API key from: https://aistudio.google.com/apikey");
console.error("");
console.error("2. Add to your shell profile:");
console.error(" For macOS/Linux (add to ~/.zshrc or ~/.bashrc):");
console.error(" export GEMINI_API_KEY='your-actual-api-key-here'");
console.error("");
console.error(" For Windows PowerShell:");
console.error(" [System.Environment]::SetEnvironmentVariable('GEMINI_API_KEY', 'your-key', 'User')");
console.error("");
console.error("3. Reload your terminal:");
console.error(" source ~/.zshrc (or source ~/.bashrc)");
console.error("");
console.error("4. Restart Claude Code");
console.error("");
console.error("For detailed instructions, see GEMINI_VISION_SETUP.md");
process.exit(1);
}
const genAI = new GoogleGenerativeAI(apiKey);
const fileManager = new GoogleAIFileManager(apiKey);
const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
// Expand home directory in paths
function expandPath(filepath) {
if (filepath.startsWith("~/")) {
return path.join(os.homedir(), filepath.slice(2));
}
return filepath;
}
// Helper function to wait/sleep
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Upload file to Gemini
async function uploadFile(filePath) {
const expandedPath = expandPath(filePath);
try {
await fs.access(expandedPath);
} catch {
throw new Error(`File not found: ${filePath}`);
}
const ext = path.extname(expandedPath).toLowerCase();
const mimeTypes = {
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.png': 'image/png',
'.gif': 'image/gif',
'.bmp': 'image/bmp',
'.webp': 'image/webp',
'.pdf': 'application/pdf',
'.txt': 'text/plain',
'.doc': 'application/msword',
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'.odt': 'application/vnd.oasis.opendocument.text',
'.rtf': 'application/rtf',
// Video formats
'.mp4': 'video/mp4',
'.avi': 'video/x-msvideo',
'.mov': 'video/quicktime',
'.webm': 'video/webm',
'.mkv': 'video/x-matroska',
'.wmv': 'video/x-ms-wmv',
'.flv': 'video/x-flv',
'.3gp': 'video/3gpp',
'.m4v': 'video/x-m4v',
};
const uploadResult = await fileManager.uploadFile(expandedPath, {
mimeType: mimeTypes[ext] || 'application/octet-stream',
});
let file = uploadResult.file;
// For video files, poll until the file is in ACTIVE state
const videoExtensions = ['.mp4', '.avi', '.mov', '.webm', '.mkv', '.wmv', '.flv', '.3gp', '.m4v'];
if (videoExtensions.includes(ext)) {
console.error(`Waiting for video file to process: ${path.basename(filePath)}`);
let attempts = 0;
const maxAttempts = 60; // Max 5 minutes (60 * 5 seconds)
while (file.state !== 'ACTIVE' && attempts < maxAttempts) {
await sleep(5000); // Wait 5 seconds
attempts++;
// Get updated file status
const fileStatus = await fileManager.getFile(file.name);
file = fileStatus;
console.error(`Video processing status: ${file.state} (attempt ${attempts}/${maxAttempts})`);
if (file.state === 'FAILED') {
throw new Error(`Video processing failed for: ${filePath}`);
}
}
if (file.state !== 'ACTIVE') {
throw new Error(`Video processing timeout for: ${filePath}. File state: ${file.state}`);
}
console.error('Video file is ready for analysis');
}
return file;
}
// Tool handlers
async function analyzeImage(args) {
const imagePath = args.image_path;
const prompt = args.prompt || "Describe this image in detail";
const file = await uploadFile(imagePath);
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
return result.response.text();
}
async function analyzeMultiple(args) {
const imagePaths = args.image_paths;
const prompt = args.prompt || "Analyze these images";
const content = [prompt];
for (const imagePath of imagePaths) {
const file = await uploadFile(imagePath);
content.push({ fileData: { fileUri: file.uri, mimeType: file.mimeType }});
}
const result = await model.generateContent(content);
return result.response.text();
}
async function extractText(args) {
const imagePath = args.image_path;
const format = args.format || "plain";
const prompts = {
plain: "Extract and transcribe all text from this image. Return only the text, nothing else.",
markdown: "Extract all text from this image and format it in markdown, preserving structure.",
structured: "Extract all text from this image and organize it with clear sections and structure."
};
const file = await uploadFile(imagePath);
const result = await model.generateContent([
prompts[format] || prompts.plain,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
return result.response.text();
}
async function compareImages(args) {
const image1Path = args.image1_path;
const image2Path = args.image2_path;
const focus = args.focus || "differences";
const prompts = {
differences: "Compare these two images and describe all the differences you can find.",
similarities: "Compare these two images and describe what they have in common.",
changes: "Describe what has changed between the first and second image."
};
const [file1, file2] = await Promise.all([
uploadFile(image1Path),
uploadFile(image2Path)
]);
const result = await model.generateContent([
prompts[focus] || prompts.differences,
{ fileData: { fileUri: file1.uri, mimeType: file1.mimeType }},
{ fileData: { fileUri: file2.uri, mimeType: file2.mimeType }}
]);
return result.response.text();
}
async function suggestFilename(args) {
const imagePath = args.image_path;
const maxLength = args.max_length || 60;
const includeDate = args.include_date || false;
const prompt = `Analyze this image and suggest a descriptive filename for it.
Requirements:
- Maximum ${maxLength} characters (not including extension)
- Use title case with spaces (will be converted to hyphens)
- Be specific and descriptive about the content
- ${includeDate ? 'Include YYYY-MM-DD prefix if a date is visible in the image' : 'Do not include date prefix'}
- Focus on the main subject or purpose of the image
- For screenshots: include the application or website name
- For diagrams: include the type and subject
- For photos: include the subject and context
- Return ONLY the filename suggestion, no explanation or extension`;
const file = await uploadFile(imagePath);
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
// Clean up the suggestion and format it
let suggestion = result.response.text().trim();
// Remove any file extension if accidentally included
suggestion = suggestion.replace(/\.(png|jpg|jpeg|gif|webp|pdf)$/i, '');
// Replace spaces with hyphens
suggestion = suggestion.replace(/\s+/g, ' ').replace(/ /g, ' - ');
// Ensure it doesn't exceed max length
if (suggestion.length > maxLength) {
suggestion = suggestion.substring(0, maxLength).replace(/ - $/, '');
}
return suggestion;
}
async function analyzeDocument(args) {
const documentPath = args.document_path;
const prompt = args.prompt || "Analyze this document and provide a comprehensive summary";
const file = await uploadFile(documentPath);
const result = await model.generateContent([
prompt,
{ fileData: { fileUri: file.uri, mimeType: file.mimeType }}
]);
return result.response.text();
}
// Analyze video files or YouTube URLs
async function analyzeVideo(args) {
const videoPath = args.video_path;
const youtubeUrl = args.youtube_url;
const prompt = args.prompt || "Summarize this video in detail, including key moments and any text or speech content";
if (!videoPath && !youtubeUrl) {
throw new Error("Either video_path or youtube_url is required");
}
if (videoPath && youtubeUrl) {
throw new Error("Please provide either video_path or youtube_url, not both");
}
let fileData;
if (youtubeUrl) {
// YouTube URLs can be passed directly to the API
fileData = { fileUri: youtubeUrl };
} else {
// Upload local video file
const file = await uploadFile(videoPath);
fileData = { fileUri: file.uri, mimeType: file.mimeType };
}
const result = await model.generateContent([
prompt,
{ fileData }
]);
return result.response.text();
}
// Create MCP server
const server = new Server(
{ name: "gemini-vision", version: "1.0.0" },
{ capabilities: { tools: {} }}
);
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "analyze_image",
description: "Analyze an image - transcribe text, describe content, or answer questions",
inputSchema: {
type: "object",
properties: {
image_path: { type: "string", description: "Path to the image file" },
prompt: { type: "string", description: "What to do with the image", default: "Describe this image" }
},
required: ["image_path"]
}
},
{
name: "analyze_multiple",
description: "Analyze multiple images at once",
inputSchema: {
type: "object",
properties: {
image_paths: { type: "array", items: { type: "string" }, description: "List of image paths" },
prompt: { type: "string", description: "What to do with the images", default: "Analyze these images" }
},
required: ["image_paths"]
}
},
{
name: "extract_text",
description: "Extract and transcribe all text from an image (OCR)",
inputSchema: {
type: "object",
properties: {
image_path: { type: "string", description: "Path to the image file" },
format: { type: "string", enum: ["plain", "markdown", "structured"], default: "plain" }
},
required: ["image_path"]
}
},
{
name: "compare_images",
description: "Compare two images and describe differences or similarities",
inputSchema: {
type: "object",
properties: {
image1_path: { type: "string", description: "Path to first image" },
image2_path: { type: "string", description: "Path to second image" },
focus: { type: "string", enum: ["differences", "similarities", "changes"], default: "differences" }
},
required: ["image1_path", "image2_path"]
}
},
{
name: "suggest_image_filename",
description: "Analyze an image and suggest a descriptive filename (without extension)",
inputSchema: {
type: "object",
properties: {
image_path: { type: "string", description: "Path to the image file" },
max_length: { type: "number", description: "Maximum filename length", default: 60 },
include_date: { type: "boolean", description: "Include date prefix in suggestion", default: false }
},
required: ["image_path"]
}
},
{
name: "analyze_video",
description: "Analyze video files or YouTube URLs - extract content, summarize, transcribe speech, identify objects/text. Provide either video_path OR youtube_url",
inputSchema: {
type: "object",
properties: {
video_path: { type: "string", description: "Path to local video file (MP4, AVI, MOV, etc.)" },
youtube_url: { type: "string", description: "YouTube video URL (e.g., https://www.youtube.com/watch?v=...)" },
prompt: { type: "string", description: "What to analyze in the video", default: "Summarize this video in detail" }
},
required: []
}
},
{
name: "analyze_document",
description: "Analyze a PDF or document with custom prompts - extract specific information, find mentions of topics, summarize sections, etc.",
inputSchema: {
type: "object",
properties: {
document_path: { type: "string", description: "Path to the document file (PDF, DOC, DOCX, ODT, RTF, TXT)" },
prompt: { type: "string", description: "What to analyze or extract from the document", default: "Analyze this document and provide a comprehensive summary" }
},
required: ["document_path"]
}
}
]
}));
// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
let result;
switch (name) {
case "analyze_image":
result = await analyzeImage(args);
break;
case "analyze_multiple":
result = await analyzeMultiple(args);
break;
case "extract_text":
result = await extractText(args);
break;
case "compare_images":
result = await compareImages(args);
break;
case "suggest_image_filename":
result = await suggestFilename(args);
break;
case "analyze_document":
result = await analyzeDocument(args);
break;
case "analyze_video":
result = await analyzeVideo(args);
break;
default:
throw new Error(`Unknown tool: ${name}`);
}
return {
content: [{ type: "text", text: result }]
};
} catch (error) {
throw new Error(`Tool execution failed: ${error.message}`);
}
});
// Start server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("🚀 Gemini Vision MCP Server running");
}
main().catch(console.error);
+10
View File
@@ -0,0 +1,10 @@
{
"permissions": {
"allow": [
"WebSearch",
"Bash(gitleaks detect:*)"
],
"deny": [],
"ask": []
}
}