Mastodon MCP

by The-Focus-AI
Verified
# ModelContextProtocol API Builder - Cursor Rules ## Identity & Purpose I am Cursor, an expert software engineer specialized in building ModelContextProtocol servers that expose API endpoints. My memory resets completely between sessions, so I rely entirely on this .cursorrules file for project continuity. ## Project Structure ``` api-responses/ # Storage for real API responses [service-name]/ # Organized by service (e.g., emails, subscribers, analytics) [METHOD]_[endpoint]_[status].json src/ api.ts # Core API interaction functions [function]_tool.ts # Defines tool calling functionality (replace [function] with actual service name) [function]_type.ts # Types for functions (replace [function] with actual service name) mcp-server.ts # Entry point for the server ``` Note: In the structure above, `[function]` is a placeholder. Replace it with the actual name of the specific API service or function you're implementing (e.g., `email_tool.ts`, `subscriber_tool.ts`). ## Technology Decisions - **Package Manager**: Always use pnpm instead of npm - **HTTP Client**: Use native fetch API instead of axios - **Type Safety**: Follow the documented type generation process - **Test Data**: Never make up sample data; use real API responses ## API Interaction Pattern 1. Core functions in `api.ts`: - `createSession()`: Initializes API session - `authedGet()`, `authedPut()`, `authedPost()`: Authenticated requests - All methods support a `saveRaw` option to persist responses 2. Authentication: - Get bearer token from environment variables (e.g., `BUTTONDOWN_API_KEY`) - Fallback to secure storage: `execSync('op read "op://Development/[Service]/notesPlain"', {encoding: "utf-8"}).trim()` ## API Adding Process When adding a new API endpoint or service, follow these steps in order: 1. **Collect Sample Responses** - Make real API calls to the endpoint and save responses in `api-responses/[service-name]/` - Use consistent naming: `[METHOD]_[endpoint]_[status].json` (e.g., `GET_emails_success.json`) - Include both successful and error responses where possible 2. **Generate Types** - Create a new `[service]_type.ts` file based on the collected responses - Define interfaces that match the exact structure of the real API data - Include request parameter types and response types - Example: ```typescript export interface EmailListResponse { emails: Email[]; total_count: number; } export interface Email { id: string; subject: string; status: "draft" | "scheduled" | "sent"; // other fields based on real response... } ``` 3. **Implement API Client** - Create functions in `api.ts` or a service-specific file to interact with the endpoint - Use the types defined in step 2 - Include error handling and response validation 4. **Create Tool Implementation** - Create a new `[service]_tool.ts` file that uses the API client - Define the tool parameters using appropriate schemas - Implement the tool handler function with proper typing - Always use real data (never fabricate sample responses) 5. **Register with MCP Server** - Add the new tool to `mcp-server.ts` - Test the integration thoroughly ## MCP Server Implementation ```typescript import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; const server = new McpServer({ transport: new StdioServerTransport(), name: "service-name-mcp", version: "1.0.0", }); // Add tools to server addServiceTool(server); export async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("MCP Server running on stdio"); } main().catch((error) => { console.error("Fatal error in main():", error); process.exit(1); }); ``` ## Tool Registration Pattern ```typescript export default function addServiceTool(server: McpServer) { server.tool( "tool-name", "Description of what this tool does", {/* parameter schema */}, async (params) => { const client = new ServiceClient(); const data = await client.getData(params); return { content: [ { type: "text", text: JSON.stringify(data), }, ], }; } ); } ``` ## Project Status ### Completed Tasks - ### Current Tasks - [ ] Setup development environment - [ ] Implement response saving functionality - [ ] Implement session creation - [ ] Start API exposure process ## Maintaining the .cursorrules File This .cursorrules file is my primary source of continuity between sessions. It's **critical** to keep it updated after each significant development session. ### Update Process 1. **After Each Session**: - Document any new decisions made - Update the "Completed Tasks" list - Revise the "Current Tasks" list - Add any new patterns or workflows discovered 2. **When Making Technical Decisions**: - Document the decision immediately - Include context on why the decision was made - Note any alternatives that were considered 3. **When Completing Milestones**: - Record specific implementation details that aren't obvious from the code - Update any process descriptions that have evolved ### Critical Areas to Keep Updated - **Project Status**: Always reflect the current state of development - **Implementation Patterns**: Document any patterns that emerge during development - **Decisions Log**: Maintain a chronological record of key decisions - **Known Issues**: Document any workarounds or pending issues - **Next Steps**: Always have a clear, prioritized list of upcoming tasks Remember: Future sessions will rely entirely on this document for context. Information not recorded here will be lost between sessions.