SP Gateway is an AI gateway application written in Go that provides a unified interface for interacting with multiple AI providers. It supports projects, agents, task management, and comprehensive AI model orchestration.
- Multi-Provider Support: Supports OpenAI, Anthropic, Google, xAI, DeepSeek, and Hugging Face AI models
- Model Self-Registration: Models automatically register themselves with their providers
- Session Management: Persistent session handling with Redis storage and MySQL metadata
- MCP Support: Model Context Protocol (MCP) support for enhanced capabilities
- Projects & Agents: Organize work into projects with configurable AI agents
- Task Management: Create, schedule, and manage tasks with automatic execution
- Task Triggers: Rule-based triggers that automatically create tasks based on conditions
- Reports & Documents: Generate monthly/annual reports and maintain living documents
- Codebases / Resources / Assets / Credentials: Manage project codebase setup plus skills/resources/tools and project-level/agent-level assets/credentials
- Codebase Runs (Phase 2): Queue lint/test/build run requests with persisted status/log history (runner-worker ready)
- Authentication: Support for both API key and username/password authentication
- RESTful API: Clean REST API for interacting with the gateway
- Web UI: Built-in web configuration interface
- Database Configuration: MySQL backend for storing configuration and metadata
- Feature Declaration: Each model declares its supported features, output formats, and MCP support
sp-gateway/
├── bin/ # Compiled binaries
├── build/ # Frontend build output
├── docs/ # Documentation
│ ├── README.md # This file
│ ├── database.sql # Complete database schema (up-to-date reference)
│ └── sp-gateway.json # Configuration example
├── sp-gateway/ # Source code
│ ├── api/ # API handlers and routing
│ ├── agents/ # Agent management
│ ├── data/ # Data layer (MySQL, Redis, HTTP, WebSocket)
│ ├── providers/ # AI provider implementations
│ │ ├── openai/ # OpenAI provider (GPT-5.2 family, GPT-5 mini/nano, DALL-E 3, Whisper, etc.)
│ │ ├── anthropic/ # Anthropic provider (Claude Opus 4.6, Sonnet 4.5, Haiku 4.5)
│ │ ├── google/ # Google provider (Gemini 3, Imagen, Veo 3.1, etc.)
│ │ ├── xai/ # xAI provider (Grok 4.1, Grok Code, Grok Imagine)
│ │ ├── deepseek/ # DeepSeek provider (DeepSeek V3.2)
│ │ └── huggingface/ # Hugging Face provider (Llama 3.1, Flux, Stable Diffusion, etc.)
│ ├── taskmanager/ # Task execution and trigger management
│ └── sp-gateway.go # Main entry point
├── tests/ # Test utilities
│ ├── api-tester/ # API testing tool
│ └── model-tester/ # Model testing tool
├── webcfg-ui/ # Web configuration UI (React/TypeScript)
├── Makefile # Build configuration
├── go.mod # Go module definition
└── LICENSE # License file
- Go 1.24 or later
- MySQL 5.7+ or 8.0+
- Redis 6.0+
- Make (optional, for using Makefile)
- Clone the repository:
git clone <repository-url>
cd sp-gateway- Install dependencies:
make install-deps
# or
go mod download- Set up the database:
mysql -u root -p < docs/database.sql- Configure the application:
cp docs/sp-gateway.json sp-gateway.json
# Edit sp-gateway.json with your MySQL and Redis credentialsBuild for your current platform:
make buildBuild for specific platforms:
make build-linux
make build-windows
make build-darwinThe binary will be created in the bin/ directory.
Run the application:
make run
# or
./bin/sp-gatewayYou can specify a custom config path using the CONFIG_PATH environment variable:
CONFIG_PATH=/path/to/config.json ./bin/sp-gatewayThe configuration file (sp-gateway.json) contains:
- Server: HTTP server configuration (host, port, timeouts, allowed origins)
- MySQL: Database connection settings
- Redis: Redis connection settings and session TTL
- Logging: Logging level and format
See docs/sp-gateway.json for an example configuration.
POST /api/v1/login- Login with username/password (no auth required)POST /api/v1/logout- Logout (no auth required)
GET /health- Health check endpoint (no auth required)
GET /api/v1/list/{type}- List resources by type- Supported types:
providers,models,agents,projects,sessions,users,gateway-api-keys,gateway-config,tasks,reports,documents,codebases,resources,assets,credentials,mcp-tools - Query parameters:
user_id,project_id, etc. (type-dependent)
- Supported types:
POST /api/v1/add/{type}- Create new resource- Supported types:
agent,project,gateway-api-key,provider,model,user,gateway-config,task,report,document,codebase,resource,asset,credential
- Supported types:
PUT /api/v1/update/{type}/{id}- Update resourcePATCH /api/v1/update/{type}/{id}- Partial update resource- Supported types:
agent,project,provider,model,user,gateway-config,task,report,document,codebase,resource,asset,credential,mcp-tool
- Supported types:
DELETE /api/v1/del/{type}/{id}- Delete resource- Supported types:
agent,project,gateway-api-key,session,provider,model,user,gateway-config,task,report,document,codebase,resource,asset,credential,mcp-tool
- Supported types:
GET /api/v1/codebases/{id}/tasks- List recent codebase tasks (query:limit)POST /api/v1/codebases/{id}/tasks- Queue a normal task forlint|test|build|custom(optionalcommand, optionalassigned_tags)
POST /api/v1/chat- Send a chat request
Query parameters:
provider- Provider name (required if session_id not provided)model- Model code (required if session_id not provided)agent_id- Agent ID (optional, uses agent's models and configuration)session- Session ID (optional, continues existing conversation)operation- Operation type:completion,chat, orconversation(optional)task_id- Task ID (optional, binds the chat to a task context and auto-reuses the task session when available)
Request body:
{
"system_message": "You are a helpful assistant",
"user_message": "Hello!",
"messages": [
{"role": "user", "content": "Hello!"}
],
"mcp_config": {
"tools": [],
"instructions": [],
"operations": []
},
"temperature": 0.7,
"max_tokens": 1000,
"response_format": "json_object",
"stream": false,
"user_id": "user123"
}GET /api/v1/session- List sessions (query:user_id)GET /api/v1/session/{session_id}- Get session detailsDELETE /api/v1/session/{session_id}- Delete a session
GET /api/v1/tasks- List tasks (query:project_id,status,assigned_tags, etc.)POST /api/v1/tasks- Create a new taskGET /api/v1/tasks/{id}- Get task detailsGET /api/v1/tasks/{id}/output.txt- Download task output text as a .txt filePOST /api/v1/tasks/{id}/attachments- Upload task attachments (multipart/form-data fieldfileorfiles)PUT /api/v1/tasks/{id}- Update taskPATCH /api/v1/tasks/{id}- Partial update taskDELETE /api/v1/tasks/{id}- Cancel task (soft delete; task is retained for history)POST /api/v1/task/{task_id}/spawn- Spawn a new task from an existing taskGET /api/v1/tasks/tags- Get all used task tagsGET /api/v1/tasks/views/{view}- Get task views (e.g.,pending,scheduled)
GET /api/v1/triggers- List triggers (query:project_id,enabled)POST /api/v1/triggers- Create a new triggerGET /api/v1/triggers/{id}- Get trigger detailsPUT /api/v1/triggers/{id}- Update triggerPATCH /api/v1/triggers/{id}- Partial update triggerDELETE /api/v1/triggers/{id}- Delete trigger
- GPT-5.2, GPT-5.2 Pro, GPT-5.2 Chat, GPT-5.3 Codex (Extra High), GPT-5 Mini, GPT-5 Nano
- DALL-E 3 (image generation)
- Whisper 1 (audio transcription)
- GPT Audio, GPT Audio Mini
- Claude Opus 4.6
- Claude Sonnet 4.5
- Claude Haiku 4.5
- Gemini 3 Pro, Gemini 3 Flash
- Imagen (image generation)
- Veo 3.1 (video generation)
- Lyria (audio generation)
- NanoBana (text-to-speech)
- Embeddings models
- Grok 4.1 Fast (Reasoning & Non-Reasoning)
- Grok Code Fast 1
- Grok Imagine Image, Image Pro, Video
- DeepSeek V3.2
- Llama 3.1
- Flux (image generation)
- Stable Diffusion XL
- Stable Video Diffusion
- CodeLlama, StarCoder 2
- Qwen 2.5 Reasoning
- AnimateDiff
- Embeddings models (BGE, E5)
To add a new provider:
- Create a directory under
sp-gateway/providers/(e.g.,sp-gateway/providers/newprovider/) - Create a provider file that imports all models (e.g.,
newprovider.go) - Create model directories under the provider (e.g.,
sp-gateway/providers/newprovider/modelname/) - Implement the
Modelinterface in each model'smodel.gofile - Models will automatically register themselves via the
init()function
Example model structure:
package modelname
import (
"github.com/stakeplus/sp-gateway/sp-gateway/providers"
)
func init() {
model := &Model{
BaseModel: providers.BaseModel{
Provider: "newprovider",
Name: "Model Name",
ModelCode: "modelname",
SupportsMCP: true,
OutputFormats: []string{"text", "json"},
Features: []string{"chat", "streaming"},
},
}
providers.RegisterModel(model)
}Each model declares:
- SupportsMCP: Whether the model supports Model Context Protocol
- OutputFormats: Native output formats (e.g., "text", "json", "json_object", "image", "base64")
- Features: List of supported features (e.g., "chat", "streaming", "function_calling", "mcp", "vision", "image_generation", "audio", "embeddings")
Sessions are stored in Redis for fast access, with metadata stored in MySQL. Sessions include:
- Message history
- MCP configuration
- Provider and model information
- User ID, agent ID, and timestamps
Sessions have a default TTL of 7 days (configurable in Redis config).
The gateway can also override TTL at runtime via gateway_config:
sessions.ttl_secondssessions.ttl_hourssessions.ttl_days
Projects are siloed, self-contained operations that can contain:
- Multiple agents with different roles and capabilities
- Tasks assigned to agents via tags
- Reports (monthly/annual)
- Living documents (knowledge base that AI regularly updates). Living documents include
description(short summary) andextended_description("agent understanding" / constraints & objectives) to help guide AI updates. - Codebases (repo URL, architecture notes, preferred stack/services, and prerequisites)
- Codebase runs (queued runtime operations like lint/test/build with status and logs)
- Resources (skills/tools)
- Assets (project-level and agent-level)
- Credentials (project-level and agent-level, optionally tied to assets)
Agents belong to projects and can have:
- Job title and role
- Job tags (for task assignment)
- Soul (personality and behavior instructions)
- Associated models (with priority ordering)
- Project and user context information
- Optional avatar/PFP images (uploaded to the gateway and served from
/uploads)
Avatar / PFP upload endpoints (multipart/form-data field file):
POST /api/v1/projects/{id}/logo-> updatesprojects.logo_urlPOST /api/v1/agents/{id}/avatar-> updatesagents.avatar_url
Tasks can be:
- Scheduled: One-time or recurring (using cron patterns or intervals)
- Spawned: Created by other tasks
- External: Created by external systems
Tasks are assigned to agents via tags. The task executor automatically picks up pending tasks and assigns them to available agents.
The UI can auto-hide completed tasks older than a configurable threshold to reduce clutter (tasks remain stored in the DB):
tasks.hide_completed_after_hours: number (default: 72; set to 0 to disable)
Triggers automatically create tasks based on conditions. Triggers can:
- Monitor metrics or conditions
- Create tasks when conditions are met
- Run on a schedule pattern
The gateway supports MCP, allowing clients to:
- Declare available tools
- Provide instructions
- Define operations
MCP configuration is passed with each request and stored in sessions for context preservation.
In addition to client-supplied mcp_config, the gateway exposes built-in MCP tools ("Skills") to an agent based on
entries in the resources table:
resources.resource_type = 'skill'resources.agent_id = <agent id>(agent-level)resources.namematches a built-in tool name
Built-in tool names:
agent_plugin- Unified agent operations (agent.list)task_plugin- Unified task operations (task.create,task.finish,task.upsert,task.delete,task.list)report_plugin- Unified report operations (report.create,report.upsert,report.delete,report.list)living_document_plugin- Unified living document operations (living_document.upsert,living_document.list)coding_plugin- Unified coding operations over remote SSH
coding_plugin MCP action names:
coding.describe_capabilitiescoding.list_directorycoding.read_filecoding.write_filecoding.append_filecoding.delete_pathcoding.make_directorycoding.search_textcoding.run_commandcoding.git_statuscoding.git_diffcoding.git_log
coding_plugin is only injected when:
- the agent has the
coding_pluginskill enabled - the agent has an assigned
codebase_id - that codebase is enabled
runtime_config.runnerhashost,ssh_user, andworkspace_root
When an agent chats using an MCP-capable model, the gateway injects the matching tool schemas and (by default) will auto-execute requested tool calls server-side, persisting tool results into the session history.
Runtime controls (stored in gateway_config):
mcp.auto_execute_skills:true|false(default: true)mcp.max_tool_iterations: number (default: 3, min: 1)mcp.max_needs_follow_up_turns: number (default: 2, max: 10)
Example (assign a skill to an agent via API):
POST /api/v1/add/resource
{
"project_id": 1,
"agent_id": 123,
"resource_type": "skill",
"name": "task_plugin",
"description": "Allow agent to manage tasks via MCP"
}The gateway supports two authentication methods:
-
Gateway API Keys: Pre-generated API keys for programmatic access
- Create via
POST /api/v1/add/gateway-api-key - Use in
X-API-Keyheader
- Create via
-
Username/Password: Traditional authentication
- Login via
POST /api/v1/login - Uses session cookies
- Login via
The complete database schema is defined in docs/database.sql. This file is the authoritative reference for the database structure and includes:
- Providers and models
- API keys (provider and gateway)
- Users and authentication
- Projects and agents
- Sessions and MCP configurations
- Tasks and triggers
- Reports and living documents
- Resources
- Assets
- Credentials
MIT License - see LICENSE file for details.
Contributions are welcome! Please ensure your code follows Go best practices and includes appropriate tests.
- API Key Encryption: API keys are currently stored in plain text. Encryption/decryption should be implemented for production use.
- Transaction Support: Operations involving both Redis and MySQL are not transactional. Consider implementing distributed transaction patterns or ensuring cleanup on both sides.
- MCP Configs Foreign Key: The foreign key constraint may fail if a session exists in Redis but hasn't been synced to MySQL yet.
- Silent Failures: Some non-critical operations (like
last_accessed_atupdates) fail silently. Consider adding proper error logging.
- Multiple API Keys Per Provider: The system allows multiple API keys per provider but only retrieves the most recent one. Consider adding methods to manage multiple keys or filter by key name.
- Data Type Consistency: Provider and model references in sessions table are stored as VARCHAR without foreign key constraints, which could lead to orphaned sessions.
- Add validation to ensure connection pool configuration is correct (MaxIdleConns <= MaxOpenConns)
- Consider composite indexes for frequently queried combinations (e.g., user_id + provider)
For issues and questions, please open an issue on the repository.