Package map¶
2.1 Top level¶
| File | Lines | Role |
|---|---|---|
__init__.py |
138 | Public re-exports and three lazy helpers |
__main__.py |
10 | python -m cloudg.mcp |
core.py |
827 | Errors, enums, content types, specs, Registry |
schema.py |
142 | JSON Schema from signatures, argument validation |
context.py |
149 | Principal, ToolContext |
layer.py |
754 | CloudGMCPLayer, CallInfo, dispatch |
state.py |
1255 | Dataset, Workspace, loaders, diff |
policy.py |
1172 | Policy (see MCP_PRIVACY.md) |
middleware.py |
597 | Audit, metrics, cache, concurrency, retry |
server.py |
632 | serve, serve_async, create_layer_from_options, ASGI auth |
cli.py |
581 | The cloudg mcp click group |
__init__.py re-exports the names most programs need (CloudGMCPLayer, CallInfo,
Principal, ToolContext, the spec and content classes, the five error classes, Policy,
available_profiles, Dataset, Workspace, Pipeline, TokenVault,
TransformContext, build_transform) and defines default_registry(),
register_into(layer, server, **kw), build_server(layer, flavor) and
export_definitions(layer, principal) as thin wrappers that import the adapters only when
called. Importing cloudg.mcp therefore never imports mcp.
__main__.py calls cloudg.mcp.cli.main(), which runs the click group with
prog_name="cloudg-mcp"; the console script cloudg-mcp points at the same function.
core.py holds everything framework-agnostic: META_PREFIX = "cloudg/"; the error
hierarchy (MCPLayerError -32603, InvalidArgumentsError -32602, NotFoundError -32602,
AccessDeniedError -31001, RateLimitedError -31029); the Sensitivity enum (public,
internal, confidential, restricted, ordered by SENSITIVITY_ORDER); the Capability enum
(read_state, write_state, read_fs, write_fs, cloud_access, exec, reveal);
ToolAnnotations, ContentAnnotations and Icon; the content dataclasses (TextContent,
ImageContent, ResourceLink, EmbeddedResource, TextResourceContents,
BlobResourceContents); ToolResult, PromptMessage, PromptResult; the four specs and
PromptArgument; Registry; and maybe_await. Every class that goes on the wire has a
to_wire() returning MCP camelCase JSON.
schema.py turns a handler signature into a pydantic model and from there into the tool's
inputSchema, and validates incoming arguments with the same model (section 3.4).
context.py defines Principal (id, roles, attributes; Principal.local()), the MCP log
level table LOG_LEVELS, and ToolContext, the per-request object handed to every handler.
ToolContext carries the progress and log callbacks the adapter supplies, the collected
resource links, a free-form meta dict, and the event loop serving the request so a sync
handler can report progress from its worker thread.
layer.py is the dispatcher. It builds the registry view, owns the policy and middleware,
renders list results per principal, and runs the four request kinds (section 4). It also
holds DEFAULT_INSTRUCTIONS, the text sent to clients on initialize.
state.py holds the workspace: Dataset with lazily built and cached indexes and
analyses, Workspace with named datasets, the active selection, name checks, path safety,
change listeners and the per-workspace live_guard (a cloudg.resilience.LiveOperationGuard
built from the config's ratelimit section on first use), file loaders with format detection (detect_kind, load_dataset_file), and
diff_datasets. NoDatasetError and ReferenceNotFoundError subclass NotFoundError so a
tool handler's "not found" becomes an error result the model can read.
policy.py compiles a policy document (built-in profile, file, dict or inline JSON) into
access decisions, token-bucket rate limits, an audit ring buffer and per-principal
input/output transform pipelines. The layer uses Policy.load, vault, is_allowed,
check_call, output_pipeline, input_pipeline, describe, record_hidden (a call to an
unknown or hidden primitive), record_rejection (an input-pipeline refusal after
check_call allowed the call) and, in server.py, save_vault. Everything else about it is
in MCP_PRIVACY.md.
middleware.py provides AuditLogMiddleware, MetricsMiddleware (alias
TimingMiddleware) with register_metrics_resource, CachingMiddleware with
is_cacheable_tool, ConcurrencyLimitMiddleware and RetryMiddleware.
server.py hosts a layer as a standalone server with any flavor and transport, refuses
option combinations a flavor cannot honor (validate_serve_options), builds layers from
CLI-style options, and provides TokenAuthASGIMiddleware, which puts the shared
OriginHostGuard and bearer-token auth in front of SDK and fastmcp HTTP apps (section 7).
cli.py is the click group behind cloudg mcp and cloudg-mcp (section 7).
2.2 adapters/¶
| File | Lines | Role |
|---|---|---|
__init__.py |
196 | detect_server_kind, register_into, build_server, re-exports |
_common.py |
232 | Ownership checks, principal resolution, ChangeFanout, version helpers |
lowlevel.py |
578 | LowLevelBinding for the SDK's low-level Server, 1.x and 2.x |
mcp_sdk.py |
107 | High-level SDK servers, delegating to lowlevel.py |
fastmcp.py |
569 | FastMCPBinding for standalone fastmcp 2.x to 4.x |
export.py |
217 | export_definitions and the function-calling converters |
__init__.py classifies a server object and dispatches to the right install, and builds
fresh server objects for each flavor. _common.py holds what the adapters share: the
owns_tool / owns_prompt / owns_resource / owns_template checks that decide whether a
request belongs to cloudg or to the host, resolve_principal (custom resolver with fallback
to the default), lower_headers, normalize_kinds (validates include=),
package_version / major_version, and ChangeFanout, which forwards layer change events
to client sessions from any thread. lowlevel.py wraps the request handlers of an SDK
low-level server (section 5.2). mcp_sdk.py finds the low-level server inside MCPServer
or SDK FastMCP and applies lowlevel.py to it, and creates fresh SDK servers. fastmcp.py
registers fastmcp component subclasses plus a list-filtering middleware (section 5.4).
export.py produces wire definitions and handlers with no framework, and converts tools to
OpenAI, Anthropic and LangChain formats.
2.3 native/¶
| File | Lines | Role |
|---|---|---|
__init__.py |
61 | Re-exports |
jsonrpc.py |
141 | Protocol constants, message classification, error helpers |
protocol.py |
913 | NativeMCPServer, Session, method implementations |
stdio.py |
189 | run_stdio_async, protected_stdout |
http.py |
960 | NativeHTTPServer, HTTPConfig, legacy SSE |
auth.py |
223 | RequestInfo, TokenAuth, default_principal_resolver |
http.py also holds OriginHostGuard, the DNS-rebinding check that every HTTP flavor uses.
jsonrpc.py defines the supported protocol versions (handshake versions 2024-11-05 to
2025-11-25, the stateless 2026-07-28), the reserved _meta envelope keys, the error codes,
which methods return cacheable results, and small helpers (is_request, error_response,
dumps producing single-line JSON). protocol.py is the transport-independent engine: a
transport creates a Session per connection and feeds it decoded messages (section 6.2).
stdio.py and http.py are the two transports. auth.py turns transport facts into a
Principal and is also used by the SDK and fastmcp adapters, which is why it lives here and
has no dependencies.
2.4 catalog/¶
| File | Registers |
|---|---|
__init__.py |
CATEGORIES, default_registry() (all modules below, privacy guarded by ImportError) |
_common.py |
Nothing; argument type aliases (DatasetArg, RefArg, Limit, Cursor), brief builders, enum parsing, cursor pagination, output-schema models |
workspace.py |
8 tools (category workspace) |
inventory.py |
11 tools |
graph.py |
17 tools |
findings.py |
10 tools |
compliance.py |
5 tools |
ontology.py |
6 tools |
export.py |
3 tools |
live.py |
5 tools (four collecting, plus rate_limit_status) and cloudg://ratelimit; the credential preflight and the live-guard wrapper |
meta.py |
4 tools |
privacy.py |
5 tools (reveal_token among them) and 2 resources |
resources.py |
10 resources and 11 templates, with completions |
prompts.py |
11 prompts |
Each module exposes register(reg: Registry); the order in _modules() is the order tools
are listed. The tools themselves are documented in MCP_TOOLS.md. Two helpers
from _common.py matter when you write tools: paginate(items, limit, cursor, fp) with
fingerprint(ds, **filters) implements the c<offset>.<hash> cursors, and the *Out
pydantic models, every field optional and extra="allow", give output schemas that
projection and redaction cannot invalidate (schema(Model) renders one).
2.5 transforms/ and policies/¶
transforms/base.py defines TransformContext (principal, spec, kind, direction, vault and
a report dict) and Pipeline, an ordered list of objects with apply(value, ctx).
detectors.py, redaction.py, vault.py, substitution.py, projection.py and
annotation.py implement the transforms, and transforms/__init__.py maps transform type
names to factories (build_transform). policies/*.yaml are the built-in profiles: open,
standard, strict, read_only, airgapped, audit and soc-analyst. All of this is
covered in MCP_PRIVACY.md. The layer only touches TransformContext,
Pipeline.apply and the report.