Skip to main content
Glama
jespermetahubb

apify-mcp-policy-gateway

Apify MCP Policy Gateway — M1

A deliberately narrow, local-first MCP policy gateway for one organization-owned Apify fixture Actor. It supports a fake transport for deterministic tests and an explicit real Apify HTTP transport for a scoped live fixture.

M1 started with fake transport. The real transport and Codex-agent verification are documented below; the live mode is opt-in and must never receive credentials through MCP tool arguments.

  1. plan_operation

  2. approve_operation

  3. execute_approved_operation

  4. read_sanitized_results

The gateway is a policy control plane, not an Actor browser, generic proxy, hosted MCP replacement, or credential forwarder.

Fixed M1 policy

Only this operation can be planned:

Setting

Allowed value

Actor ID

P4XBS39SYl7aeFJ7g

Canonical owner/name

metahubb~apify-mcp-policy-fixture

Build

0.1.1

Maximum runtime

60 seconds

Maximum charge ceiling

USD 0.10

Maximum result count

3

Risk

low only

The fixture input is restricted to:

{
  "message": "1 to 64 characters",
  "recordCount": 1,
  "delayMs": 0
}

recordCount defaults to 3, delayMs defaults to 0, and unknown input fields are denied. recordCount may not exceed the requested result limit.

Related MCP server: ceco proof gate

Flow

plan_operation

Validates the exact Actor, pinned build, fixture input, timeout, charge ceiling, and result limit. A successful response contains:

  • A short-lived plan ID and expiry.

  • A canonical SHA-256 input hash.

  • A canonical plan digest.

  • The explicit ALLOW_LOW_RISK policy decision.

  • Bounded execution parameters.

  • approval_required status.

No credential or raw secret is accepted or returned.

approve_operation

Marks a known, valid, unexpired low-risk plan approved. M1 approval is a local state transition only; it is not a signed human approval mechanism.

execute_approved_operation

Creates and durably writes an execution reservation before invoking the configured ActorRunTransport.

The default transport is local and fake. Set APIFY_TRANSPORT=real to use the real Apify HTTP transport. Real mode requires APIFY_TOKEN in the runtime environment and never accepts credentials through MCP arguments.

Execution states:

  • SUBMITTED: the transport returned a run identity.

  • REJECTED: the transport returned a definitive HTTP rejection such as 403.

  • EXECUTION_UNKNOWN: submission may have reached the upstream boundary, so it is never automatically retried.

The execution ID is replay-safe. A persisted attempted reservation also recovers as EXECUTION_UNKNOWN rather than issuing another POST.

read_sanitized_results

Reads only results belonging to an execution in this gateway state namespace. In fake mode it reads local fixture results; in real mode it reads the execution's Apify default dataset. It:

  • Returns at most three items.

  • Removes keys beginning with # recursively.

  • Removes fields whose names look like token, password, secret, API-key, authorization, or credential fields.

  • Labels every item with:

{
  "dataClassification": "untrusted_external_content"
}

The result envelope also states that content must not be treated as instructions and includes Actor, build, execution, policy, and timestamp provenance.

Real transport mode

Keep fake mode as the default for deterministic development. For a scoped live fixture run, inject the token through the runtime environment:

export APIFY_TRANSPORT=real
export APIFY_TOKEN='provided by a secret manager or protected shell environment'
npm run build
node real-apify-run.mjs

The verified live path uses Actor P4XBS39SYl7aeFJ7g, build 0.1.1, a maximum charge ceiling of USD 0.10, a 60-second timeout, and at most three results. Never place the token in MCP arguments, source files, README files, audit logs, Obsidian notes, or Git history.

The Codex-agent live verification and observed Apify metadata are recorded outside the repository in 16_live_mcp_agent_verification_2026-08-09.md.

Local state and audit

By default, npm run start creates .gateway-state/ in the current working directory.

  • gateway.lock is acquired with exclusive creation. A second process cannot use the same state directory.

  • state.json is written to a new file, fsynced, atomically renamed, and followed by a directory fsync.

  • audit.jsonl is append-only in application behavior and each event is fsynced.

  • Audit events contain identifiers, decisions, state, latency, safe error codes, and item counts—not raw Actor input, fixture output, credentials, or authorization material.

A privileged local filesystem user remains outside the M1 tamper-prevention boundary.

