SynaMCPs

by synamcps

Not rated
GitHub

About

Provides a universal gateway for corporate AI tools, offering knowledge storage, access control, and proxying of external AI sources.

Details

Author
synamcps
Categories
AI, Knowledge Base, Security, API

Setup

Install SynaMCPs in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/synamcps/synamcps-server

Follow the installation instructions in the repository README, then restart your MCP client.

Synamcps (SynaMCPs) — MCP + Knowledge Storage Gateway

- An MCP serverfor LLM clients (Cursor / Claude Desktop / Claude Code / etc.)
- An HTTP APIto create/search/read knowledge items
- A Web Admin UIto manage users/groups/storages/tokens, view status, and do basic diagnostics
- Token-based access to storages(tokens onlynarrowpermissions), with ACL/RBAC, rate limiting, and usage/metrics

The server supports multiple auth methods (OIDC/Keycloak/Google/Teleport Proxy JWT) and aninternal loginfor the Admin UI.

- Login:http://localhost:8080/login
- Admin UI:http://localhost:8080/admin
- User app:http://localhost:8080/app
- MCP endpoint (streamable):http://localhost:8080/mcp
- HTTP API:http://localhost:8080/api/

- Go1.23+
- Postgres, Redis, S3/MinIO available (or use Docker Compose as your infrastructure)

export CONFIG_PATH=configs/config.local.yaml go run ./cmd/server

- Storageis a logical entity tied to:

- records in the metadata catalog (Postgres)
- an S3 prefix (storage.S3Prefix)
- search scoping (vector backend: pgvector/qdrant)

- belong to a user (owner)
- do not expandpermissions — they
narrowthe owner's access (intersection of user ACL and token scopes)
- can restrict:storageIds,maxMode(read/read_write),toolAllowlist, rate limits.

- You can add an item as:

- Text(via the standardPOST /api/knowledge)
- File(upload → raw stored to S3 → best-effort extraction → summary+embeddings → item saved to storage)
- Link(download → raw stored to S3 → extraction → summary+embeddings → item saved to storage)

- MCP exposes adynamictools/listbased on the bearer token (only allowed tools/storages are visible).
- SupportsStreamable HTTPtransport (/mcp) and optional legacy SSE.
- MCP tool names use_(underscore) to avoid filtering/warnings in some clients.
- MCP proxy: register upstream HTTP/SSE MCP servers in Admin UI (MCP Serverstab), discover tools/resources/prompts, restrict by ACL and per-token scopes. Proxied identifiers:

- tools/prompts:{slug}__{upstream_name}
- resources:syna-mcp/{slug}/{upstream_uri}
- theslugis generated automatically from the server name (no manual entry).

- Rate limiting per token (minute/hour/day + burst), enforced forbothMCP calls and the REST API (429 Too Many Requestswhen exceeded).
- Request bodies are capped bylimits.max_upload_bytes(413when exceeded).
- Usage events (and status/errors) can be written to Redis TimeSeries (when enabled).
- /metricsexposes Prometheus-format metrics (label values are sanitized and series cardinality is bounded).

The built-in admin UI (server-rendered HTML) lets you:

- Users / Groups / Group members
- Storages + Storage details (ACL, keys/tokens, items list)
- Tokens + MCP Connect wizard + delete
- Add item (Text/File/Link)
- Search (by token / by storage)
- Status (Postgres/Redis/S3/LLMs + error counters)

Forms pick entities fromname dropdowns(storages/groups/users/tokens/MCP servers) with refresh buttons instead of typing raw IDs. Slugs are no longer entered by hand — a storage defaults its slug to its id and an MCP server derives a unique slug from its name.

Default config:configs/config.example.yaml
Override:CONFIG_PATH=/path/to/config.yaml

