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 分