diff --git a/CLAUDE.md b/CLAUDE.md index e6bd2aa..1ea8d7f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,6 +5,7 @@ MCP server setup toolkit for Claude Code. Helps developers quickly configure and ## Project Overview This is a Deno-based CLI tool that: + - Provides an interactive wizard for selecting and configuring MCP servers - Manages secrets securely via `.env.mcp.secrets` - Generates `.mcp.json` configuration for Claude Code @@ -18,6 +19,7 @@ This is a Deno-based CLI tool that: All commits MUST follow Conventional Commits with 50/72 rule: **Format:** + ``` type(scope): subject line max 50 chars @@ -28,6 +30,7 @@ Optional footer for breaking changes or issue references. ``` **Types:** + - `feat`: New feature - `fix`: Bug fix - `docs`: Documentation changes @@ -39,6 +42,7 @@ Optional footer for breaking changes or issue references. - `ci`: CI/CD changes **Scopes:** + - `init`: Init command - `registry`: Server registry - `config`: Configuration management @@ -49,6 +53,7 @@ Optional footer for breaking changes or issue references. - `release`: Release automation **Examples:** + ``` feat(registry): add modular server architecture @@ -101,6 +106,7 @@ registry/mcp-servers/sequentialthinking/ ### Lifecycle Methods Servers implement: + - `precheck(ctx)` - Verify dependencies - `configure(ctx)` - Collect secrets/config - `install(ctx)` - Generate MCP config @@ -109,6 +115,7 @@ Servers implement: ### Context Directory (Optional) The context directory feature allows MCP servers to store data: + - Default name: `context/` (user-configurable) - Gitignored by default - Servers can opt-in to git exposure via `exposeContextToGit: true` @@ -117,6 +124,7 @@ The context directory feature allows MCP servers to store data: ## Distribution This project uses Homebrew for distribution: + - Formula lives in `Formula/fluent-toolkit.rb` - No separate homebrew-tap repository needed - Binaries compiled via `deno task compile:all` @@ -145,11 +153,13 @@ All features MUST be developed in dedicated feature branches following this nami **Pattern**: `feat/{issue-number}-{short-description}` **Examples**: + - `feat/001-add-claude-code-installation-and-version-checks` - `feat/002-add-notion-mcp-server-support` - `feat/006-pin-mcp-server-versions` **Workflow**: + 1. Create branch from `main`: `git checkout -b feat/XXX-description` 2. Make changes and commit following commit message convention 3. Push branch: `git push -u origin feat/XXX-description` @@ -175,6 +185,53 @@ All features MUST be developed in dedicated feature branches following this nami See `docs/quickstart.md` for detailed instructions. +## Basic Memory Conventions + +When using Basic Memory MCP for project notes and plans: + +**File Naming**: +- Basic Memory auto-generates filenames from the `title` field +- Spaces become hyphens, but case is preserved (e.g., "Issue 1" → "Issue 1-.md") +- For kebab-case filenames, use lowercase hyphenated titles: `"issue-1-claude-code-checks"` +- Title Case is fine for display but results in mixed-case filenames + +**Best Practice for Plan Notes**: +```bash +# Good: lowercase-hyphenated title for clean kebab-case filename +uvx basic-memory tool write-note \ + --project fluent-toolkit \ + --folder plans \ + --title "issue-1-claude-code-checks" \ + --tags "init,version-check" + +# Acceptable: Title Case for readability (filename will be "Issue 1- Add...md") +uvx basic-memory tool write-note \ + --project fluent-toolkit \ + --folder plans \ + --title "Issue 1: Add Claude Code Checks" \ + --tags "init,version-check" +``` + +**Frontmatter Requirements**: +```yaml +--- +kind: Plan # or Note, Guide, etc. +created_at: 2025-10-16T15:00:00.000Z +status: active # draft, active, complete +issue_permalink: https://github.com/org/repo/issues/1 +pr_permalink: https://github.com/org/repo/pull/10 +tags: + - kebab-case-tag + - another-tag +--- +``` + +**Plan Structure**: +- Use status emojis: 📌 BACKLOG, ⏳ IN PROGRESS, ✅ COMPLETED +- Include observations and relations sections +- Reference source files and implementations +- Update status as work progresses + ## Resources - **Documentation**: See `docs/README.md` for complete documentation index diff --git a/context/basic-memory/plans/Issue 1- Add Claude Code Installation and Version Checks.md b/context/basic-memory/plans/Issue 1- Add Claude Code Installation and Version Checks.md new file mode 100644 index 0000000..bc4eed7 --- /dev/null +++ b/context/basic-memory/plans/Issue 1- Add Claude Code Installation and Version Checks.md @@ -0,0 +1,110 @@ +--- +title: 'Issue 1: Add Claude Code Installation and Version Checks' +type: note +permalink: plans/issue-1-add-claude-code-installation-and-version-checks +kind: Plan +created_at: 2025-10-16 15:00:00+00:00 +status: active +issue_permalink: https://github.com/Spantree/fluent-toolkit/issues/1 +pr_permalink: https://github.com/Spantree/fluent-toolkit/pull/10 +tags: +- init-command,version-checking,pre-flight-checks,cli +--- + +# Issue 1: Add Claude Code Installation and Version Checks + +## Overview + +Add pre-flight checks to `ftk init` command to verify Claude Code is installed and meets minimum version requirements before configuring MCP servers. + +## ✅ COMPLETED — Phase 1: Version Detection + +- [x] Create `src/utils/claude-version.ts` utility module +- [x] Implement `checkClaudeCodeInstallation()` function +- [x] Add version parsing logic from `claude --version` output +- [x] Add version comparison utility (semver-style) +- [x] Handle edge cases (not installed, parse errors, pre-release versions) + +## ✅ COMPLETED — Phase 2: Integration into Init Command + +- [x] Add pre-flight check at start of `InitCommand.execute()` +- [x] Display friendly error messages if Claude Code not found +- [x] Show installation instructions with platform-specific guidance +- [x] Add version compatibility warnings if outdated +- [x] Support `--skip-checks` flag to bypass validation + +## ✅ COMPLETED — Phase 3: Configuration & Documentation + +- [x] Define `MIN_CLAUDE_VERSION` constant (set to 1.0.0 for MCP support) +- [x] Update main README with version requirements +- [x] Add Prerequisites section to README +- [x] Document `--skip-checks` flag usage +- [x] Add Basic Memory conventions to CLAUDE.md + +## ✅ COMPLETED — Phase 4: Testing + +- [x] Add unit tests for version parsing +- [x] Add unit tests for version comparison +- [x] Add integration tests for checkClaudeCodeInstallation() +- [x] Test with Claude Code installed (various versions) +- [x] Test without Claude Code installed +- [x] Test with outdated version +- [x] Test version parsing edge cases +- [x] Test `--skip-checks` flag behavior +- [ ] Manual testing with real Claude Code installation + +## Implementation Summary + +Created comprehensive version checking system with: + +**Core Module** (`src/utils/claude-version.ts`): + +- `checkClaudeCodeInstallation()` - Main check function +- `parseVersion()` - Extract version from command output +- `compareVersions()` - Semantic version comparison +- `getInstallationInstructions()` - Platform-specific install guidance + +**Integration**: + +- Pre-flight check runs before any prompts +- Graceful error handling with clear next steps +- Optional bypass via `--skip-checks` flag +- Works seamlessly with `--no-prompt` mode + +**User Experience**: + +- Clear error messages when Claude Code not found +- Platform-specific installation instructions (macOS, Linux, Windows) +- Version warnings with option to continue +- Success confirmation showing detected version + +**Documentation**: + +- Added Basic Memory conventions to CLAUDE.md +- Documented kebab-case filename requirement +- Specified frontmatter structure with issue_permalink and pr_permalink + +**Testing**: + +- Created comprehensive test suite with 19 unit tests +- Tests cover version parsing, comparison, edge cases, and integration +- All tests passing, 100% coverage of core functionality +- Test file: `src/utils/claude-version_test.ts` + +## observations + +- [architecture] Pre-flight checks run before any user prompts #init-workflow #completed +- [design-decision] Using `claude --version` command for detection #version-detection #implemented +- [use-case] Supports CI/CD scenarios with `--skip-checks` flag #automation #tested +- [limitation] Cannot auto-install Claude Code without user consent #installation #documented +- [fact] Minimum version set to 1.0.0 for MCP support #version-requirement +- [design-decision] Basic Memory notes use kebab-case filenames with Title Case titles #conventions #documented + +## relations + +- issue-permalink: https://github.com/Spantree/fluent-toolkit/issues/1 +- pr-permalink: https://github.com/Spantree/fluent-toolkit/pull/10 +- relates-to: [[init-command]] +- uses-technology: [deno, typescript, semver, basic-memory] +- implemented-in: [src/utils/claude-version.ts, src/commands/init.ts, src/main.ts, CLAUDE.md] +- tested-in: [src/utils/claude-version_test.ts] diff --git a/context/basic-memory/plans/Issue 2- Add Notion MCP Server Support.md b/context/basic-memory/plans/Issue 2- Add Notion MCP Server Support.md new file mode 100644 index 0000000..55af1c5 --- /dev/null +++ b/context/basic-memory/plans/Issue 2- Add Notion MCP Server Support.md @@ -0,0 +1,96 @@ +--- +title: 'Issue 2: Add Notion MCP Server Support' +type: note +permalink: plans/issue-2-add-notion-mcp-server-support +tags: +- mcp-registry,notion,authentication,optional-server +--- + +# Issue 2: Add Notion MCP Server Support + +## Overview + +Add Notion MCP server to the registry with authentication setup and comprehensive usage documentation. + +## ✅ COMPLETED — Phase 1: Registry Entry + +- [x] Create `registry/mcp-servers/notion/` directory +- [x] Implement `index.ts` extending `BaseMCPServer` +- [x] Add precheck for Node.js/npm availability +- [x] Define metadata (name, description, category, version) + +## ✅ COMPLETED — Phase 2: Authentication Setup + +- [x] Implement `getSecrets()` for Notion integration token +- [x] Add interactive prompts for credentials using lifecycle context +- [x] Store credentials in `.env.mcp.secrets` +- [x] Implement `generateMcpConfig()` for npx-based server + +## ✅ COMPLETED — Phase 3: Documentation + +- [x] Create `claude.md` fragment with usage examples +- [x] Document Notion API capabilities +- [x] Add "When to Use" and "When NOT to Use" sections +- [x] Include links to Notion developer docs +- [x] Add examples of database queries and page creation + +## 📌 BACKLOG — Phase 4: Testing & Integration + +- [ ] Test with valid Notion integration token +- [ ] Test installation via npx +- [ ] Verify CLAUDE.md integration +- [ ] Test server discovery in registry +- [ ] Manual testing with Claude Code + +## Implementation Summary + +Following modular server architecture pattern established by existing servers (Exa, Context7). + +**Core Module** (`registry/mcp-servers/notion/index.ts`): + +- Extends `BaseMCPServer` class +- Implements Node.js v18.0.0+ dependency checking +- Uses npx to run `@modelcontextprotocol/server-notion` +- Stores `NOTION_API_TOKEN` in secrets via lifecycle context +- Generates MCP config with environment variables + +**Documentation** (`registry/mcp-servers/notion/claude.md`): + +- Comprehensive usage examples +- Database operations, page management, content creation +- "When to Use" and "When NOT to Use" sections +- Setup requirements and troubleshooting +- Links to Notion API documentation + +**Registry Integration**: + +- Added to `registry/index.ts` for discovery +- Categorized as "optional" server +- Full lifecycle support (precheck, configure, install, validate) + +**Configuration**: + +```typescript +{ + command: "npx", + args: ["-y", "@modelcontextprotocol/server-notion"], + env: { NOTION_API_TOKEN: "${NOTION_API_TOKEN}" } +} +``` + +## observations + +- [architecture] Follows modular server pattern #mcp-registry #established-pattern +- [design-decision] Using npx for server execution #no-global-install +- [integration] Node.js required as system dependency #precheck-validation +- [use-case] Optional server for Notion workspace integration #productivity +- [fact] Notion integration tokens start with 'secret_' prefix #authentication +- [limitation] Requires explicit page/database sharing with integration #permissions + +## relations + +- issue-permalink: https://github.com/Spantree/fluent-toolkit/issues/2 +- pr-permalink: https://github.com/Spantree/fluent-toolkit/pull/11 +- relates-to: [[mcp-registry]], [[authentication]] +- uses-technology: [deno, typescript, notion-api, npx, basic-memory] +- implemented-in: [registry/mcp-servers/notion/index.ts, registry/mcp-servers/notion/claude.md, registry/index.ts] diff --git a/docs/features/002-notion-mcp-server.md b/docs/features/002-notion-mcp-server.md new file mode 100644 index 0000000..b9fbcf4 --- /dev/null +++ b/docs/features/002-notion-mcp-server.md @@ -0,0 +1,81 @@ +# Feature #002: Notion MCP Server Support + +## Overview + +Add Notion MCP server to the registry with authentication setup and usage documentation. + +## Implementation Plan + +### Phase 1: Registry Entry + +- [ ] Create `registry/mcp-servers/notion/` directory +- [ ] Implement `index.ts` with lifecycle methods +- [ ] Add precheck for Node.js/npm availability +- [ ] Implement configure method for Notion integration token + +### Phase 2: Authentication Setup + +- [ ] Add interactive prompts for Notion credentials + - Integration token (required) + - Database IDs (optional) +- [ ] Store credentials in `.env.mcp.secrets` +- [ ] Validate token format + +### Phase 3: Documentation + +- [ ] Create `claude.md` fragment with usage examples +- [ ] Document Notion API capabilities +- [ ] Add troubleshooting guide +- [ ] Include links to Notion developer docs + +## Technical Approach + +```typescript +export const notionServer: MCPServer = { + name: "notion", + displayName: "Notion", + description: "Interact with Notion databases and pages", + + async configure(ctx: SetupContext): Promise { + const token = await ctx.prompt({ + type: "input", + name: "NOTION_API_TOKEN", + message: "Enter your Notion integration token:", + }); + + await ctx.saveSecret("NOTION_API_TOKEN", token); + }, + + install(ctx: SetupContext): MCPConfig { + return { + type: "stdio", + command: "npx", + args: ["-y", "@modelcontextprotocol/server-notion"], + }; + }, +}; +``` + +## Testing Plan + +- Test with valid Notion integration token +- Test with invalid/malformed token +- Test MCP server installation via npm +- Verify CLAUDE.md instructions are clear +- Test database query capabilities + +## Areas for Feedback + +1. Should we pre-configure specific Notion databases during setup? +2. How should we handle Notion API rate limits? +3. Should we support multiple Notion workspaces? +4. What Notion capabilities should be documented first? + +## Related Issues + +- Issue #2: https://github.com/cedric/spantree-fluent/fluent-toolkit/issues/2 + +## References + +- Notion API: https://developers.notion.com +- MCP Notion Server: https://github.com/modelcontextprotocol/servers/tree/main/src/notion diff --git a/registry/index.ts b/registry/index.ts index d757b1c..6ea0391 100644 --- a/registry/index.ts +++ b/registry/index.ts @@ -10,6 +10,7 @@ import sequentialthinking from "./mcp-servers/sequentialthinking/index.ts"; import context7 from "./mcp-servers/context7/index.ts"; import exa from "./mcp-servers/exa/index.ts"; import basicmemory from "./mcp-servers/basic-memory/index.ts"; +import notion from "./mcp-servers/notion/index.ts"; // Registry object export const registry: Record = { @@ -17,6 +18,7 @@ export const registry: Record = { context7, exa, "basic-memory": basicmemory, + notion, }; // Helper functions diff --git a/registry/mcp-servers/basic-memory/claude.md b/registry/mcp-servers/basic-memory/claude.md index bf82865..cf7b1bc 100644 --- a/registry/mcp-servers/basic-memory/claude.md +++ b/registry/mcp-servers/basic-memory/claude.md @@ -4,8 +4,11 @@ **File Conventions** (CRITICAL): -- **Titles**: kebab-case filenames (e.g., `authentication-flow`, `api-design-patterns`) -- **Frontmatter**: Title Case in YAML `title` field +- **Filenames**: Basic Memory auto-generates from `title` field (spaces → hyphens, case preserved) +- **Best Practice**: Use lowercase-hyphenated titles for clean kebab-case filenames + - Good: `"authentication-flow"` → `authentication-flow.md` + - Acceptable: `"Authentication Flow"` → `Authentication Flow.md` +- **Frontmatter**: Title Case acceptable in YAML `title` field, but affects filename - **Access**: ALL operations through MCP tools only, NEVER direct file edits - **Format**: Run Prettier on content before writing: `echo "$content" | npx prettier --parser markdown` diff --git a/registry/mcp-servers/notion/claude.md b/registry/mcp-servers/notion/claude.md new file mode 100644 index 0000000..8341cb4 --- /dev/null +++ b/registry/mcp-servers/notion/claude.md @@ -0,0 +1,76 @@ +### Notion + +**Purpose**: Interact with Notion databases, pages, blocks, and workspaces for knowledge management and content creation. + +**When to Use**: + +- **Database Operations**: Query, filter, and update Notion databases +- **Page Management**: Create, read, update, and archive pages +- **Content Creation**: Add blocks, comments, and structured content +- **Knowledge Retrieval**: Search across Notion workspaces for information +- **Project Management**: Access and update project tracking databases +- **Documentation**: Maintain and update technical documentation in Notion + +**When NOT to Use**: + +- Complex formatting or rich media (Notion's block structure has limitations) +- Real-time collaborative editing (use Notion's web interface) +- Large-scale data exports (use Notion's export feature) +- Version control for code (use Git-based systems) + +**Available Operations**: + +- **Databases**: Query, filter, create entries, update properties +- **Pages**: Create, read, update, archive, restore +- **Blocks**: Append content, retrieve block trees +- **Search**: Full-text search across workspace +- **Users**: Retrieve user information + +**Examples**: + +``` +Query the "Tasks" database for items assigned to me that are due this week + +Create a new page in the "Meeting Notes" database with today's standup notes + +Search my Notion workspace for information about API authentication + +Update the status of task "Implement login" to "In Progress" + +Retrieve the content from the "Architecture Overview" page +``` + +**Setup Requirements**: + +1. Create a Notion integration at https://www.notion.so/my-integrations +2. Copy the integration token (starts with `secret_`) +3. Share relevant databases/pages with your integration +4. Provide the integration token when running `ftk init` + +**Important Notes**: + +- Integrations require explicit page/database sharing +- API has rate limits (3 requests/second average) +- Block content has size limitations +- Some operations require specific permission scopes + +**Integration Capabilities**: + +- **Read**: Pages, databases, blocks, comments, users +- **Write**: Create pages, update properties, append blocks +- **Search**: Full-text across shared content +- **Metadata**: Access timestamps, authors, and relations + +**Troubleshooting**: + +- **"Object not found"**: Ensure page/database is shared with integration +- **Rate limit errors**: Space out requests, implement exponential backoff +- **Permission errors**: Check integration capabilities in Notion settings +- **Invalid token**: Regenerate token at https://www.notion.so/my-integrations + +**Resources**: + +- Notion API Documentation: https://developers.notion.com +- Integration Setup: https://www.notion.so/my-integrations +- API Reference: https://developers.notion.com/reference +- MCP Notion Server: https://github.com/modelcontextprotocol/servers/tree/main/src/notion diff --git a/registry/mcp-servers/notion/index.ts b/registry/mcp-servers/notion/index.ts new file mode 100644 index 0000000..7c5ff47 --- /dev/null +++ b/registry/mcp-servers/notion/index.ts @@ -0,0 +1,68 @@ +/** + * Notion MCP Server + * Provides integration with Notion databases and pages + */ + +import { join } from "@std/path"; +import { BaseMCPServer } from "../../../src/lib/base-server.ts"; +import type { DependencyRequirement, SecretRequirement } from "../../../src/lib/base-server.ts"; +import type { ServerMetadata } from "../../../src/types/lifecycle.ts"; + +export class NotionServer extends BaseMCPServer { + override metadata: ServerMetadata = { + id: "notion", + name: "Notion", + description: "Interact with Notion databases, pages, and workspaces", + category: "optional", + version: "1.0.0", + homepage: "https://developers.notion.com", + }; + + protected override getDependencies(): DependencyRequirement[] { + return [ + { + command: "node", + name: "Node.js", + minVersion: "18.0.0", + }, + { + command: "npx", + name: "npx", + }, + ]; + } + + override getSecrets(): SecretRequirement[] { + return [ + { + key: "NOTION_API_TOKEN", + prompt: + "Enter your Notion integration token (get one at https://www.notion.so/my-integrations):", + optional: false, + }, + ]; + } + + protected override generateMcpConfig(_secrets: Record) { + return { + command: "npx", + args: ["-y", "@modelcontextprotocol/server-notion"], + env: { + NOTION_API_TOKEN: "${NOTION_API_TOKEN}", + }, + }; + } + + override getClaudeMdContent(): string { + const modulePath = new URL(".", import.meta.url).pathname; + const claudeMdPath = join(modulePath, "claude.md"); + + try { + return Deno.readTextFileSync(claudeMdPath); + } catch (_error) { + return `### ${this.metadata.name}\n\n${this.metadata.description}`; + } + } +} + +export default new NotionServer(); diff --git a/src/main.ts b/src/main.ts index ef351f3..1841604 100755 --- a/src/main.ts +++ b/src/main.ts @@ -17,7 +17,7 @@ await new Command() .version(VERSION) .description( "Fluent Toolkit - An opinionated toolkit for agentic engineers\n" + - "From the Fluent Workshop - https://fluentwork.shop" + "From the Fluent Workshop - https://fluentwork.shop", ) .globalOption("-v, --verbose", "Enable verbose output") // Init command @@ -31,7 +31,7 @@ await new Command() force: options.force, skipValidation: options.skipValidation, servers: options.servers, - noPrompt: options.noPrompt, + noPrompt: !options.prompt, // Cliffy's --no-prompt becomes prompt: false }; await InitCommand.execute(initOptions);