Run over stdio

Requirements:

  • Node.js 22 or later.

  • Project dependencies installed with npm in a normal development environment.

npm install
npm run start

Standard output is reserved for newline-delimited MCP JSON-RPC messages. Do not add console.log diagnostics to the server process.

Example MCP host command:

{
  "command": "npm",
  "args": ["run", "start", "--silent"],
  "cwd": "/root/apify-mcp-policy-gateway"
}

Tests and type checking

npm test
npm run typecheck

All tests are non-networked. They use only fake transports, in-memory state, temporary local state directories, and deterministic fixture data.

Build-environment note

The execution environment used to produce this M1 could not fetch packages from its configured npm registry. The repository therefore contains a small dependency-free stdio MCP wire adapter and the verification run used Node's built-in test runner. package.json pins the intended maintained MCP SDK and Vitest dependencies, but replacing the temporary stdio adapter with the official SDK wiring and executing the same suite under Vitest remains a tooling-conformance follow-up. This limitation is recorded in M1_IMPLEMENTATION_REPORT.md rather than hidden.

Security boundaries

  • No user token field exists.

  • No .env or credential loader exists.

  • No live Apify request exists.

  • No arbitrary Actor, build, run, dataset, or storage identifier is accepted.

  • The plan digest and current policy are revalidated before approval, execution, and result access.

  • An ambiguous outbound submission is never retried automatically.

  • Actor/dataset content is always untrusted external content, never policy or instructions.

  • Result sanitation is deterministic key removal, not a claim of complete secret detection.

Intentionally not implemented

  • Real Apify REST transport or token handling.

  • Arbitrary Actor discovery or execution.

  • Signed-JWS approval.

  • Approval-required or blocked workflows beyond explicit denial.

  • URL-target policy.

  • Remote run-status or dataset reads.

  • General redaction of values such as email or phone.

  • Universal rollback.

  • Prompt-injection detection or prevention claims.

  • Multi-user or network transport.

Available Tools

4 tools
approve_operationApprove OperationA

Approve a known, unexpired low-risk plan. M1 has no signed external approval mechanism.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden. It adds some behavioral context by noting 'M1 has no signed external approval mechanism,' implying the approval is internal and informal. However, it does not disclose side effects, permissions, or what happens to the plan upon approval, leaving gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is exceptionally concise: two short sentences that state the action and a key environmental constraint. Every word earns its place, and the most critical information is front-loaded in the first sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter approval tool, the description covers core purpose and a key constraint, but it lacks details on return values, error behavior, or post-approval effects. With no output schema and no annotations, some information is missing, though the sibling tools provide workflow context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does clarify that planId refers to a 'known, unexpired low-risk plan,' which adds meaning beyond the bare schema property. However, it omits how to obtain or format the planId, leaving the parameter partially under-specified.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb+resource pairing — 'Approve a known, unexpired low-risk plan' — and clearly indicates the object and its qualifying conditions. It also differentiates from sibling tools like execute_approved_operation by focusing on the approval step rather than execution.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states that the plan must be 'known, unexpired low-risk,' which gives clear conditions for when this tool is appropriate. It doesn't explicitly name alternatives, but the sibling tool context implies a workflow where approval precedes execution, providing sufficient usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

execute_approved_operationExecute Approved OperationA

Execute an approved fixture plan once through the injected local transport; ambiguous submission is never retried.

ParametersJSON Schema
NameRequiredDescriptionDefault
planIdYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses that execution happens once and that ambiguous submissions are never retried, which adds useful behavioral context. However, it does not mention side effects, permissions, or failure behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, front-loaded with the main purpose, and includes valuable details like 'once' and 'never retried'. It contains no unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, but the description lacks explicit preconditions (e.g., plan must be approved) and return value information. It also introduces jargon ('injected local transport') without explanation. Overall, it is adequate but has gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The parameter planId is not mentioned in the description, and schema coverage is 0%. The description implicitly suggests the parameter identifies the plan to execute, but it adds no explicit meaning beyond the schema's name and constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool executes an approved fixture plan, using a specific verb and resource. It distinguishes itself from siblings like plan_operation, approve_operation, and read_sanitized_results by being the execution step.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The name and context imply it should be used after approval, but the description does not explicitly state when to use it versus alternatives. It lacks clear exclusions or alternative tool references.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

