naftiko: "1.0.0-alpha2" info: label: "Programming Quotes API — Quotes" description: >- Programming Quotes — Quotes. 8 operations. Lead operation: Programming Quotes Get Random Quote. Self-contained Naftiko capability covering one Programming Quotes business surface. tags: - Programming Quotes - Quotes - Open Source created: "2026-05-30" modified: "2026-05-30" binds: - namespace: env keys: PROGRAMMING_QUOTES_TOKEN: PROGRAMMING_QUOTES_TOKEN capability: # ── 1. Consumes — upstream Programming Quotes HTTP surface ──────────── consumes: - type: http namespace: "programming-quotes-quotes" baseUri: "https://programming-quotes-api.azurewebsites.net/api" description: "Programming Quotes API — Quotes business capability. Self-contained, no shared references." authentication: type: bearer token: "{{env.PROGRAMMING_QUOTES_TOKEN}}" resources: - name: "quotes-random" path: "/quotes/random" operations: - name: "getRandomQuote" method: GET description: "Return a single random programming quote from the corpus." outputRawFormat: json outputParameters: - name: result type: object value: "$." - name: "quotes" path: "/quotes" operations: - name: "listQuotes" method: GET description: "Return a paginated list of programming quotes, optionally filtered by author." inputParameters: - name: "page" in: query type: integer required: false description: "1-based page number." - name: "quotesPerPage" in: query type: integer required: false description: "Number of quotes per page." - name: "author" in: query type: string required: false description: "Filter by author name (underscores for spaces)." outputRawFormat: json outputParameters: - name: result type: object value: "$." - name: "createQuote" method: POST description: "Create a new programming quote (requires JWT)." inputParameters: - name: "body" in: body type: object required: true description: "Quote payload (author, text, optional source)." outputRawFormat: json outputParameters: - name: result type: object value: "$." - name: "quotes-by-id" path: "/quotes/{id}" operations: - name: "getQuoteById" method: GET description: "Fetch a single quote by its identifier." inputParameters: - name: "id" in: path type: string required: true description: "Quote identifier (MongoDB ObjectId)." outputRawFormat: json outputParameters: - name: result type: object value: "$." - name: "updateQuote" method: PUT description: "Update an existing quote's author, text, or source (requires JWT)." inputParameters: - name: "id" in: path type: string required: true description: "Quote identifier." - name: "body" in: body type: object required: true description: "Partial quote update payload." outputRawFormat: json outputParameters: - name: result type: object value: "$." - name: "deleteQuote" method: DELETE description: "Delete a quote by ID (requires JWT)." inputParameters: - name: "id" in: path type: string required: true description: "Quote identifier." outputRawFormat: json outputParameters: - name: result type: object value: "$." - name: "quotes-favorite" path: "/quotes/favorite/{id}" operations: - name: "addFavoriteQuote" method: POST description: "Mark a quote as a favorite for the authenticated user." inputParameters: - name: "id" in: path type: string required: true description: "Quote identifier." outputRawFormat: json outputParameters: - name: result type: object value: "$." - name: "quotes-vote" path: "/quotes/vote/{id}" operations: - name: "voteQuote" method: POST description: "Submit a 1-5 vote for a quote on behalf of the authenticated user." inputParameters: - name: "id" in: path type: string required: true description: "Quote identifier." - name: "body" in: body type: object required: true description: "Vote payload `{newVote: 1..5}`." outputRawFormat: json outputParameters: - name: result type: object value: "$." # ── 2. REST exposer ──────────────────────────────────────────────────── exposes: - type: rest namespace: "programming-quotes-quotes-rest" port: 8080 description: "REST adapter for Programming Quotes — Quotes. One Spectral-compliant resource per consumed operation, prefixed with /v1." resources: - path: "/v1/quotes/random" name: "quotes-random" description: "REST surface for the random quote endpoint." operations: - method: GET name: "getRandomQuote" description: "Return a single random programming quote." call: "programming-quotes-quotes.getRandomQuote" outputParameters: - type: object mapping: "$." - path: "/v1/quotes" name: "quotes" description: "REST surface for the quotes collection." operations: - method: GET name: "listQuotes" description: "Return a paginated list of programming quotes." call: "programming-quotes-quotes.listQuotes" with: "page": "rest.page" "quotesPerPage": "rest.quotesPerPage" "author": "rest.author" outputParameters: - type: object mapping: "$." - method: POST name: "createQuote" description: "Create a new programming quote." call: "programming-quotes-quotes.createQuote" with: "body": "rest.body" outputParameters: - type: object mapping: "$." - path: "/v1/quotes/{id}" name: "quotes-by-id" description: "REST surface for a single quote." operations: - method: GET name: "getQuoteById" description: "Fetch a single quote by identifier." call: "programming-quotes-quotes.getQuoteById" with: "id": "rest.id" outputParameters: - type: object mapping: "$." - method: PUT name: "updateQuote" description: "Update an existing quote." call: "programming-quotes-quotes.updateQuote" with: "id": "rest.id" "body": "rest.body" outputParameters: - type: object mapping: "$." - method: DELETE name: "deleteQuote" description: "Delete a quote." call: "programming-quotes-quotes.deleteQuote" with: "id": "rest.id" outputParameters: - type: object mapping: "$." - path: "/v1/quotes/favorite/{id}" name: "quotes-favorite" description: "REST surface for favoriting a quote." operations: - method: POST name: "addFavoriteQuote" description: "Mark a quote as favorite." call: "programming-quotes-quotes.addFavoriteQuote" with: "id": "rest.id" outputParameters: - type: object mapping: "$." - path: "/v1/quotes/vote/{id}" name: "quotes-vote" description: "REST surface for voting on a quote." operations: - method: POST name: "voteQuote" description: "Submit a 1-5 vote for a quote." call: "programming-quotes-quotes.voteQuote" with: "id": "rest.id" "body": "rest.body" outputParameters: - type: object mapping: "$." # ── 3. MCP exposer ────────────────────────────────────────────────── - type: mcp namespace: "programming-quotes-quotes-mcp" port: 9090 transport: http description: "MCP adapter for Programming Quotes — Quotes. One tool per consumed operation, routed inline through this capability's consumes block." tools: - name: "get-random-quote" description: "Return a single random programming quote." hints: readOnly: true destructive: false idempotent: true call: "programming-quotes-quotes.getRandomQuote" outputParameters: - type: object mapping: "$." - name: "list-quotes" description: "Return a paginated list of programming quotes." hints: readOnly: true destructive: false idempotent: true call: "programming-quotes-quotes.listQuotes" with: "page": "tools.page" "quotesPerPage": "tools.quotesPerPage" "author": "tools.author" outputParameters: - type: object mapping: "$." - name: "create-quote" description: "Create a new programming quote (requires JWT)." hints: readOnly: false destructive: false idempotent: false call: "programming-quotes-quotes.createQuote" with: "body": "tools.body" outputParameters: - type: object mapping: "$." - name: "get-quote-by-id" description: "Fetch a single quote by identifier." hints: readOnly: true destructive: false idempotent: true call: "programming-quotes-quotes.getQuoteById" with: "id": "tools.id" outputParameters: - type: object mapping: "$." - name: "update-quote" description: "Update an existing quote (requires JWT)." hints: readOnly: false destructive: false idempotent: true call: "programming-quotes-quotes.updateQuote" with: "id": "tools.id" "body": "tools.body" outputParameters: - type: object mapping: "$." - name: "delete-quote" description: "Delete a quote by ID (requires JWT)." hints: readOnly: false destructive: true idempotent: true call: "programming-quotes-quotes.deleteQuote" with: "id": "tools.id" outputParameters: - type: object mapping: "$." - name: "add-favorite-quote" description: "Mark a quote as a favorite for the authenticated user." hints: readOnly: false destructive: false idempotent: true call: "programming-quotes-quotes.addFavoriteQuote" with: "id": "tools.id" outputParameters: - type: object mapping: "$." - name: "vote-quote" description: "Submit a 1-5 vote for a quote (requires JWT)." hints: readOnly: false destructive: false idempotent: false call: "programming-quotes-quotes.voteQuote" with: "id": "tools.id" "body": "tools.body" outputParameters: - type: object mapping: "$."