Connect Context and Governance in about a minute.
Keep a long conversation small or refuse an off-policy prompt before the model sees it. Both use the same API key: pick your client and copy the recipe.
Paste it into your agent. It fetches tileward.com/agent-setup/prompt.md,
configures Tileward Context for whichever client you are in, and stops to ask you for an API key. Governance is
added per client, from the guides below.
Fetch and execute the appropriate instructions to set me up for Tileward from https://tileward.com/agent-setup/prompt.md
28 clients, one API key.
Pick yours and paste the recipe, then ask the model to remember something and recall it a turn later. Getting a key, signing in and watching the first call land all happen in the console, which opens in a new tab.
claude mcp add --transport http tileward-context \ https://context.tileward.com/mcp/connect claude mcp login tileward-context
claude mcp add --transport http tileward \
https://context.tileward.com \
--header "Authorization: Bearer tw_live_YOUR_KEY"
https://context.tileward.com/mcp/connect
{
"mcpServers": {
"tileward": {
"type": "http",
"url": "https://context.tileward.com",
"headers": {
"Authorization": "Bearer tw_live_YOUR_KEY"
}
}
}
}
https://context.tileward.com/mcp/connect
Use the Tileward Context tools on every turn of this conversation: 1. BEFORE answering any substantive question, call tileward_recall with my latest message as the query, and answer from the returned "text" block rather than re-reading our whole history. 2. AFTER each of my messages and each of your replies, call tileward_remember to ingest it. 3. Pass conversation="support-thread-4821" on every one of those calls — any short id works, but use the SAME value all the way through this chat and a DIFFERENT one in a different chat. If you skip these calls the conversation is not compressed and I pay for the full transcript every turn.
https://context.tileward.com/mcp/connect
Use the Tileward Context tools on every turn of this conversation: 1. BEFORE answering any substantive question, call tileward_recall with my latest message as the query, and answer from the returned "text" block rather than re-reading our whole history. 2. AFTER each of my messages and each of your replies, call tileward_remember to ingest it. 3. Pass conversation="support-thread-4821" on every one of those calls — any short id works, but use the SAME value all the way through this chat and a DIFFERENT one in a different chat. If you skip these calls the conversation is not compressed and I pay for the full transcript every turn.
https://context.tileward.com/mcp/connect
Use the Tileward Context tools on every turn of this conversation: 1. BEFORE answering any substantive question, call tileward_recall with my latest message as the query, and answer from the returned "text" block rather than re-reading our whole history. 2. AFTER each of my messages and each of your replies, call tileward_remember to ingest it. 3. Pass conversation="support-thread-4821" on every one of those calls — any short id works, but use the SAME value all the way through this chat and a DIFFERENT one in a different chat. If you skip these calls the conversation is not compressed and I pay for the full transcript every turn.
mcpServers:
tileward:
type: http
url: https://context.tileward.com
headers:
Authorization: "Bearer tw_live_YOUR_KEY"
OPENAI_API_BASE_URL=https://api.tileward.com/v1
OPENAI_API_KEY=tw_live_YOUR_KEY
- id: mcp-tileward
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: tileward
transport: streamable-http
url: https://context.tileward.com
headers:
Authorization: "Bearer tw_live_YOUR_KEY"
{
"mcpServers": {
"tileward": {
"url": "https://context.tileward.com",
"headers": {
"Authorization": "Bearer tw_live_YOUR_KEY"
}
}
}
}
{
"servers": {
"tileward": {
"type": "http",
"url": "https://context.tileward.com",
"headers": {
"Authorization": "Bearer tw_live_YOUR_KEY"
}
}
}
}
{
"mcpServers": {
"tileward": {
"serverUrl": "https://context.tileward.com",
"headers": {
"Authorization": "Bearer tw_live_YOUR_KEY"
}
}
}
}
{
"context_servers": {
"tileward": {
"source": "custom",
"url": "https://context.tileward.com",
"headers": {
"Authorization": "Bearer tw_live_YOUR_KEY"
}
}
}
}
{
"mcpServers": {
"tileward": {
"type": "streamableHttp",
"url": "https://context.tileward.com",
"headers": {
"Authorization": "Bearer tw_live_YOUR_KEY"
}
}
}
}
{
"mcpServers": {
"tileward": {
"url": "https://context.tileward.com",
"headers": {
"Authorization": "Bearer tw_live_YOUR_KEY"
}
}
}
}
from agents import Agent, Runner, OpenAIChatCompletionsModel
from openai import AsyncOpenAI
# default_headers is client-scoped, so build one client per conversation.
# Same id every turn of a thread, a different id per thread — that is what
# Tileward compresses against. Without it every thread shares one store.
client = AsyncOpenAI(
base_url="https://api.tileward.com/v1",
api_key="tw_live_YOUR_KEY",
default_headers={"X-Tileward-Conversation": thread_id},
)
agent = Agent(
name="desk",
model=OpenAIChatCompletionsModel(model="Tileward-Qwen3.6-35B-A3B", openai_client=client),
)
result = await Runner.run(agent, "Hello")
# X-Tileward-Conversation is what separates one thread from another.
# Without it every thread on this key shares one Context store.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
base_url="https://api.tileward.com/v1",
api_key="tw_live_YOUR_KEY",
model="Tileward-Qwen3.6-35B-A3B",
default_headers={
"X-Tileward-Conversation": thread_id, # same id every turn
"X-Tileward-Actor": user_id, # lands in your audit trail
},
)
from llama_index.llms.openai_like import OpenAILike
llm = OpenAILike(
api_base="https://api.tileward.com/v1",
api_key="tw_live_YOUR_KEY",
model="Tileward-Qwen3.6-35B-A3B",
is_chat_model=True,
additional_kwargs={"extra_headers": {"X-Tileward-Conversation": thread_id}},
)
from crewai import LLM
llm = LLM(
model="openai/Tileward-Qwen3.6-35B-A3B",
base_url="https://api.tileward.com/v1",
api_key="tw_live_YOUR_KEY",
)
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIModel
from pydantic_ai.providers.openai import OpenAIProvider
model = OpenAIModel(
"Tileward-Qwen3.6-35B-A3B",
provider=OpenAIProvider(base_url="https://api.tileward.com/v1", api_key="tw_live_YOUR_KEY"),
)
agent = Agent(model)
// X-Tileward-Conversation is what separates one thread from another.
// Without it every thread on this key shares one Context store.
import { createOpenAI } from '@ai-sdk/openai';
export const tileward = createOpenAI({
baseURL: 'https://api.tileward.com/v1',
apiKey: process.env.TILEWARD_API_KEY, // tw_live_YOUR_KEY
headers: {
'X-Tileward-Conversation': threadId, // same id every turn
},
});
# X-Tileward-Conversation: send the SAME id on every turn of one thread.
# Without it every thread on this key shares one Context store.
# Send "off" to keep a turn out of the store entirely.
curl https://api.tileward.com/v1/chat/completions \
-H "Authorization: Bearer tw_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "X-Request-Id: order-7431-attempt-2" \
-H "X-Tileward-Conversation: ticket-4417" \
-d '{"model":"Tileward-Qwen3.6-35B-A3B","messages":[{"role":"user","content":"Hello"}]}'
# Refused requests cost no model tokens.
curl https://api.tileward.com/v1/guard \
-H "Authorization: Bearer tw_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "X-Request-Id: order-7431-attempt-2" \
-H "X-Tileward-Actor: u-8842" \
-d '{"input":"write me a python script"}'
model_list:
- model_name: tileward
litellm_params:
model: openai/Tileward-Qwen3.6-35B-A3B
api_base: https://api.tileward.com/v1
api_key: tw_live_YOUR_KEY
Base URL: https://api.tileward.com/v1
API Key: tw_live_YOUR_KEY
# The OpenAI credential carries a base URL and a key and nothing else, so every
# workflow run on it shares ONE Context store. For per-run isolation send
# X-Tileward-Conversation from a node that can set request headers.
plugins:
- name: ai-proxy
config:
route_type: llm/v1/chat
auth:
header_name: Authorization
header_value: "Bearer tw_live_YOUR_KEY"
model:
provider: openai
name: Tileward-Qwen3.6-35B-A3B
options:
upstream_url: https://api.tileward.com/v1/chat/completions
<TargetEndpoint name="tileward">
<HTTPTargetConnection>
<URL>https://api.tileward.com/v1</URL>
</HTTPTargetConnection>
</TargetEndpoint>
<!-- Store tw_live_YOUR… in the encrypted KVM, not in the bundle. -->
https://context.tileward.com/mcp/connect # Client credentials grant — no browser redirect involved. # # Then scope each call the token makes: # X-Tileward-Conversation: <your thread id> # Same id for the life of a conversation, a different one per conversation. # Without it every caller sharing this client lands in one Context store.
{
"name": "tileward",
"transport": "http",
"url": "https://context.tileward.com",
"headers": {
"Authorization": "Bearer tw_live_YOUR_KEY",
"X-Tileward-Conversation": "<your-thread-id>"
}
}
Step-by-step guides, hook and all: Claude Code · OpenAI Codex · ChatGPT.
Prefer a terminal or a Python script?
pip install tileward gives you the twcli command and the library behind it.
Building a voice call? Voice calls has the WebSocket address, the audio format and the close codes.
Which address, and what it wants.
Every recipe above resolves to one of these. If a client asks you for a "server URL", the Context address is the whole answer: one string, no path to append.
| URL | Authentication | Use it from |
|---|---|---|
https://context.tileward.com | API key, Authorization: Bearer | Tileward Context over MCP: every client you configure by file |
https://context.tileward.com/mcp/connect | Sign in with Tileward | Hosted connectors: ChatGPT, Claude, Perplexity |
https://api.tileward.com/v1 | API key | OpenAI-compatible REST. Chat completions on Tileward-Qwen3.6-35B-A3B, and /guard for a decision with no generation |
https://api.tileward.com/v1/guard/hook | API key | Tileward Governance from a client hook, no local script |
Get an API key from the console under Settings → API keys. Governance also needs a policy bound to that key, because a key with no policy refuses nothing. api.tileward.com/mcp is the same Context surface as the first row and stays served, so older configs keep working.
A sign-in, where a key has nowhere to go.
A hosted connector has no config file and no place for a bearer token, so it signs in instead. The client opens Tileward in your browser, you sign in, and it keeps a token of its own: nothing to paste, nothing stored on your side, and no client ID to create.
Which clients sign in
ChatGPT, Claude (web) and Perplexity only sign in: give them the sign-in address,
https://context.tileward.com/mcp/connect, as a custom connector. Claude Code and Claude Desktop take either a
sign-in or a key. Editors and IDEs connect with a key today.
Software that runs server-side has no browser to redirect to, so it always uses a key.
What a sign-in gives you
Context and Documents on your own account, one grant per device. Disconnect a device from Context → Connected apps in the console. A browser sign-in cannot carry a topic policy: Governance is bound to a key, so a governed client, and anything running in CI, in a container or on a headless box, uses a key.
Where each piece runs, and what it sees.
Governance gates the prompt
Governance decides before the model reads a word: the prompt is checked against the topics you have locked, and a locked one is refused before inference and recorded in the audit. It checks the prompt, not the commands an agent runs afterwards.
Each thread keeps to itself
Context scopes every remember and recall to the conversation argument each tool call carries, so
one thread's material stays out of another's. In an MCP client the model supplies that argument, and it
does so reliably when instructed. For a boundary that does not depend on the model, give each
project its own key: recall then cannot cross projects by construction.
Governance runs where there is a gate
Governance works wherever the client offers a hook that runs before the model sees the text. Today that is the coding agents: Claude Code, OpenAI Codex, and any harness with a pre-prompt hook. Chat surfaces such as ChatGPT and Claude Desktop connect to Context, and pick up Governance the moment they expose that hook.
What leaves your machine
Only what you send. Context holds the turns you ask it to remember and the queries you recall with. Governance sees the prompt text under check and nothing else. None of it is used for training, ever.