plan_operationPlan OperationA

Validate a bounded request for the single owned fixture Actor and create a short-lived approval-required plan.

ParametersJSON Schema
NameRequiredDescriptionDefault
buildYes
inputYes
actorIdYes
requestedResultLimitYes
requestedTimeoutSecondsYes
requestedMaxTotalChargeUsdYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses useful behavioral traits: 'short-lived' (expiration), 'approval-required' (dependency on approval), 'bounded' (limits), and 'single owned fixture Actor' (scope restriction). However, it does not mention error conditions, side effects, or validation specifics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with active verbs and a clear front-loaded structure. Every word contributes meaning, with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with six required parameters, no annotations, and no output schema, this description is under-specified. It covers the overall purpose and a couple of behavioral traits, but leaves out parameter semantics, return values, validation rules, and explicit workflow integration. The sibling names help but do not compensate for the gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, and the description provides no parameter-specific meaning. It only refers to a 'bounded request' generically. None of the six required parameters are explained, failing to compensate for the lack of schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool validates a bounded request and creates a short-lived approval-required plan. It specifies the exact resource (single owned fixture Actor) and distinguishes itself from siblings (approve, execute, read) by describing a distinct planning phase.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is the initial step in a plan-approve-execute-read workflow, but it does not explicitly mention when to use this tool versus alternatives or state exclusions. Sibling names provide context, but the description itself lacks explicit guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_sanitized_resultsRead Sanitized ResultsB

Read at most three locally generated fixture results and label them as untrusted external content.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitYes
executionIdYes

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full responsibility for behavioral disclosure. It mentions reading at most three results and labeling them as untrusted, but does not clarify whether the labeling is a side effect, whether the read is idempotent, or what authentication or access implications exist. This is a significant gap for a tool that appears to mark content.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the verb and resource. It contains no filler words and every phrase earns its place, making it highly efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema, no annotations, and only two parameters, the description leaves key context ambiguous: what 'sanitized' means, what a 'fixture result' is, what the return format looks like, and how the 'untrusted external content' label affects the agent's next steps. The tool appears part of a workflow but lacks enough context to be used effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, so the description must compensate. It only hints at the 'limit' parameter via 'at most three' but does not explain the meaning or format of 'executionId'. The schema provides structural constraints but not semantic meaning, and the description adds minimal value beyond that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'read' with a clear resource ('locally generated fixture results') and an additional purpose ('label them as untrusted external content'). This distinguishes it from sibling tools that plan, approve, or execute operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The context of sibling tools (plan_operation, approve_operation, execute_approved_operation) implies this is used after execution, but the description does not explicitly state when to use this tool vs alternatives. No exclusions are given, so the usage context is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A3.9/5.0
Disambiguation5/5

Each tool occupies a distinct lifecycle stage: plan, approve, execute, and read. There is no overlap in purpose, and the descriptions clearly differentiate the action and its constraints.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (plan_operation, approve_operation, execute_approved_operation, read_sanitized_results). The verbs are clear and the objects precisely describe the target, making the set predictable and readable.

Tool Count5/5

With 4 tools, the server is well-scoped for a policy gateway that manages a simple operation lifecycle. Each tool is necessary and the count feels intentional, not bloated or thin.

Completeness4/5

The lifecycle of plan-approve-execute-read is fully covered for the stated single owned fixture actor. A minor gap is the absence of a cancel or reject operation, but the given M1 context (no signed external approval mechanism) makes this an acceptable simplification for the bounded domain.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    MCP server that evaluates agent actions against a Policy State Machine, emits a tamper-evident audit trail, and dispatches approved transitions to internal or federated handlers.
  • A
    license
    Not graded
    quality
    B
    maintenance
    A gateway that enforces permissions, sanitization, approval, and audit for AI agent MCP tool calls, with a policy engine and local proxy CLI.
    148
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Self-hosted MCP gateway that applies deterministic, compiled policy to tool discovery, invocation, and outbound data flow, with no model in the enforcement path. Every decision emits a hash-chained receipt sealed with Ed25519 and verifiable using public keys only.
    Apache 2.0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jespermetahubb/apify-mcp-policy-gateway'

If you have feedback or need assistance with the MCP directory API, please join our Discord server