Gateco

ai.gateco由 gateco.ai 發布v1.13.0更新於 Oct 24, 2026

Permission-aware retrieval for AI systems: policy-enforced access to organizational knowledge.

已驗證STDIO僅桌面知識與記憶安全與監控

概覽

AI 產生的概覽

Gateco MCP 伺服器讓助理以受政策約束、依權限過濾的方式檢索組織知識,只有指定主體有權查看的內容才會送到模型。

可以做什麼
  • 以向量、關鍵字、混合或 grep 模式在連接器上執行權限感知檢索
  • 提出有依據的問題並取得附政策過濾引用的彙整答案
  • 列出連接器與其就緒等級、列出主體與群組,並依電子郵件或身分提供者主體解析主體
  • 試跑存取模擬,查看某主體會被允許看到哪些內容
適用情境
當助理需要依據公司文件回答問題、同時遵守每位使用者的存取政策,且希望不必自行寫程式就由 Gateco 把關檢索時使用。適合已在用 Gateco 連接器與身分資料的團隊。
執行需求
本機 Python 套件,以 uvx 或 pip 安裝 gateco[mcp] 並以本機程序啟動。需要 Gateco 帳號與具備 retrieve 範圍的 GATECO_API_KEY;存取檢查工具則需要透過 gateco login 儲存的使用者工作階段。GATECO_BASE_URL 為選用,預設使用託管 API。需要能連線至 Gateco API 的網路。
安裝前請注意
API 金鑰屬機密,會隨每次請求送出,請勿放入共用設定。存取檢查工具無法以 API 金鑰呼叫,依賴本機儲存的登入工作階段檔案,不應在多台機器間複製。查詢內容與主體識別碼會送到 Gateco API,答案由檢索到的內容彙整而成,結果取決於政策設定是否正確。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Gateco,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

Gateco Python SDK

Official Python client for the Gateco API — permission-aware retrieval for AI systems.

[PyPI version] [Python 3.10+] [GitHub]


The problem it solves

Without Gateco, when an employee asks your AI assistant "What is the CEO's salary?", the RAG pipeline returns the salary from a leaked HR document.

With Gateco:

python
from gateco_sdk import GatecoClient
client = GatecoClient("https://api.gateco.ai")client.login("[email protected]", "...")
result = client.retrievals.execute(    query="What is the CEO's salary?",    principal_id="user_james_wu",    connector_id="connector_hr_docs",    search_mode="hybrid",)
# result.allowed_chunks → [] (denied — James Wu lacks HR classification access)# result.denied_count   → 1# result.decision       → "DENIED"# Your AI model never sees the salary data

Gateco sits between your AI agent and your vector store. Every retrieval is evaluated against your access policies before any content reaches the model.


Installation

bash
pip install gateco

For MCP server support (Claude Desktop, Cursor, etc.):

bash
pip install gateco[mcp]

Authentication

Gateco API keys use the format gck_<env>_<random> (e.g. gck_live_abc123...).

Generate keys via the dashboard or via client.api_keys.create(name="my-service").

python
from gateco_sdk import AsyncGatecoClient, GatecoClient
# Async client with API keyclient = AsyncGatecoClient("https://api.gateco.ai", api_key="gck_live_abc123...")
# Sync client with API keyclient = GatecoClient("https://api.gateco.ai", api_key="gck_live_abc123...")
# Or use email/password login (issues a short-lived JWT)client = GatecoClient("https://api.gateco.ai")client.login("[email protected]", "password")

The API key is sent as the X-API-Key header on every request. Set it via the GATECO_API_KEY environment variable when using the CLI or MCP server. The key takes precedence over a stored login.

No credential at all? Since 1.13.0 a client constructed with no api_key, no GATECO_API_KEY and no access_token reads the session that gateco login stored in ~/.gateco/credentials.json (and its base_url), and writes refreshed tokens back. One login on a machine serves the CLI, the MCP server and your own scripts; do not copy the file between machines, because refresh rotates and the two copies would revoke each other.

Which routes accept an API key

A key carries explicit scopes, chosen when it is created (Settings > API Keys, every plan). Everything not listed here needs a user session (gateco login or client.login(...)); a key sent there gets 401 AUTH_JWT_REQUIRED, and a key without the needed scope gets 403 API_KEY_SCOPE_MISSING.

