From c817700869aeb0dfa05d95964dfd63d3f5d3c799 Mon Sep 17 00:00:00 2001 From: Lilith Date: Sat, 27 Dec 2025 19:07:51 -0800 Subject: [PATCH] Initial commit --- .gitignore | 25 +++++++++++++++++++++++ LICENSE | 21 ++++++++++++++++++++ README.md | 39 ++++++++++++++++++++++++++++++++++++ package.json | 44 +++++++++++++++++++++++++++++++++++++++++ src/data-directories.ts | 33 +++++++++++++++++++++++++++++++ src/index.ts | 8 ++++++++ src/types.ts | 36 +++++++++++++++++++++++++++++++++ src/version.ts | 38 +++++++++++++++++++++++++++++++++++ tsconfig.json | 20 +++++++++++++++++++ 9 files changed, 264 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 package.json create mode 100644 src/data-directories.ts create mode 100644 src/index.ts create mode 100644 src/types.ts create mode 100644 src/version.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ae7879 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Dependencies +node_modules/ + +# Build output +dist/ + +# Logs +*.log +npm-debug.log* +pnpm-debug.log* + +# OS files +.DS_Store +Thumbs.db + +# IDE +.idea/ +.vscode/ +*.swp +*.swo + +# Environment +.env +.env.local +.env.*.local diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..379c826 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Victoria Lackey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..84962e4 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# @3viky/mcp-common + +Shared utilities for MCP (Model Context Protocol) servers. + +## Installation + +```bash +npm install @3viky/mcp-common +``` + +## Usage + +```typescript +import { createVersionInfo, getMCPServiceDataDir } from '@3viky/mcp-common'; + +// Get version info +const version = createVersionInfo(import.meta.url); +console.log(version); + +// Get data directory +const dataDir = getMCPServiceDataDir('my-service'); +console.log(dataDir); +``` + +## API + +### Version Utilities + +- **`getPackageJsonPath(importMetaUrl: string): string`** - Get path to package.json +- **`createVersionInfo(importMetaUrl: string): VersionInfo`** - Create version info object from package.json + +### Data Directory Utilities + +- **`getMCPServicesCacheDir(): string`** - Get OS-specific cache directory for MCP services +- **`getMCPServiceDataDir(serviceName: string): string`** - Get data directory for specific MCP service + +## License + +MIT diff --git a/package.json b/package.json new file mode 100644 index 0000000..e41ee2a --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "@3viky/mcp-common", + "version": "1.0.0", + "description": "Shared utilities for MCP servers - versioning, common types, helpers", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "scripts": { + "build": "tsc", + "dev": "tsc --watch", + "clean": "rm -rf dist", + "typecheck": "tsc --noEmit", + "prepublishOnly": "npm run build" + }, + "keywords": [ + "mcp", + "model-context-protocol", + "utilities", + "versioning", + "claude-code" + ], + "author": "Victoria Lackey ", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/3viky/mcp-common.git" + }, + "bugs": { + "url": "https://github.com/3viky/mcp-common/issues" + }, + "homepage": "https://github.com/3viky/mcp-common#readme", + "devDependencies": { + "@types/node": "^22.10.1", + "typescript": "^5.7.2" + }, + "engines": { + "node": ">=18.0.0" + } +} diff --git a/src/data-directories.ts b/src/data-directories.ts new file mode 100644 index 0000000..f9804a2 --- /dev/null +++ b/src/data-directories.ts @@ -0,0 +1,33 @@ +import { homedir } from 'os'; +import { join } from 'path'; +import { platform } from 'process'; + +/** + * Get the OS-specific data directory for MCP services + */ +function getMCPDataRoot(): string { + switch (platform) { + case 'win32': + return join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'Claude', 'mcp'); + case 'darwin': + return join(homedir(), 'Library', 'Application Support', 'Claude', 'mcp'); + default: // Linux and others + return join(process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share'), 'claude', 'mcp'); + } +} + +/** + * Get the cache directory for MCP services + */ +export function getMCPServicesCacheDir(): string { + const root = getMCPDataRoot(); + return join(root, 'cache'); +} + +/** + * Get the data directory for a specific MCP service + */ +export function getMCPServiceDataDir(serviceName: string): string { + const root = getMCPDataRoot(); + return join(root, 'data', serviceName); +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..243e488 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,8 @@ +/** + * MCP Common Utilities + * Shared utilities for all MCP servers + */ + +export * from './version.js'; +export * from './data-directories.js'; +export * from './types.js'; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..8785dd6 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,36 @@ +/** + * Common types shared across MCP servers + */ + +/** + * Version information object + */ +export interface VersionInfo { + name: string; + version: string; + description: string; + author: string; + license: string; + error?: string; +} + +/** + * MCP tool result success + */ +export interface ToolResultSuccess { + content: Array<{ type: 'text'; text: string }>; + isError?: false; +} + +/** + * MCP tool result error + */ +export interface ToolResultError { + content: Array<{ type: 'text'; text: string }>; + isError: true; +} + +/** + * MCP tool result (union type) + */ +export type ToolResult = ToolResultSuccess | ToolResultError; diff --git a/src/version.ts b/src/version.ts new file mode 100644 index 0000000..490bba1 --- /dev/null +++ b/src/version.ts @@ -0,0 +1,38 @@ +import { readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + +/** + * Get the path to package.json for the calling module + */ +export function getPackageJsonPath(importMetaUrl: string): string { + const __dirname = dirname(fileURLToPath(importMetaUrl)); + return join(__dirname, '..', 'package.json'); +} + +/** + * Create version info object from package.json + */ +export function createVersionInfo(importMetaUrl: string) { + try { + const packagePath = getPackageJsonPath(importMetaUrl); + const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8')); + + return { + name: packageJson.name || 'unknown', + version: packageJson.version || '0.0.0', + description: packageJson.description || '', + author: packageJson.author || 'unknown', + license: packageJson.license || 'UNLICENSED', + }; + } catch (error) { + return { + name: 'unknown', + version: '0.0.0', + description: 'Failed to load version info', + author: 'unknown', + license: 'UNLICENSED', + error: error instanceof Error ? error.message : 'Unknown error', + }; + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2c27588 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "Node16", + "moduleResolution": "Node16", + "lib": ["ES2022"], + "outDir": "./dist", + "rootDir": "./src", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +}