naftiko: "1.0.0-alpha2" info: label: "Wordnik — Words" description: >- Words — cross-word discovery surface. 5 operations covering single random word, batched random words, full-text search, reverse-dictionary natural-language lookup, and the daily word-of-the-day. Lead operation: return a single random WordObject. Self-contained Naftiko capability covering one Wordnik business surface. tags: - Wordnik - Dictionary - Words created: "2026-05-29" modified: "2026-05-29" binds: - namespace: env keys: WORDNIK_API_KEY: WORDNIK_API_KEY capability: consumes: - type: http namespace: "wordnik-words" baseUri: "https://api.wordnik.com/v4" description: "Wordnik — Words business capability. Self-contained, no shared references." authentication: type: apikey key: api_key value: "{{env.WORDNIK_API_KEY}}" placement: query resources: - name: "words" path: "/words.json" operations: - name: "getRandomWord" method: GET description: "Return a single random WordObject." inputParameters: - { name: hasDictionaryDef, in: query, type: string, required: false, description: "Only return words with dictionary definitions." } - { name: includePartOfSpeech, in: query, type: string, required: false, description: "CSV part-of-speech values to include." } - { name: excludePartOfSpeech, in: query, type: string, required: false, description: "CSV part-of-speech values to exclude." } - { name: minCorpusCount, in: query, type: integer, required: false, description: "Minimum corpus frequency for terms." } - { name: maxCorpusCount, in: query, type: integer, required: false, description: "Maximum corpus frequency for terms." } - { name: minDictionaryCount, in: query, type: integer, required: false, description: "Minimum dictionary count." } - { name: maxDictionaryCount, in: query, type: integer, required: false, description: "Maximum dictionary count." } - { name: minLength, in: query, type: integer, required: false, description: "Minimum word length." } - { name: maxLength, in: query, type: integer, required: false, description: "Maximum word length." } outputRawFormat: json outputParameters: - { name: result, type: object, value: "$." } - name: "getRandomWords" method: GET description: "Return an array of random WordObjects." inputParameters: - { name: hasDictionaryDef, in: query, type: string, required: false, description: "Only return words with dictionary definitions." } - { name: includePartOfSpeech, in: query, type: string, required: false, description: "CSV part-of-speech values to include." } - { name: excludePartOfSpeech, in: query, type: string, required: false, description: "CSV part-of-speech values to exclude." } - { name: minCorpusCount, in: query, type: integer, required: false, description: "Minimum corpus frequency for terms." } - { name: maxCorpusCount, in: query, type: integer, required: false, description: "Maximum corpus frequency for terms." } - { name: minDictionaryCount, in: query, type: integer, required: false, description: "Minimum dictionary count." } - { name: maxDictionaryCount, in: query, type: integer, required: false, description: "Maximum dictionary count." } - { name: minLength, in: query, type: integer, required: false, description: "Minimum word length." } - { name: maxLength, in: query, type: integer, required: false, description: "Maximum word length." } - { name: sortBy, in: query, type: string, required: false, description: "Attribute to sort by." } - { name: sortOrder, in: query, type: string, required: false, description: "Sort direction." } - { name: limit, in: query, type: integer, required: false, description: "Maximum number of results to return." } outputRawFormat: json outputParameters: - { name: result, type: object, value: "$." } - name: "reverseDictionary" method: GET description: "Reverse dictionary search." inputParameters: - { name: query, in: query, type: string, required: true, description: "Search term." } - { name: findSenseForWord, in: query, type: string, required: false, description: "Restricts words and finds closest sense." } - { name: includeSourceDictionaries, in: query, type: string, required: false, description: "Include these source dictionaries." } - { name: excludeSourceDictionaries, in: query, type: string, required: false, description: "Exclude these source dictionaries." } - { name: includePartOfSpeech, in: query, type: string, required: false, description: "Include parts of speech." } - { name: excludePartOfSpeech, in: query, type: string, required: false, description: "Exclude parts of speech." } - { name: minCorpusCount, in: query, type: integer, required: false, description: "Minimum corpus frequency for terms." } - { name: maxCorpusCount, in: query, type: integer, required: false, description: "Maximum corpus frequency for terms." } - { name: minLength, in: query, type: integer, required: false, description: "Minimum word length." } - { name: maxLength, in: query, type: integer, required: false, description: "Maximum word length." } - { name: expandTerms, in: query, type: string, required: false, description: "Expand terms." } - { name: includeTags, in: query, type: string, required: false, description: "Return XML tags in response." } - { name: sortBy, in: query, type: string, required: false, description: "Attribute to sort by." } - { name: sortOrder, in: query, type: string, required: false, description: "Sort direction." } - { name: skip, in: query, type: string, required: false, description: "Results to skip." } - { name: limit, in: query, type: integer, required: false, description: "Maximum number of results to return." } outputRawFormat: json outputParameters: - { name: result, type: object, value: "$." } - name: "searchWords" method: GET description: "Search words." inputParameters: - { name: query, in: path, type: string, required: true, description: "Search query." } - { name: allowRegex, in: query, type: string, required: false, description: "Search term is a regular expression." } - { name: caseSensitive, in: query, type: string, required: false, description: "Search case sensitive." } - { name: includePartOfSpeech, in: query, type: string, required: false, description: "Include parts of speech." } - { name: excludePartOfSpeech, in: query, type: string, required: false, description: "Exclude parts of speech." } - { name: minCorpusCount, in: query, type: integer, required: false, description: "Minimum corpus frequency for terms." } - { name: maxCorpusCount, in: query, type: integer, required: false, description: "Maximum corpus frequency for terms." } - { name: minDictionaryCount, in: query, type: integer, required: false, description: "Minimum dictionary count." } - { name: maxDictionaryCount, in: query, type: integer, required: false, description: "Maximum dictionary count." } - { name: minLength, in: query, type: integer, required: false, description: "Minimum word length." } - { name: maxLength, in: query, type: integer, required: false, description: "Maximum word length." } - { name: skip, in: query, type: integer, required: false, description: "Results to skip." } - { name: limit, in: query, type: integer, required: false, description: "Maximum number of results to return." } outputRawFormat: json outputParameters: - { name: result, type: object, value: "$." } - name: "getWordOfTheDay" method: GET description: "Return the word of the day." inputParameters: - { name: date, in: query, type: string, required: false, description: "Fetches by date in yyyy-MM-dd." } outputRawFormat: json outputParameters: - { name: result, type: object, value: "$." } exposes: - type: rest namespace: "wordnik-words-rest" port: 8080 description: "REST adapter for Wordnik — Words. One Spectral-compliant resource per consumed operation, prefixed with /v1." resources: - path: "/v1/words/random-word" name: "random-word" description: "REST surface for a single random word." operations: - method: GET name: "getRandomWord" description: "Return a single random WordObject." call: "wordnik-words.getRandomWord" with: hasDictionaryDef: "rest.hasDictionaryDef" includePartOfSpeech: "rest.includePartOfSpeech" excludePartOfSpeech: "rest.excludePartOfSpeech" minCorpusCount: "rest.minCorpusCount" maxCorpusCount: "rest.maxCorpusCount" minDictionaryCount: "rest.minDictionaryCount" maxDictionaryCount: "rest.maxDictionaryCount" minLength: "rest.minLength" maxLength: "rest.maxLength" outputParameters: - { type: object, mapping: "$." } - path: "/v1/words/random-words" name: "random-words" description: "REST surface for random words batch." operations: - method: GET name: "getRandomWords" description: "Return an array of random WordObjects." call: "wordnik-words.getRandomWords" with: hasDictionaryDef: "rest.hasDictionaryDef" includePartOfSpeech: "rest.includePartOfSpeech" excludePartOfSpeech: "rest.excludePartOfSpeech" minCorpusCount: "rest.minCorpusCount" maxCorpusCount: "rest.maxCorpusCount" minDictionaryCount: "rest.minDictionaryCount" maxDictionaryCount: "rest.maxDictionaryCount" minLength: "rest.minLength" maxLength: "rest.maxLength" sortBy: "rest.sortBy" sortOrder: "rest.sortOrder" limit: "rest.limit" outputParameters: - { type: object, mapping: "$." } - path: "/v1/words/reverse-dictionary" name: "reverse-dictionary" description: "REST surface for reverse-dictionary search." operations: - method: GET name: "reverseDictionary" description: "Reverse dictionary search." call: "wordnik-words.reverseDictionary" with: query: "rest.query" findSenseForWord: "rest.findSenseForWord" includeSourceDictionaries: "rest.includeSourceDictionaries" excludeSourceDictionaries: "rest.excludeSourceDictionaries" includePartOfSpeech: "rest.includePartOfSpeech" excludePartOfSpeech: "rest.excludePartOfSpeech" minCorpusCount: "rest.minCorpusCount" maxCorpusCount: "rest.maxCorpusCount" minLength: "rest.minLength" maxLength: "rest.maxLength" expandTerms: "rest.expandTerms" includeTags: "rest.includeTags" sortBy: "rest.sortBy" sortOrder: "rest.sortOrder" skip: "rest.skip" limit: "rest.limit" outputParameters: - { type: object, mapping: "$." } - path: "/v1/words/search/{query}" name: "words-search" description: "REST surface for word search." operations: - method: GET name: "searchWords" description: "Search words." call: "wordnik-words.searchWords" with: query: "rest.query" allowRegex: "rest.allowRegex" caseSensitive: "rest.caseSensitive" includePartOfSpeech: "rest.includePartOfSpeech" excludePartOfSpeech: "rest.excludePartOfSpeech" minCorpusCount: "rest.minCorpusCount" maxCorpusCount: "rest.maxCorpusCount" minDictionaryCount: "rest.minDictionaryCount" maxDictionaryCount: "rest.maxDictionaryCount" minLength: "rest.minLength" maxLength: "rest.maxLength" skip: "rest.skip" limit: "rest.limit" outputParameters: - { type: object, mapping: "$." } - path: "/v1/words/word-of-the-day" name: "word-of-the-day" description: "REST surface for word of the day." operations: - method: GET name: "getWordOfTheDay" description: "Return the word of the day." call: "wordnik-words.getWordOfTheDay" with: date: "rest.date" outputParameters: - { type: object, mapping: "$." } - type: mcp namespace: "wordnik-words-mcp" port: 9090 transport: http description: "MCP adapter for Wordnik — Words. One tool per consumed operation, routed inline through this capability's consumes block." tools: - name: "get-random-word" description: "Return a single random WordObject." hints: { readOnly: true, destructive: false, idempotent: true } call: "wordnik-words.getRandomWord" with: hasDictionaryDef: "tools.hasDictionaryDef" includePartOfSpeech: "tools.includePartOfSpeech" excludePartOfSpeech: "tools.excludePartOfSpeech" minCorpusCount: "tools.minCorpusCount" maxCorpusCount: "tools.maxCorpusCount" minDictionaryCount: "tools.minDictionaryCount" maxDictionaryCount: "tools.maxDictionaryCount" minLength: "tools.minLength" maxLength: "tools.maxLength" outputParameters: - { type: object, mapping: "$." } - name: "get-random-words" description: "Return an array of random WordObjects." hints: { readOnly: true, destructive: false, idempotent: true } call: "wordnik-words.getRandomWords" with: hasDictionaryDef: "tools.hasDictionaryDef" includePartOfSpeech: "tools.includePartOfSpeech" excludePartOfSpeech: "tools.excludePartOfSpeech" minCorpusCount: "tools.minCorpusCount" maxCorpusCount: "tools.maxCorpusCount" minDictionaryCount: "tools.minDictionaryCount" maxDictionaryCount: "tools.maxDictionaryCount" minLength: "tools.minLength" maxLength: "tools.maxLength" sortBy: "tools.sortBy" sortOrder: "tools.sortOrder" limit: "tools.limit" outputParameters: - { type: object, mapping: "$." } - name: "search-reverse-dictionary" description: "Reverse dictionary search." hints: { readOnly: true, destructive: false, idempotent: true } call: "wordnik-words.reverseDictionary" with: query: "tools.query" findSenseForWord: "tools.findSenseForWord" includeSourceDictionaries: "tools.includeSourceDictionaries" excludeSourceDictionaries: "tools.excludeSourceDictionaries" includePartOfSpeech: "tools.includePartOfSpeech" excludePartOfSpeech: "tools.excludePartOfSpeech" minCorpusCount: "tools.minCorpusCount" maxCorpusCount: "tools.maxCorpusCount" minLength: "tools.minLength" maxLength: "tools.maxLength" expandTerms: "tools.expandTerms" includeTags: "tools.includeTags" sortBy: "tools.sortBy" sortOrder: "tools.sortOrder" skip: "tools.skip" limit: "tools.limit" outputParameters: - { type: object, mapping: "$." } - name: "search-words" description: "Search words." hints: { readOnly: true, destructive: false, idempotent: true } call: "wordnik-words.searchWords" with: query: "tools.query" allowRegex: "tools.allowRegex" caseSensitive: "tools.caseSensitive" includePartOfSpeech: "tools.includePartOfSpeech" excludePartOfSpeech: "tools.excludePartOfSpeech" minCorpusCount: "tools.minCorpusCount" maxCorpusCount: "tools.maxCorpusCount" minDictionaryCount: "tools.minDictionaryCount" maxDictionaryCount: "tools.maxDictionaryCount" minLength: "tools.minLength" maxLength: "tools.maxLength" skip: "tools.skip" limit: "tools.limit" outputParameters: - { type: object, mapping: "$." } - name: "get-word-of-the-day" description: "Return the word of the day." hints: { readOnly: true, destructive: false, idempotent: true } call: "wordnik-words.getWordOfTheDay" with: date: "tools.date" outputParameters: - { type: object, mapping: "$." }