ScopeRoutes
retrievePOST /api/retrievals/execute, POST /api/retrievals/filter, POST /api/answers/execute, GET /api/principals, GET /api/principals/:id, POST /api/principals/resolve, GET /api/groups (since 2026-10-02), GET /api/connectors (id, name, type, status)
ingestPOST /api/v1/ingest, /batch, /file, /files, DELETE /api/v1/resources/:id, /api/v1/ingest/jobs*
relationshipsPOST, GET, DELETE /api/relationships
principalsPOST, PATCH, DELETE /api/principals (local directory)
any keyGET /api/users/me (reports the key's name and scopes)

Session only: policies, connector create/update/delete and their search and ingestion configs, identity providers, API-key management, audit, retrieval history, billing, the access simulator, classification suggestions.


Quick Start

Async (recommended for production services)

python
import asynciofrom gateco_sdk import AsyncGatecoClient
async def main():    async with AsyncGatecoClient(        "https://api.gateco.ai",        api_key="gck_live_abc123...",    ) as client:
        # Policy-gated retrieval — the core Gateco primitive        result = await client.retrievals.execute(            query="What is the CEO's salary?",            principal_id="user_james_wu",            connector_id="connector_hr_docs",            search_mode="hybrid",            alpha=0.7,   # 70% vector weight, 30% keyword            top_k=5,        )
        # Allowed chunks are safe to pass to your LLM        for chunk in result.allowed_chunks:            print(f"[ALLOWED] {chunk.resource_id} score={chunk.score}")
        # Denied chunks are redacted — only metadata is surfaced        print(f"Denied: {result.denied_count} chunk(s)")
asyncio.run(main())

Synchronous (scripts and notebooks)

python
from gateco_sdk import GatecoClient
with GatecoClient("https://api.gateco.ai", api_key="gck_live_abc123...") as client:    result = client.retrievals.execute(        query="What is the CEO's salary?",        principal_id="user_james_wu",        connector_id="connector_hr_docs",        search_mode="hybrid",    )    print(result.decision)  # "DENIED"

Available Namespaces

Every namespace, and every method on it, is available on both AsyncGatecoClient (async) and GatecoClient (sync); tests/test_sync_parity.py fails the build if the two drift.

NamespaceDescription
client.answersGrounded answer synthesis with policy-filtered citations (Team+)
client.api_keysCreate, list, delete, and rotate API keys
client.auditAudit log listing and CSV export
client.authLogin, signup, token refresh, logout
client.billingPlans, usage meters, invoices, subscription, Stripe checkout and portal
client.connectorsConnector CRUD, connection testing, search/ingestion config, coverage, classification suggestions
client.dashboardAggregated dashboard statistics with optional sparklines
client.data_catalogGated resource listing and metadata updates
client.groupsRead-only groups directory with live member counts
client.identity_providersIdentity provider CRUD and sync (Okta, Azure Entra ID, AWS IAM, GCP)
client.ingestSingle-document, batch, and file ingestion (Tier 1 connectors)
client.onboardingOnboarding status (6 computed steps) and checklist dismissal
client.pipelinesPipeline CRUD and run management
client.policiesPolicy CRUD, lifecycle (activate/archive), and templates
client.principalsPrincipal listing, detail, and resolution by email or provider subject
client.relationshipsREBAC direct-relation CRUD — create, list, delete 1-hop tuples (Team+)
client.retroactiveRetroactive vector registration for existing connectors
client.retrievalsPermission-gated retrieval execution, policy filter, and history
client.simulatorDry-run, live-preview, and batch-preview access simulation (Growth+)
client.sourcesContent-source connections (Drive, SharePoint, Confluence, Notion): create, test, ACL coverage
client.usersCurrent user profile — get_me(), update_me(name)

Retrieval Search Modes

python
# Vector search (default) — semantic similarityresult = await client.retrievals.execute(    query="quarterly earnings", principal_id="...", connector_id="...",)
# Keyword search — ranked full-text search (BM25)result = await client.retrievals.execute(    query="quarterly earnings", principal_id="...", connector_id="...",    search_mode="keyword",)
# Hybrid search — vector + keyword fused (RRF)result = await client.retrievals.execute(    query="quarterly earnings", principal_id="...", connector_id="...",    search_mode="hybrid",    alpha=0.5,   # 1.0 = all-vector, 0.0 = all-keyword)
# Grep — exact pattern matchingresult = await client.retrievals.execute(    query="ERR-4021", principal_id="...", connector_id="...",    search_mode="grep",    pattern_type="regex",    case_sensitive=False,)

API Key Management

python
# Create a key — the plaintext is returned exactly oncekey_info = await client.api_keys.create(name="prod-worker")print(key_info["key"])    # gck_live_abc123...  (store this securely)print(key_info["prefix"]) # gck_live_abc
# List keys (plaintext never returned after creation)keys = await client.api_keys.list()
# Rotate a key — old key is invalidated immediatelynew_key = await client.api_keys.rotate(key_id="key-uuid-here")
# Delete a keyawait client.api_keys.delete(key_id="key-uuid-here")

Relationship-Based Access Control (REBAC)

python
# Create a direct relation: Alice owns resource Rrel = await client.relationships.create(    subject_principal_id="principal-uuid",    relation_name="owner_of",    object_resource_id="resource-uuid",)print(rel["id"])
# List relations for a principalrels = await client.relationships.list(    subject_id="principal-uuid",    relation="owner_of",)
# Delete a relation (invalidates policy cache immediately)await client.relationships.delete(relationship_id=rel["id"])

Use relation.<name> as a policy condition field to gate access on the existence of a tuple:

python
# Policy rule: allow access when principal has owner_of relation on the resourcerule = {"field": "relation.owner_of", "operator": "eq", "value": True}

Onboarding Status

python
# Check which onboarding steps are completestatus = await client.onboarding.status()for step in status["steps"]:    print(f"{step['name']:30s}  {step['status']}")
# Dismiss the checklist once the org is fully configuredawait client.onboarding.dismiss()

Principal Resolution

python
# Resolve a principal by email (read-only — never creates)principal = await client.principals.resolve(email="[email protected]")
# Resolve by raw IDP-side user IDprincipal = await client.principals.resolve(provider_subject="okta-user-123")
# Scoped to a specific identity providerprincipal = await client.principals.resolve(    email="[email protected]",    identity_provider_id="idp-uuid-here",)

Grounded Answer Synthesis (Team+)

python
answer = await client.answers.execute(    query="Summarise the Q4 revenue results.",    principal_id="user_alice",    connector_id="connector_finance_docs",    search_mode="hybrid",)
print(answer.answer_text)      # LLM-generated answer from allowed chunks onlyprint(answer.outcome)          # "answered" | "no_access" | "insufficient_context"for citation in answer.citations:    print(f"  [{citation.score:.2f}] {citation.resource_id}")

Policy Creation

python
# Create an RBAC policypolicy = await client.policies.create(    name="Engineering read-only",    description="Allow engineering group to read internal resources",    type="rbac",    effect="allow",    rules=[{        "description": "Engineering group members",        "effect": "allow",        "conditions": [{"field": "principal.groups", "operator": "contains", "value": "engineering"}],        "priority": 1,    }],    resource_selectors=[{"field": "resource.classification", "op": "lte", "value": "internal"}],)

Policy validation rules:

  • Condition fields must use resource., principal., or relation. prefix. Bare field names (e.g., "classification") are rejected with 422 — they silently resolve against the principal rather than the resource.
  • Policies with empty resource_selectors require apply_to_all_resources=True in the request body to opt into matching all resources explicitly.

Retrieval Diagnostics

python
result = await client.retrievals.execute(    query="quarterly earnings",    principal_id="user_alice",    connector_id="connector_finance_docs",    search_mode="hybrid",)
# All retrieval responses include diagnosticsprint(result.diagnostics.outcome_detail)    # Human-readable explanationprint(result.diagnostics.candidates_fetched)  # How many candidates were checkedprint(result.diagnostics.candidates_denied)   # How many were denied by policyprint(result.diagnostics.refill_rounds)       # How many refill rounds ran (0 = first pass sufficient)

Connector Preflight Check

python
# Check if a connector is production-ready before using it in retrievalspreflight = client.connectors.preflight(connector_id="...")print(preflight.ready_for_production)  # boolprint(preflight.recommendation)        # What to fix nextfor check in preflight.checks:    print(f"{check.name}: {'PASS' if check.passed else 'FAIL'} (blocking={check.blocking})")

Dashboard Activation Metrics

python
# Aggregated dashboard statisticsstats = await client.dashboard.stats()print(stats["total_retrievals"])print(stats["allowed_retrievals"])
# Activation funnel metricsactivation = client.dashboard.get_activation_stats()print(activation.total_retrievals_30d)print(activation.allowed_retrievals_30d)print(activation.no_access_retrievals_30d)  # Retrievals where 0 results were authorizedprint(activation.p95_latency_ms)            # End-to-end p95 latency

Pagination

List endpoints return a Page object. Use list_all() for automatic async pagination:

python
async for connector in client.connectors.list_all():    print(connector.name)

Rate Limits

Three endpoints enforce per-org-per-minute limits:

EndpointLimit
POST /api/retrievals/execute60/min
POST /api/answers/execute20/min
POST /api/simulator/preview10/min

Exceeded limits raise RateLimitError. The SDK retries automatically with exponential backoff (configurable via max_retries). Limits are org-scoped and reset on process restart (in-memory implementation).


Error Handling

python
from gateco_sdk.errors import NotFoundError, RateLimitError, AuthenticationError
try:    conn = await client.connectors.get("nonexistent-id")except NotFoundError:    print("Connector not found")except RateLimitError as e:    print(f"Rate limited — retry after {e.retry_after}s")except AuthenticationError:    print("Invalid or expired credentials")

CLI

The gateco command is installed with the SDK and uses the same credentials.

bash
# Log in once; you are prompted for the password (or pipe it on stdin).# Passing --password on the command line works but lands in shell history.gateco login --email [email protected]
gateco whoami                       # base URL, credential in use, key scopes
# Connectors: inspect and configure (user session only)gateco connectors listgateco connectors get <connector_id>gateco connectors get-search-config <connector_id>gateco connectors set-search-config <connector_id> --json '{"table_name": "docs", "vector_column": "embedding", "content_column": "text"}'gateco connectors get-ingestion-config <connector_id>gateco connectors set-ingestion-config <connector_id> --file ingestion.json
# Ingest: .txt/.md are sent as text; PDF, Word, PowerPoint, Excel and CSV are uploadedgateco ingest report.txt --connector-id <id> --classification confidential --sensitivity highgateco ingest "Q3 board deck.pdf" --connector-id <id> --classification confidential --sensitivity high --domain financegateco ingest-batch ./documents --connector-id <id> --glob "*.md"
# Retrieve as a principal (API key with the retrieve scope, or a session)gateco retrieve --connector-id <id> --principal-id <id> --query "revenue report" --search-mode hybrid

--classification accepts public, internal, confidential, restricted; --sensitivity accepts low, medium, high, critical (gateco ingest --help lists them).


MCP Server (Model Context Protocol)

The optional MCP server lets AI agents (Claude Desktop, Cursor, etc.) perform permission-aware retrieval without any custom code.

bash
pip install gateco[mcp]
# Start the servergateco mcp serve
# Or use the direct entry point (for MCP host configs)gateco-mcp

Claude Desktop Configuration

json
{  "mcpServers": {    "gateco": {      "command": "gateco-mcp",      "env": {        "GATECO_API_KEY": "gck_live_abc123...",        "GATECO_BASE_URL": "https://api.gateco.ai"      }    }  }}

Available MCP Tools

ToolDescription
gateco_retrievePermission-aware retrieval (vector/keyword/hybrid/grep)
gateco_askGrounded answer synthesis with search modes (Team+)
gateco_check_accessDry-run access simulation (Growth+). User session only (gateco login); not callable with an API key
gateco_list_connectorsList connectors with readiness levels
gateco_list_principalsList identity principals
gateco_list_groupsList groups (IdP-synced and local directory) with live member counts. Works with a retrieve-scoped key against a backend from 2026-10-02 on; older backends answer that a user session is needed
gateco_resolve_principalResolve a principal by email or provider subject

All tools return markdown-formatted text. Denied content is never exposed — only denial reasons and counts are shown.


Development

bash
pip install -e ".[dev]"pytest -v
# Run MCP server testspytest tests/test_mcp/ -v
# With coveragepytest --cov=src/gateco_sdk

Links

來源:README.md,提交 d188b83

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

3
  1. v1.13.0最新Oct 4, 2026
  2. v1.12.1Sep 27, 2026
  3. v1.11.1Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分