# Development Guide ## Prerequisites - Node.js 18 or higher - Linux operating system (for full functionality) - Basic understanding of procfs and Linux system internals - TypeScript knowledge ## Setup Development Environment ```bash # Clone the repository git clone https://github.com/cameronrye/activitypub-mcp.git cd activitypub-mcp/mcp-proc # Install dependencies npm install # Build the project npm run build ``` ## Project Structure ``` mcp-proc/ ├── src/ │ ├── lib/ # Core library code │ │ ├── procfs-reader.ts # ProcFS reading logic │ │ └── procfs-writer.ts # ProcFS writing logic │ ├── types/ # Type definitions │ │ ├── procfs.ts # ProcFS types │ │ ├── mcp.ts # MCP protocol types │ │ └── schemas.ts # Zod validation schemas │ ├── server.ts # MCP JSON-RPC server │ ├── server-sse.ts # HTTP/SSE server │ ├── cli.ts # CLI for JSON-RPC server │ ├── cli-sse.ts # CLI for HTTP server │ └── index.ts # Main exports ├── examples/ # Usage examples ├── scripts/ # Build and setup scripts ├── tests/ # Test files └── docs/ # Documentation ``` ## Development Workflow ### Running in Development Mode ```bash # Watch mode with hot reload npm run dev # For HTTP/SSE server npm run start:sse ``` ### Building ```bash # Compile TypeScript npm run build # Clean build rm -rf dist/ && npm run build ``` ### Testing ```bash # Run all tests npm test # Watch mode npm run test:watch # Coverage report npm run test:coverage ``` ### Linting and Formatting ```bash # Check code style npm run lint # Format code npm run format ``` ## Adding New Features ### Adding a New ProcFS Reader 1. Add the method to `src/lib/procfs-reader.ts`: ```typescript async getNewMetric(): Promise { const content = await this.readRaw('path/to/file'); // Parse content return parsedData; } ``` 2. Add the type definition in `src/types/procfs.ts`: ```typescript export interface NewMetricType { field1: string; field2: number; } ``` 3. Add validation schema in `src/types/schemas.ts`: ```typescript export const NewMetricRequestSchema = z.object({ param: z.string(), }); ``` 4. Add tool definition in `src/server.ts`: ```typescript { name: 'get_new_metric', description: 'Get new metric', inputSchema: { type: 'object', properties: { param: { type: 'string' } } } } ``` 5. Add HTTP endpoint in `src/server-sse.ts`: ```typescript this.app.get('/api/new-metric', async (req, res) => { try { const data = await this.reader.getNewMetric(); res.json({ success: true, data }); } catch (error) { res.status(500).json({ success: false, error: (error as Error).message }); } }); ``` ### Adding Tests Create test file in `tests/`: ```typescript import { ProcFSReader } from '../src/lib/procfs-reader'; describe('ProcFSReader', () => { let reader: ProcFSReader; beforeEach(() => { reader = new ProcFSReader(); }); test('should read CPU info', async () => { const info = await reader.getCPUInfo(); expect(info).toHaveProperty('model'); expect(info).toHaveProperty('cores'); }); }); ``` ## Code Style Guidelines - Use TypeScript strict mode - Follow ESLint rules - Use Prettier for formatting - Add JSDoc comments for public APIs - Use async/await for asynchronous code - Handle errors gracefully - Validate inputs with Zod schemas ## Debugging ### Debug MCP Server ```bash # With debug output DEBUG=* npm start ``` ### Debug HTTP Server ```bash # Check server logs npm run start:sse # Test endpoints curl http://localhost:3000/health ``` ### Using VS Code Debugger Create `.vscode/launch.json`: ```json { "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Debug Server", "program": "${workspaceFolder}/src/cli.ts", "preLaunchTask": "npm: build", "outFiles": ["${workspaceFolder}/dist/**/*.js"] } ] } ``` ## Common Issues ### Permission Errors Some operations require elevated permissions: ```bash # Run with sudo (not recommended for development) sudo npm start # Better: Use capabilities sudo setcap cap_sys_nice,cap_sys_admin+ep $(which node) ``` ### TypeScript Errors ```bash # Clean and rebuild rm -rf dist/ node_modules/ npm install npm run build ``` ### Port Already in Use ```bash # Change port PORT=8080 npm run start:sse # Kill process using port 3000 lsof -ti:3000 | xargs kill -9 ``` ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests 5. Run linting and tests 6. Submit a pull request ### Commit Message Format ``` type(scope): subject body footer ``` Types: - `feat`: New feature - `fix`: Bug fix - `docs`: Documentation - `style`: Formatting - `refactor`: Code restructuring - `test`: Adding tests - `chore`: Maintenance Example: ``` feat(procfs): add disk temperature reading Add support for reading disk temperature from /sys/class/hwmon. Includes new getDiskTemperature() method in ProcFSReader. Closes #123 ``` ## Release Process 1. Update version in `package.json` 2. Update `CHANGELOG.md` 3. Run tests: `npm test` 4. Build: `npm run build` 5. Commit changes 6. Create git tag: `git tag v1.0.0` 7. Push: `git push --follow-tags` 8. Publish: `npm publish` Or use the release script: ```bash ./scripts/release.sh 1.0.0 ``` ## Resources - [MCP Specification](https://modelcontextprotocol.io) - [TypeScript Documentation](https://www.typescriptlang.org/docs/) - [Express.js Guide](https://expressjs.com/en/guide/routing.html) - [Zod Documentation](https://zod.dev/) - [Jest Testing Framework](https://jestjs.io/)