- web.default_admin: Admin UI username/password (password via env ref)
- oauth.providers: OIDC providers (issuer/audience/jwks_url; optional client_id for AS login)
- oauth_as: MCP OAuth 2.1 Authorization Server for Claude Desktop Connectors
- teleport: Teleport Proxy JWT (issuer/audience)
- redis: sessions + usage/time-series (when enabled)
- s3: endpoint/bucket + large document threshold
- embedding,summarization: LLMs (provider/model/api/api_key_env_ref)
- vector_backend.active:pgvectororqdrant
- metadata_catalog.dsn: Postgres DSN
- api.allowed_origins: strict CORS allowlist
- usage: accounting and time series, retention, exporters

Example.envfor local development:.env.example.

- 401— missing token/session
- 403— forbidden (insufficient permissions for the storage/operation)
- 404— not found
- 413— request body exceedslimits.max_upload_bytes
- 422— invalid request
- 429— rate limit exceeded (per-token limits)

- page(int)
- pageSize(int)
- storageId(string) — limit to a specific storage
- source(string) — exact match
- sourceUrl(string)
- sourceUrlMode(exact|partial) —partialworks only whensearch.filters.source_url.allow_partial_match=true

Response:models.PaginatedKnowledgeList(items + total + hasNext + page/pageSize).

{ "storageId": "storage-id-optional", "title": "Runbook", "text": "Long knowledge text...", "mimeType": "text/plain", "visibility": "personal", "groupIds": [], "source": "api", "sourceUrl": "https://docs.example.com/runbook" }

- ifstorageIdis empty and access-service is enabled, the server uses/creates the user's personal storage
- visibilitydefaults topersonal
- groupIdsmust be an array (notnull)

Delete a document (and associated embeddings in the vector store).

{ "query": "kubernetes ingress timeout", "topK": 10, "filters": { "storageId": "storage-id-optional", "source": "api", "sourceUrl": "https://...", "sourceUrlMode": "exact" } }

Response: an array of search hits (including snippet/title/source/sourceUrl).

POST /api/knowledge/ingest/file(multipart)

- raw content is stored in S3
- best-effort text extraction is performed
- the pipeline produces summary + embeddings
- the final result is saved as a normal knowledge item

- storageId(string, optional)
- title(string, optional)
- visibility(personal|group|public, optional)
- source(string, optional)
- sourceUrl(string, optional)
- mimeType(string, optional)
- file(required)

curl -X POST http://localhost:8080/api/knowledge/ingest/file \ -H "Authorization: Bearer $TOKEN" \ -F "storageId=..." \ -F "title=Spec" \ -F "visibility=personal" \ -F "file=@./spec.txt"

Downloads a URL, stores raw content to S3, extracts text, and saves an item.

{ "storageId": "storage-id-optional", "title": "Optional title", "url": "https://example.com/docs", "visibility": "personal", "source": "link" }

- GET /api/admin/me
- GET /api/admin/users(platform_admin)
- POST /api/admin/users(platform_admin)
- GET /api/admin/users/{id}(admin или сам пользователь)
- PATCH /api/admin/users/{id}(admin или сам пользователь)
- POST /api/admin/users/{id}/password(admin или сам пользователь)
- DELETE /api/admin/users/{id}(platform_admin)

- GET /api/admin/groups(platform_admin)
- POST /api/admin/groups(platform_admin)
- DELETE /api/admin/groups/{id}(platform_admin)
- GET /api/admin/groups/{id}/members(platform_admin)
- PUT /api/admin/groups/{id}/members/{userId}(platform_admin)
- DELETE /api/admin/groups/{id}/members/{userId}(platform_admin)

- GET /api/admin/storages(storages available to the current user)
- POST /api/admin/storages
- DELETE /api/admin/storages/{id}(requiresstorage.delete: storage owner/admin or platform_admin)
- GET /api/admin/storages/{id}(storage details: storage + acl + tokens; requires read access)
- GET /api/admin/storages/{id}/acl(requiresacl.manage)
- PUT /api/admin/storages/{id}/acl(requiresacl.manage)

Mutating token endpoints require the caller to be thetoken owner or platform_admin;GET /api/admin/tokenslists only the caller's own tokens (platform_admin sees all).

