Spaces:
Sleeping
Sleeping
`feat: Add optional authentication support and related changes`
Browse files- .gitignore +1 -0
- CHANGELOG.md +21 -0
- LICENSE +0 -21
- README.md +39 -0
- coding-robot-test.png +0 -0
- example-mcp.json +4 -0
- generate-mcp-config.js +29 -0
- package.json +1 -1
- pollinations-mcp-server.js +24 -5
- src/services/audioService.js +15 -2
- src/services/imageService.js +18 -4
- src/services/textService.js +15 -2
.gitignore
CHANGED
|
@@ -66,6 +66,7 @@ pids
|
|
| 66 |
.env.test.local
|
| 67 |
.env.production.local
|
| 68 |
.env.local
|
|
|
|
| 69 |
|
| 70 |
# parcel-bundler cache
|
| 71 |
.cache
|
|
|
|
| 66 |
.env.test.local
|
| 67 |
.env.production.local
|
| 68 |
.env.local
|
| 69 |
+
mcp.json
|
| 70 |
|
| 71 |
# parcel-bundler cache
|
| 72 |
.cache
|
CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to the MCPollinations will be documented in this file.
|
|
| 5 |
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
| 6 |
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
## [1.0.7] - `2025-04-08`
|
| 9 |
|
| 10 |
### Added
|
|
|
|
| 5 |
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
| 6 |
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
| 7 |
|
| 8 |
+
## [1.1.2] - `2025-07-25`
|
| 9 |
+
|
| 10 |
+
### Added
|
| 11 |
+
- **Optional Authentication Support**: Added support for optional `token` and `referrer` parameters to access enhanced Pollinations API features
|
| 12 |
+
- Environment variable support: `POLLINATIONS_TOKEN` and `POLLINATIONS_REFERRER`
|
| 13 |
+
- MCP configuration file support with new `auth` section
|
| 14 |
+
- Authorization header (`Bearer token`) and Referer header support in all API requests
|
| 15 |
+
- Backward compatible - free tier continues to work without authentication
|
| 16 |
+
- Enhanced MCP configuration generator with authentication prompts
|
| 17 |
+
- Updated example-mcp.json to include auth section template
|
| 18 |
+
- Comprehensive documentation updates for authentication setup
|
| 19 |
+
- **Windows Path Guidance**: Added documentation for Windows users to use absolute paths for reliable file saving
|
| 20 |
+
|
| 21 |
+
### Changed
|
| 22 |
+
- All service functions now accept optional `authConfig` parameter
|
| 23 |
+
- MCP server now reads and passes authentication configuration to services
|
| 24 |
+
- Configuration generator includes new authentication configuration section
|
| 25 |
+
|
| 26 |
+
### Fixed
|
| 27 |
+
- Improved file path handling documentation for Windows compatibility
|
| 28 |
+
|
| 29 |
## [1.0.7] - `2025-04-08`
|
| 30 |
|
| 31 |
### Added
|
LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
| 1 |
-
MIT License
|
| 2 |
-
|
| 3 |
-
Copyright (c) 2025 Pink Pixel
|
| 4 |
-
|
| 5 |
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
-
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
-
in the Software without restriction, including without limitation the rights
|
| 8 |
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
-
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
-
furnished to do so, subject to the following conditions:
|
| 11 |
-
|
| 12 |
-
The above copyright notice and this permission notice shall be included in all
|
| 13 |
-
copies or substantial portions of the Software.
|
| 14 |
-
|
| 15 |
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
-
SOFTWARE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
README.md
CHANGED
|
@@ -82,6 +82,8 @@ node /path/to/MCPollinations/generate-mcp-config.js
|
|
| 82 |
|
| 83 |
2. Follow the prompts to customize your configuration or use the defaults.
|
| 84 |
- Set custom output and temporary directories (defaults to relative paths for portability)
|
|
|
|
|
|
|
| 85 |
- Configure default parameters for image generation (with a list of available models, dimensions, etc.)
|
| 86 |
- Configure default parameters for text generation (with a list of available models)
|
| 87 |
- Configure default parameters for audio generation (voice)
|
|
@@ -94,6 +96,41 @@ After integration, you can use commands like:
|
|
| 94 |
|
| 95 |
"Generate an image of a sunset over the ocean using MCPollinations"
|
| 96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
## Troubleshooting
|
| 99 |
|
|
@@ -193,6 +230,8 @@ When using Claude or another application with the MCP server:
|
|
| 193 |
|
| 194 |
3. If Claude Desktop launches the MCP server automatically, images will be saved in Claude Desktop's working directory (typically in an application data folder).
|
| 195 |
|
|
|
|
|
|
|
| 196 |
### Finding Your Generated Images
|
| 197 |
|
| 198 |
- The response from Claude after generating an image includes the full file path where the image was saved
|
|
|
|
| 82 |
|
| 83 |
2. Follow the prompts to customize your configuration or use the defaults.
|
| 84 |
- Set custom output and temporary directories (defaults to relative paths for portability)
|
| 85 |
+
- **Windows users**: Consider using absolute paths (e.g., `C:\Users\YourName\Pictures\MCPollinations`) for more reliable file saving
|
| 86 |
+
- **Configure optional authentication** (token and referrer for enhanced access)
|
| 87 |
- Configure default parameters for image generation (with a list of available models, dimensions, etc.)
|
| 88 |
- Configure default parameters for text generation (with a list of available models)
|
| 89 |
- Configure default parameters for audio generation (voice)
|
|
|
|
| 96 |
|
| 97 |
"Generate an image of a sunset over the ocean using MCPollinations"
|
| 98 |
|
| 99 |
+
## Authentication (Optional)
|
| 100 |
+
|
| 101 |
+
MCPollinations supports optional authentication to provide access to more models and better rate limits. The server works perfectly without authentication (free tier), but users with API tokens can get enhanced access.
|
| 102 |
+
|
| 103 |
+
### Configuration Methods
|
| 104 |
+
|
| 105 |
+
**Method 1: Environment Variables (Recommended for security)**
|
| 106 |
+
```bash
|
| 107 |
+
# Set environment variables before running the server
|
| 108 |
+
export POLLINATIONS_TOKEN="your-api-token"
|
| 109 |
+
export POLLINATIONS_REFERRER="https://your-domain.com"
|
| 110 |
+
|
| 111 |
+
# Then run the server
|
| 112 |
+
npx @pinkpixel/mcpollinations
|
| 113 |
+
```
|
| 114 |
+
|
| 115 |
+
**Method 2: MCP Configuration File**
|
| 116 |
+
When generating your MCP configuration, you'll be prompted for optional authentication settings:
|
| 117 |
+
```json
|
| 118 |
+
{
|
| 119 |
+
"mcpollinations": {
|
| 120 |
+
"auth": {
|
| 121 |
+
"token": "your-api-token",
|
| 122 |
+
"referrer": "https://your-domain.com"
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
```
|
| 127 |
+
|
| 128 |
+
### Authentication Parameters
|
| 129 |
+
|
| 130 |
+
- **`token`** (optional): Your Pollinations API token for enhanced access
|
| 131 |
+
- **`referrer`** (optional): Your domain/application referrer URL
|
| 132 |
+
|
| 133 |
+
Both parameters are completely optional. Leave them empty or unset to use the free tier.
|
| 134 |
|
| 135 |
## Troubleshooting
|
| 136 |
|
|
|
|
| 230 |
|
| 231 |
3. If Claude Desktop launches the MCP server automatically, images will be saved in Claude Desktop's working directory (typically in an application data folder).
|
| 232 |
|
| 233 |
+
**💡 Windows Users**: For reliable file saving on Windows, use absolute paths in your MCP configuration instead of relative paths (e.g., `C:\Users\YourName\Pictures\MCPollinations` instead of `./mcpollinations-output`). Relative paths may not resolve as expected depending on the working directory context.
|
| 234 |
+
|
| 235 |
### Finding Your Generated Images
|
| 236 |
|
| 237 |
- The response from Claude after generating an image includes the full file path where the image was saved
|
coding-robot-test.png
ADDED
|
example-mcp.json
CHANGED
|
@@ -8,6 +8,10 @@
|
|
| 8 |
"resources": {
|
| 9 |
"output_dir": "./mcpollinations-output"
|
| 10 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
"default_params": {
|
| 12 |
"image": {
|
| 13 |
"model": "flux",
|
|
|
|
| 8 |
"resources": {
|
| 9 |
"output_dir": "./mcpollinations-output"
|
| 10 |
},
|
| 11 |
+
"auth": {
|
| 12 |
+
"token": "",
|
| 13 |
+
"referrer": ""
|
| 14 |
+
},
|
| 15 |
"default_params": {
|
| 16 |
"image": {
|
| 17 |
"model": "flux",
|
generate-mcp-config.js
CHANGED
|
@@ -19,6 +19,10 @@ const defaultConfig = {
|
|
| 19 |
"resources": {
|
| 20 |
"output_dir": "./mcpollinations-output",
|
| 21 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
"default_params": {
|
| 23 |
"image": {
|
| 24 |
"model": "flux",
|
|
@@ -93,6 +97,31 @@ async function generateMcpConfig() {
|
|
| 93 |
config[configKey].resources.output_dir = outputDir;
|
| 94 |
}
|
| 95 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
// Default parameters customization
|
| 97 |
console.log('\nDefault Parameters:');
|
| 98 |
|
|
|
|
| 19 |
"resources": {
|
| 20 |
"output_dir": "./mcpollinations-output",
|
| 21 |
},
|
| 22 |
+
"auth": {
|
| 23 |
+
"token": "",
|
| 24 |
+
"referrer": ""
|
| 25 |
+
},
|
| 26 |
"default_params": {
|
| 27 |
"image": {
|
| 28 |
"model": "flux",
|
|
|
|
| 97 |
config[configKey].resources.output_dir = outputDir;
|
| 98 |
}
|
| 99 |
|
| 100 |
+
// Authentication configuration
|
| 101 |
+
console.log('\nAuthentication Configuration (Optional):');
|
| 102 |
+
console.log('These settings are optional and provide access to more models and better rate limits.');
|
| 103 |
+
console.log('Leave empty to use the free tier.');
|
| 104 |
+
console.log('Note: You can also set these via environment variables POLLINATIONS_TOKEN and POLLINATIONS_REFERRER');
|
| 105 |
+
|
| 106 |
+
const authToken = await prompt('API Token (optional): ');
|
| 107 |
+
if (authToken && authToken.trim()) {
|
| 108 |
+
config[configKey].auth.token = authToken.trim();
|
| 109 |
+
} else {
|
| 110 |
+
delete config[configKey].auth.token;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
const authReferrer = await prompt('Referrer URL (optional): ');
|
| 114 |
+
if (authReferrer && authReferrer.trim()) {
|
| 115 |
+
config[configKey].auth.referrer = authReferrer.trim();
|
| 116 |
+
} else {
|
| 117 |
+
delete config[configKey].auth.referrer;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
// Remove auth section entirely if both fields are empty
|
| 121 |
+
if (!config[configKey].auth.token && !config[configKey].auth.referrer) {
|
| 122 |
+
delete config[configKey].auth;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
// Default parameters customization
|
| 126 |
console.log('\nDefault Parameters:');
|
| 127 |
|
package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
{
|
| 2 |
"name": "@pinkpixel/mcpollinations",
|
| 3 |
-
"version": "1.
|
| 4 |
"description": "Model Context Protocol (MCP) server for the Pollinations APIs with image saving functionality.",
|
| 5 |
"type": "module",
|
| 6 |
"bin": {
|
|
|
|
| 1 |
{
|
| 2 |
"name": "@pinkpixel/mcpollinations",
|
| 3 |
+
"version": "1.1.2",
|
| 4 |
"description": "Model Context Protocol (MCP) server for the Pollinations APIs with image saving functionality.",
|
| 5 |
"type": "module",
|
| 6 |
"bin": {
|
pollinations-mcp-server.js
CHANGED
|
@@ -102,11 +102,30 @@ import player from 'play-sound';
|
|
| 102 |
// Create audio player instance
|
| 103 |
const audioPlayer = player({});
|
| 104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
// Create the server instance
|
| 106 |
const server = new Server(
|
| 107 |
{
|
| 108 |
name: '@pinkpixel/mcpollinations',
|
| 109 |
-
version: '1.
|
| 110 |
},
|
| 111 |
{
|
| 112 |
capabilities: {
|
|
@@ -135,7 +154,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
| 135 |
if (name === 'generateImageUrl') {
|
| 136 |
try {
|
| 137 |
const { prompt, model = 'flux', seed, width = 1024, height = 1024, enhance = true, safe = false } = args;
|
| 138 |
-
const result = await generateImageUrl(prompt, model, seed, width, height, enhance, safe);
|
| 139 |
return {
|
| 140 |
content: [
|
| 141 |
{ type: 'text', text: JSON.stringify(result, null, 2) }
|
|
@@ -152,7 +171,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
| 152 |
} else if (name === 'generateImage') {
|
| 153 |
try {
|
| 154 |
const { prompt, model = 'flux', seed, width = 1024, height = 1024, enhance = true, safe = false, outputPath = './mcpollinations-output', fileName = '', format = 'png' } = args;
|
| 155 |
-
const result = await generateImage(prompt, model, seed, width, height, enhance, safe, outputPath, fileName, format);
|
| 156 |
|
| 157 |
// Prepare the response content
|
| 158 |
const content = [
|
|
@@ -186,7 +205,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
| 186 |
} else if (name === 'respondAudio') {
|
| 187 |
try {
|
| 188 |
const { prompt, voice, seed, voiceInstructions } = args;
|
| 189 |
-
const result = await respondAudio(prompt, voice, seed, voiceInstructions);
|
| 190 |
|
| 191 |
// Save audio to a temporary file
|
| 192 |
const tempDir = os.tmpdir();
|
|
@@ -274,7 +293,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
| 274 |
} else if (name === 'respondText') {
|
| 275 |
try {
|
| 276 |
const { prompt, model = "openai", seed } = args;
|
| 277 |
-
const result = await respondText(prompt, model, seed);
|
| 278 |
return {
|
| 279 |
content: [
|
| 280 |
{ type: 'text', text: result }
|
|
|
|
| 102 |
// Create audio player instance
|
| 103 |
const audioPlayer = player({});
|
| 104 |
|
| 105 |
+
// Read authentication configuration from environment variables
|
| 106 |
+
// These are optional - the server works without them (free tier)
|
| 107 |
+
const authConfig = {
|
| 108 |
+
token: process.env.POLLINATIONS_TOKEN || null,
|
| 109 |
+
referrer: process.env.POLLINATIONS_REFERRER || null
|
| 110 |
+
};
|
| 111 |
+
|
| 112 |
+
// Only create authConfig object if we have at least one auth parameter
|
| 113 |
+
const finalAuthConfig = (authConfig.token || authConfig.referrer) ? authConfig : null;
|
| 114 |
+
|
| 115 |
+
if (finalAuthConfig) {
|
| 116 |
+
console.error('Auth configuration loaded:', {
|
| 117 |
+
hasToken: !!finalAuthConfig.token,
|
| 118 |
+
hasReferrer: !!finalAuthConfig.referrer
|
| 119 |
+
});
|
| 120 |
+
} else {
|
| 121 |
+
console.error('Running in free tier mode (no auth configuration)');
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
// Create the server instance
|
| 125 |
const server = new Server(
|
| 126 |
{
|
| 127 |
name: '@pinkpixel/mcpollinations',
|
| 128 |
+
version: '1.1.2',
|
| 129 |
},
|
| 130 |
{
|
| 131 |
capabilities: {
|
|
|
|
| 154 |
if (name === 'generateImageUrl') {
|
| 155 |
try {
|
| 156 |
const { prompt, model = 'flux', seed, width = 1024, height = 1024, enhance = true, safe = false } = args;
|
| 157 |
+
const result = await generateImageUrl(prompt, model, seed, width, height, enhance, safe, finalAuthConfig);
|
| 158 |
return {
|
| 159 |
content: [
|
| 160 |
{ type: 'text', text: JSON.stringify(result, null, 2) }
|
|
|
|
| 171 |
} else if (name === 'generateImage') {
|
| 172 |
try {
|
| 173 |
const { prompt, model = 'flux', seed, width = 1024, height = 1024, enhance = true, safe = false, outputPath = './mcpollinations-output', fileName = '', format = 'png' } = args;
|
| 174 |
+
const result = await generateImage(prompt, model, seed, width, height, enhance, safe, outputPath, fileName, format, finalAuthConfig);
|
| 175 |
|
| 176 |
// Prepare the response content
|
| 177 |
const content = [
|
|
|
|
| 205 |
} else if (name === 'respondAudio') {
|
| 206 |
try {
|
| 207 |
const { prompt, voice, seed, voiceInstructions } = args;
|
| 208 |
+
const result = await respondAudio(prompt, voice, seed, voiceInstructions, finalAuthConfig);
|
| 209 |
|
| 210 |
// Save audio to a temporary file
|
| 211 |
const tempDir = os.tmpdir();
|
|
|
|
| 293 |
} else if (name === 'respondText') {
|
| 294 |
try {
|
| 295 |
const { prompt, model = "openai", seed } = args;
|
| 296 |
+
const result = await respondText(prompt, model, seed, finalAuthConfig);
|
| 297 |
return {
|
| 298 |
content: [
|
| 299 |
{ type: 'text', text: result }
|
src/services/audioService.js
CHANGED
|
@@ -11,9 +11,10 @@
|
|
| 11 |
* @param {string} [voice="alloy"] - Voice to use for audio generation. Available options: "alloy", "echo", "fable", "onyx", "nova", "shimmer", "coral", "verse", "ballad", "ash", "sage", "amuch", "dan"
|
| 12 |
* @param {number} [seed] - Seed for reproducible results
|
| 13 |
* @param {string} [voiceInstructions] - Additional instructions for voice character/style
|
|
|
|
| 14 |
* @returns {Promise<Object>} - Object containing the base64 audio data, mime type, and metadata
|
| 15 |
*/
|
| 16 |
-
export async function respondAudio(prompt, voice = "alloy", seed, voiceInstructions) {
|
| 17 |
if (!prompt || typeof prompt !== 'string') {
|
| 18 |
throw new Error('Prompt is required and must be a string');
|
| 19 |
}
|
|
@@ -41,8 +42,20 @@ export async function respondAudio(prompt, voice = "alloy", seed, voiceInstructi
|
|
| 41 |
url += `?${queryString}`;
|
| 42 |
|
| 43 |
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
// Fetch the audio from the URL
|
| 45 |
-
const response = await fetch(url);
|
| 46 |
|
| 47 |
if (!response.ok) {
|
| 48 |
throw new Error(`Failed to generate audio: ${response.statusText}`);
|
|
|
|
| 11 |
* @param {string} [voice="alloy"] - Voice to use for audio generation. Available options: "alloy", "echo", "fable", "onyx", "nova", "shimmer", "coral", "verse", "ballad", "ash", "sage", "amuch", "dan"
|
| 12 |
* @param {number} [seed] - Seed for reproducible results
|
| 13 |
* @param {string} [voiceInstructions] - Additional instructions for voice character/style
|
| 14 |
+
* @param {Object} [authConfig] - Optional authentication configuration {token, referrer}
|
| 15 |
* @returns {Promise<Object>} - Object containing the base64 audio data, mime type, and metadata
|
| 16 |
*/
|
| 17 |
+
export async function respondAudio(prompt, voice = "alloy", seed, voiceInstructions, authConfig = null) {
|
| 18 |
if (!prompt || typeof prompt !== 'string') {
|
| 19 |
throw new Error('Prompt is required and must be a string');
|
| 20 |
}
|
|
|
|
| 42 |
url += `?${queryString}`;
|
| 43 |
|
| 44 |
try {
|
| 45 |
+
// Prepare fetch options with optional auth headers
|
| 46 |
+
const fetchOptions = {};
|
| 47 |
+
if (authConfig) {
|
| 48 |
+
fetchOptions.headers = {};
|
| 49 |
+
if (authConfig.token) {
|
| 50 |
+
fetchOptions.headers['Authorization'] = `Bearer ${authConfig.token}`;
|
| 51 |
+
}
|
| 52 |
+
if (authConfig.referrer) {
|
| 53 |
+
fetchOptions.headers['Referer'] = authConfig.referrer;
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
// Fetch the audio from the URL
|
| 58 |
+
const response = await fetch(url, fetchOptions);
|
| 59 |
|
| 60 |
if (!response.ok) {
|
| 61 |
throw new Error(`Failed to generate audio: ${response.statusText}`);
|
src/services/imageService.js
CHANGED
|
@@ -14,10 +14,11 @@
|
|
| 14 |
* @param {number} [height=1024] - Height of the generated image
|
| 15 |
* @param {boolean} [enhance=true] - Whether to enhance the prompt using an LLM before generating
|
| 16 |
* @param {boolean} [safe=false] - Whether to apply content filtering
|
|
|
|
| 17 |
* @returns {Object} - Object containing the image URL and metadata
|
| 18 |
* @note Always includes nologo=true and private=true parameters
|
| 19 |
*/
|
| 20 |
-
export async function generateImageUrl(prompt, model = 'flux', seed = Math.floor(Math.random() * 1000000), width = 1024, height = 1024, enhance = true, safe = false) {
|
| 21 |
if (!prompt || typeof prompt !== 'string') {
|
| 22 |
throw new Error('Prompt is required and must be a string');
|
| 23 |
}
|
|
@@ -81,20 +82,33 @@ export async function generateImageUrl(prompt, model = 'flux', seed = Math.floor
|
|
| 81 |
* @param {string} [outputPath='./mcpollinations-output'] - Directory path where to save the image
|
| 82 |
* @param {string} [fileName] - Name of the file to save (without extension)
|
| 83 |
* @param {string} [format='png'] - Image format to save as (png, jpeg, jpg, webp)
|
|
|
|
| 84 |
* @returns {Promise<Object>} - Object containing the base64 image data, mime type, metadata, and file path if saved
|
| 85 |
* @note Always includes nologo=true and private=true parameters
|
| 86 |
*/
|
| 87 |
-
export async function generateImage(prompt, model = 'flux', seed = Math.floor(Math.random() * 1000000), width = 1024, height = 1024, enhance = true, safe = false, outputPath = './mcpollinations-output', fileName = '', format = 'png') {
|
| 88 |
if (!prompt || typeof prompt !== 'string') {
|
| 89 |
throw new Error('Prompt is required and must be a string');
|
| 90 |
}
|
| 91 |
|
| 92 |
// First, generate the image URL
|
| 93 |
-
const urlResult = await generateImageUrl(prompt, model, seed, width, height, enhance, safe);
|
| 94 |
|
| 95 |
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
// Fetch the image from the URL
|
| 97 |
-
const response = await fetch(urlResult.imageUrl);
|
| 98 |
|
| 99 |
if (!response.ok) {
|
| 100 |
throw new Error(`Failed to generate image: ${response.statusText}`);
|
|
|
|
| 14 |
* @param {number} [height=1024] - Height of the generated image
|
| 15 |
* @param {boolean} [enhance=true] - Whether to enhance the prompt using an LLM before generating
|
| 16 |
* @param {boolean} [safe=false] - Whether to apply content filtering
|
| 17 |
+
* @param {Object} [authConfig] - Optional authentication configuration {token, referrer}
|
| 18 |
* @returns {Object} - Object containing the image URL and metadata
|
| 19 |
* @note Always includes nologo=true and private=true parameters
|
| 20 |
*/
|
| 21 |
+
export async function generateImageUrl(prompt, model = 'flux', seed = Math.floor(Math.random() * 1000000), width = 1024, height = 1024, enhance = true, safe = false, authConfig = null) {
|
| 22 |
if (!prompt || typeof prompt !== 'string') {
|
| 23 |
throw new Error('Prompt is required and must be a string');
|
| 24 |
}
|
|
|
|
| 82 |
* @param {string} [outputPath='./mcpollinations-output'] - Directory path where to save the image
|
| 83 |
* @param {string} [fileName] - Name of the file to save (without extension)
|
| 84 |
* @param {string} [format='png'] - Image format to save as (png, jpeg, jpg, webp)
|
| 85 |
+
* @param {Object} [authConfig] - Optional authentication configuration {token, referrer}
|
| 86 |
* @returns {Promise<Object>} - Object containing the base64 image data, mime type, metadata, and file path if saved
|
| 87 |
* @note Always includes nologo=true and private=true parameters
|
| 88 |
*/
|
| 89 |
+
export async function generateImage(prompt, model = 'flux', seed = Math.floor(Math.random() * 1000000), width = 1024, height = 1024, enhance = true, safe = false, outputPath = './mcpollinations-output', fileName = '', format = 'png', authConfig = null) {
|
| 90 |
if (!prompt || typeof prompt !== 'string') {
|
| 91 |
throw new Error('Prompt is required and must be a string');
|
| 92 |
}
|
| 93 |
|
| 94 |
// First, generate the image URL
|
| 95 |
+
const urlResult = await generateImageUrl(prompt, model, seed, width, height, enhance, safe, authConfig);
|
| 96 |
|
| 97 |
try {
|
| 98 |
+
// Prepare fetch options with optional auth headers
|
| 99 |
+
const fetchOptions = {};
|
| 100 |
+
if (authConfig) {
|
| 101 |
+
fetchOptions.headers = {};
|
| 102 |
+
if (authConfig.token) {
|
| 103 |
+
fetchOptions.headers['Authorization'] = `Bearer ${authConfig.token}`;
|
| 104 |
+
}
|
| 105 |
+
if (authConfig.referrer) {
|
| 106 |
+
fetchOptions.headers['Referer'] = authConfig.referrer;
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
// Fetch the image from the URL
|
| 111 |
+
const response = await fetch(urlResult.imageUrl, fetchOptions);
|
| 112 |
|
| 113 |
if (!response.ok) {
|
| 114 |
throw new Error(`Failed to generate image: ${response.statusText}`);
|
src/services/textService.js
CHANGED
|
@@ -10,9 +10,10 @@
|
|
| 10 |
* @param {string} prompt - The text prompt to generate a response for
|
| 11 |
* @param {string} [model="openai"] - Model to use for text generation. Available options: "openai", "anthropic", "mistral", "llama", "gemini"
|
| 12 |
* @param {number} [seed] - Seed for reproducible results (default: random)
|
|
|
|
| 13 |
* @returns {Promise<string>} - The generated text response
|
| 14 |
*/
|
| 15 |
-
export async function respondText(prompt, model = "openai", seed = Math.floor(Math.random() * 1000000)) {
|
| 16 |
if (!prompt || typeof prompt !== 'string') {
|
| 17 |
throw new Error('Prompt is required and must be a string');
|
| 18 |
}
|
|
@@ -34,8 +35,20 @@ export async function respondText(prompt, model = "openai", seed = Math.floor(Ma
|
|
| 34 |
}
|
| 35 |
|
| 36 |
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
// Fetch the text from the URL
|
| 38 |
-
const response = await fetch(url);
|
| 39 |
|
| 40 |
if (!response.ok) {
|
| 41 |
throw new Error(`Failed to generate text: ${response.statusText}`);
|
|
|
|
| 10 |
* @param {string} prompt - The text prompt to generate a response for
|
| 11 |
* @param {string} [model="openai"] - Model to use for text generation. Available options: "openai", "anthropic", "mistral", "llama", "gemini"
|
| 12 |
* @param {number} [seed] - Seed for reproducible results (default: random)
|
| 13 |
+
* @param {Object} [authConfig] - Optional authentication configuration {token, referrer}
|
| 14 |
* @returns {Promise<string>} - The generated text response
|
| 15 |
*/
|
| 16 |
+
export async function respondText(prompt, model = "openai", seed = Math.floor(Math.random() * 1000000), authConfig = null) {
|
| 17 |
if (!prompt || typeof prompt !== 'string') {
|
| 18 |
throw new Error('Prompt is required and must be a string');
|
| 19 |
}
|
|
|
|
| 35 |
}
|
| 36 |
|
| 37 |
try {
|
| 38 |
+
// Prepare fetch options with optional auth headers
|
| 39 |
+
const fetchOptions = {};
|
| 40 |
+
if (authConfig) {
|
| 41 |
+
fetchOptions.headers = {};
|
| 42 |
+
if (authConfig.token) {
|
| 43 |
+
fetchOptions.headers['Authorization'] = `Bearer ${authConfig.token}`;
|
| 44 |
+
}
|
| 45 |
+
if (authConfig.referrer) {
|
| 46 |
+
fetchOptions.headers['Referer'] = authConfig.referrer;
|
| 47 |
+
}
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
// Fetch the text from the URL
|
| 51 |
+
const response = await fetch(url, fetchOptions);
|
| 52 |
|
| 53 |
if (!response.ok) {
|
| 54 |
throw new Error(`Failed to generate text: ${response.statusText}`);
|