diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e9aaca6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,76 @@ +# make-mcp-server + +TypeScript MCP server exposing Make.com on-demand scenarios as callable tools for AI assistants. Stdio transport, no HTTP. + +## Project map + +- `src/index.ts` — server init, MCP handler registration, env var validation +- `src/make.ts` — Make API client (`Make` + `Scenarios` classes) +- `src/utils.ts` — `remap()` schema converter, `MakeError`, `createMakeError` +- `src/types.ts` — TypeScript interfaces +- `test/server.spec.ts` — tests; fixtures in `test/mocks/` + +## Stack + +TypeScript, ESNext modules → `build/`. MCP SDK (`@modelcontextprotocol/sdk`). Jest + `jest-fetch-mock`. + + + +| Command | What it does | +|---|---| +| `npm run build` | tsc + chmod 755 on entry point | +| `npm test` | Run Jest tests | +| `npm run inspector` | Launch MCP inspector UI against `build/index.js` | + + + + +Three required env vars (process exits 1 if missing): +- `MAKE_API_KEY` — used as `Token ` (not Bearer) +- `MAKE_ZONE` — API base hostname (e.g. `eu2.make.com`) +- `MAKE_TEAM` — integer team ID + + + + +No static tool registry. On every `tools/list` request the server queries Make API for scenarios, filters to `scheduling.type === 'on-demand'`, fetches input interfaces in parallel, converts via `remap()` to JSON Schema. Tool names: `run_scenario_{id}`. + +Run calls use `{ data: , responsive: true }` for synchronous execution. + + + + +URL assembly: `/`-prefixed → `https://${MAKE_ZONE}/api/v2` prepended; `//`-prefixed → `https:` prepended; absolute URLs pass through. + +Every request gets `user-agent: MakeMCPServer/0.1.0` and `authorization: Token ` headers. + + + + +`remap()` recursively converts Make `Input[]` → JSON Schema. Always called with synthetic wrapper `{ type: 'collection', spec: Input[] }`, so top-level is always `type: object`. See `src/utils.ts` for the type mapping. + + + + +Error handling asymmetry: +- `CallToolRequest` handler wraps `run()` in try/catch — MakeErrors → MCP `isError: true` +- `ListToolsRequest` handler has **no try/catch** — errors propagate unhandled +- HTTP status >= 400 → `createMakeError()` tries JSON parse for `detail`/`message`/`suberrors`; falls back to `statusText` + + + + +- All HTTP mocked via `jest-fetch-mock` — `enableFetchMocks()` at module level, `fetchMock.resetMocks()` in `beforeEach` +- Mock pattern: `fetchMock.mockResponse(req => { if (req.url !== expected) throw ...; return Promise.resolve({ body, headers }) })` +- Error tests: try/catch with `instanceof MakeError` guard, field-by-field assertions +- `jest.config.ts`: `moduleNameMapper` strips `.js` extensions (ESM compat) + + + + +Published as `@makehq/mcp-server`, bin entry `mcp-server-make`. Registry configs: `smithery.yaml`, `glama.json`. `Dockerfile` for containerized deployment. + + +## Keeping AGENTS.md current + +When your changes alter anything described in this file — project map, env vars, architectural patterns, API client behavior, error handling, test patterns, or packaging — notify the user that AGENTS.md should be updated and suggest the specific edit. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md