Tileward / Docs / Claude Code
Docs · Claude Code

Tileward in Claude Code.

Context as an MCP server, Governance as a hook that runs before the model. Context takes a sign-in or a key; Governance takes a key, because the policy is bound to it. There is no server to run on your machine.

Context

Recall instead of resend.

One command. No local server, no Python, no database: the history lives on our side, and each turn asks for the part that answers the question.

claude mcp add --transport http tileward-context https://context.tileward.com \
  --header "Authorization: Bearer $TILEWARD_API_KEY"

Restart, then /mcp lists the tools. Ask the model to remember something, start a new thread, and ask it to recall. That round trip is the whole product.

Or sign in instead of pasting a key

Add the same server at the sign-in address, then log in once: Claude Code opens your browser, you sign in, and it keeps a token of its own. Nothing to paste, and you can disconnect this device from Context → Connected apps in the console.

claude mcp add --transport http tileward-context https://context.tileward.com/mcp/connect
claude mcp login tileward-context

Take the key when this runs in CI, in a container or on a headless box, or when one credential should also carry the Governance hook below: a sign-in cannot carry a topic policy.

Each remember and recall carries a conversation argument that the model fills in, so one thread's material stays out of another's. For a boundary that does not depend on the model, give each project its own key.

Governance

A gate, not a system prompt.

Claude Code runs a UserPromptSubmit hook before the model sees a prompt and honours its refusal. A refused prompt costs no generation tokens. The gate ships as a plugin.

claude plugin marketplace add Tileward-com/tileward-claude-marketplace
claude plugin install tileward-guard@tileward
export TILEWARD_API_KEY=tw_live_...

The plugin registers a small script that runs before each prompt and refuses on the policy bound to your key. /hooks in a session shows it loaded.

Bind a policy to the key first, in the console under Settings → API keys. A key with no policy refuses nothing.

Without installing anything

You can also point the hook at Tileward directly and deploy nothing. Claude Code lets a prompt through when it cannot reach an HTTP hook, so this shape suits a setup that can tolerate an outage.

// .claude/settings.json
{
  "hooks": {
    "UserPromptSubmit": [{
      "matcher": "",
      "hooks": [{
        "type": "http",
        "url": "https://api.tileward.com/v1/guard/hook",
        "headers": { "Authorization": "Bearer $TILEWARD_API_KEY" },
        "allowedEnvVars": ["TILEWARD_API_KEY"],
        "timeout": 10
      }]
    }]
  }
}

The address is /v1/guard/hook, which answers in the shape Claude Code's hooks expect. The plain /v1/guard on the endpoint table is the same guard for calling from your own code.

For an organisation

Make it a control, not a guardrail.

The configuration above is a developer's choice. Managed settings make it the organisation's: they apply to everyone, and a user cannot override them.

// managed-settings.json
{
  "extraKnownMarketplaces": {
    "tileward": { "source": { "source": "github", "repo": "Tileward-com/tileward-claude-marketplace" } }
  },
  "enabledPlugins": { "tileward-guard@tileward": true },
  "allowManagedHooksOnly": true,
  "strictKnownMarketplaces": true,
  "disableSideloadFlags": true
}

Each line closes a specific door, and dropping any one turns enforcement back into a suggestion. enabledPlugins force-enables the plugin, so a user cannot uninstall it. allowManagedHooksOnly loads only managed hooks and force-enabled plugins, so a developer cannot unhook themselves. strictKnownMarketplaces stops them adding their own sources, and disableSideloadFlags rejects the command-line flags that would bypass both for a single run.

Managed settings live at /Library/Application Support/ClaudeCode/managed-settings.json on macOS, /etc/claude-code/managed-settings.json on Linux and C:\Program Files\ClaudeCode\managed-settings.json on Windows, or are pushed from the claude.ai admin console. Verify on one machine before rolling out: a plugin that cannot be fetched never loads, and a hook that does not load does not run.

Failing closed

What happens when Tileward is unreachable.

With the plugin, the prompt is blocked. With a direct HTTP hook, it runs: Claude Code logs an unreachable HTTP hook as an error and sends the prompt on.

The plugin's script runs on the machine, so an unreachable Tileward, a missing key or a crash all block, with the reason shown. Set TILEWARD_FAIL_OPEN=1 in the environment if you would rather a prompt ran during an outage.

Claude Code lets the prompt through if a local hook exceeds its timeout, so the script keeps its own timeout under the hook's.

Other guides: OpenAI Codex · ChatGPT. Every other client, and the endpoint table: the connect guide.