- GET /api/admin/tokens
- POST /api/admin/tokens
- DELETE /api/admin/tokens/{id}(owner/platform_admin)
- PATCH /api/admin/tokens/{id}/rate-limit(owner/platform_admin)
- POST /api/admin/tokens/{id}/revoke(owner/platform_admin)
- POST /api/admin/tokens/{id}/rotate(owner/platform_admin)
- PATCH /api/admin/tokens/{id}/mcp-scopes(owner/platform_admin)
- GET/POST /api/admin/tokens/{id}/connect-options(wizard for MCP clients)

- GET /api/admin/usage/series
- GET /api/admin/usage/summary
- GET /api/admin/status— component status + error counters (Redis TimeSeries)

- Streamable HTTP:POST /mcp(JSON-RPC) +GET /mcp(SSE stream поMcp-Session-Id)
- Legacy SSE (если включено):/sse+/messages
- Obtain a bearer token (OIDC/Teleport/or internal)
- initialize:

curl -X POST http://localhost:8080/mcp \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":"1","method":"initialize","params":{}}'

- SaveMcp-Session-Idfrom headers/response (clients do this automatically)
- Open the stream (the bearer token is required and must match the session owner):

curl -N http://localhost:8080/mcp \ -H "Authorization: Bearer $TOKEN" \ -H "Mcp-Session-Id: <session_id>"

GET /mcpandDELETE /mcpare authenticated; a session can only be read/closed by the principal that created it.

tools/listreturns only the tools allowed by the current bearer token and its storage scopes.

tools/callroutes calls to the corresponding internal methods (knowledge_ etc.).

The Admin UI (/admin) includes anMCP Connectpage that generates:

- config file name
- configBody(JSON)
- step-by-step instructions

- make compose-down
- make seed-dev(if used in your environment)

- configs/config.example.yaml— example config
- configs/config.local.yaml— local compose config (used indocker-compose.yml)
- .env— secrets (passwords/keys), example in.env.example

api.allowed_originsis a strict allowlist. Unknown origins are rejected. Web UI routes (/,/login,/logout,/app,/admin) bypass the origin check.

- Origin not allowed:

- add the origin toapi.allowed_origins
- make sure you open the Web UI via/login(web routes bypass origin-check)

- verify.envis loaded (in compose it is wired viaenv_file: .env)
- verifyweb.default_admin.password_env_ref

- you need Redis with the RedisTimeSeries module (TS.ADDmust be supported)
- or disableusage.redis_timeseries

- docs/marketing.md— product overview + corporate RAG / agentic pipeline scenarios
- docs/setup.md— installation and run
- docs/api.md— basic knowledge endpoints
- docs/mcp-connection.md— MCP connection
- docs/auth-setup.md— auth providers
- docs/openapi.yaml— baseline OpenAPI stub

Access control, conflict resolution, and audit for shared agent memory.

Waymark — shared route network for AI agents. Query verified step sequences + documented failure modes for API tasks over MCP. Reads free & keyless. 7,400+ routes, 2,100+ domains.

Persistent, inspectable memory for AI agents via hosted MCP and API. Supports recall, structured query, lineage, correction, and tenant-scoped remote memory.

Persistent memory for AI assistants and coding agents across ChatGPT, Claude, Cursor, and other MCP-compatible tools.

Local Work Model for AI agents that learns from real outcomes.

Auditable, self-improving knowledge & memory for AI agents over MCP — citation-enforced answers and a replayable why-trace, self-hosted on Postgres.

One shared, versioned memory for your AI agents across Claude Code, Cursor, Kiro and Grok, with a source on every answer and full history.

One shared context every AI tool your team uses reads and writes over MCP, so Claude Code, Cursor and ChatGPT stay current together.

Your company's brain, connected to Claude, ChatGPT, Gemini, Cursor, and VS Code. Turn your team's email history into shared memory that any AI assistant can query with natural language.

Operational memory for AI agents that persists across sessions and tools.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.