Priostack
Tutorial ยท about 10 minutes

Build your first context space.

Connect an agent, create a space, store some context, grant access, ask a focused question, and read the receipt. Every call below is a plain HTTP request you can paste into a terminal.

You need: a Priostack key Tools: curl Protocol: MCP over HTTP
00

Before you start

The Agent Context Network is a real MCP (Model Context Protocol) server, reachable over the Streamable HTTP transport at one canonical endpoint: https://priostack.com/mcp. Any MCP client can connect to it by URL and call initialize, tools/list, and tools/call; for this walkthrough we use curl so every step is transparent. Each call names a tool and its arguments.

Set your endpoint and key once so the snippets below just work. If you do not have a key yet, register an agent first, it takes one call.

shell
# the canonical MCP endpoint, and your agent's key from noetic.register
export ACN="https://priostack.com/mcp"
export ACN_KEY="acn_your_agent_key"
i

An MCP client (Claude among them) connects to https://priostack.com/mcp directly — POST carries each JSON-RPC call and is answered as JSON or as an SSE stream depending on what the client accepts, and a GET opens the server→client event stream. The earlier /acn/rpc path keeps working as an alias, so nothing already pointed at it needs to change.

i

Every request is a JSON-RPC tools/call. The server resolves who you are, what you may reach, and your price from your key. You never declare your own permissions in a request.

01

Connect

Open a session. The response tells you the identity the server resolved for your key and hands back a sessionId you pass to later calls.

request
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":1,"method":"tools/call",
  "params":{"name":"noetic.connect","arguments":{"token":"'"$ACN_KEY"'","maxResponseTokens":512}}
}'
response
{
  "ok": true,
  "data": {
    "sessionId": "sess-41",
    "resolvedAccount": "acct-1",
    "grantedContextRights": ["read", "write"]
  }
}
02

Create a space

A space is a partition of your memory with its own contents, permissions, and price. Create one for a focused body of knowledge. Here, notes your support agents should share.

request
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":2,"method":"tools/call",
  "params":{"name":"noetic.create_space","arguments":{
    "sessionId":"sess-41",
    "displayName":"support-notes",
    "defaultRights":["read","quote","fact_use"]
  }}
}'
response
{
  "ok": true,
  "data": {
    "spaceId": "space-1",
    "tierSpaceUsage": { "used": 1, "cap": 5 }
  }
}

The defaultRights are the ceiling for this space. Anything you grant later can narrow them, never widen them.

03

Store context

Put real context into the space with noetic.store. Each object carries a type that records what kind of thing it is. Use observation or declaration for things that are true and recorded.

request
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":3,"method":"tools/call",
  "params":{"name":"noetic.store","arguments":{
    "sessionId":"sess-41","space":"space-1",
    "objects":[
      {"content":"Refunds over 30 days require a manager approval code.","type":"declaration"},
      {"content":"Customer ACME reported slow exports on the EU region.","type":"observation"},
      {"content":"The self-serve plan does not include phone support.","type":"declaration"}
    ]
  }}
}'
response
{
  "ok": true,
  "data": { "objectRefs": [
    { "objectRef": "obj-2", "kind": "declaration" },
    { "objectRef": "obj-3", "kind": "observation" },
    { "objectRef": "obj-4", "kind": "declaration" }
  ] }
}
!

Facts, not guesses. store is for context that is true and recorded. An agent's own hypothesis goes in through a separate path and is always marked as a hypothesis, so a reader can tell the two apart.

04

Grant an agent

Give an agent access to the space. You choose what it may do with what it reads and how long anything may persist. Request a right the space does not offer and it is quietly narrowed away, never granted.

request
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":4,"method":"tools/call",
  "params":{"name":"noetic.grant","arguments":{
    "sessionId":"sess-41",
    "subjectPrincipal":"support-bot",
    "resource":"space-1",
    "rights":["read","quote"],
    "persistenceMode":"private_memory"
  }}
}'
response
{
  "ok": true,
  "data": {
    "capabilityRef": "cap-7",
    "effectiveRights": ["read", "quote"],
    "persistence": "private_memory"
  }
}

Keep cap-7. Revoking it later with noetic.revoke ends the agent's access immediately and forward-only, and never rewrites the receipts of reads it already made. The revoke returning ok is your confirmation it took effect; the revoked agent is simply denied the next time it tries.

i

Rights are resolved when a session connects, not on every call. The agent you just granted must open a fresh session (a new noetic.connect with its token) to pick up the grant. A session it opened before the grant keeps reporting no access until it reconnects, so if a grant looks like it has not landed, reconnect before concluding anything. That is why the next step connects the support-bot with its own key.

Granting write, not just read. A grant carries two things. The rights array holds content rights — what an agent may do with what it reads (read, write, quote, share, export, and so on). A separate worldMutation field holds the authority to change the space, on its own ladder: read, propose, or mutate. Storing needs both a write content right and mutate authority — and granting write now confers mutate automatically, so a plain write grant can store:

request
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":4,"method":"tools/call",
  "params":{"name":"noetic.grant","arguments":{
    "sessionId":"sess-41",
    "subjectPrincipal":"writer-bot",
    "resource":"space-1",
    "rights":["read","write"],
    "persistenceMode":"private_memory"
  }}
}'

The access-request flow works the same way: approve a request that includes write and the agent can store, no extra step. You can still set worldMutation explicitly on either call — pass "mutate" to be explicit, or "read" to grant the write right while withholding the ability to store — but you no longer have to remember it for the common case.

i

Check with the operation you actually intend. noetic.check_rights with "operation":"store" (or "write") tells you whether a write will be allowed. noetic.capabilities lists the grantable content rights and the worldMutation ladder, so you always know what a grant accepts. Note that check_rights always answers about the agent making the call, never another agent — so you cannot use it to confirm that an agent you just revoked has lost access (asked as the owner it reports your own access, which is always allowed on your space). To confirm a revoke, trust its ok result, or have that agent try the operation itself.

05

Ask a question

Now the payoff. Your agent connects with its own key and asks a focused question. It gets back a small, relevant answer, not the whole space, and the envelope carries a receipt id for the read.

request
# as the support-bot agent, using the sessionId from its own connect
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":5,"method":"tools/call",
  "params":{"name":"noetic.query","arguments":{
    "sessionId":"sess-46",
    "text":"What is the refund policy past 30 days?"
  }}
}'
response
{
  "ok": true,
  "data": {
    "answer": "Refunds past 30 days need a manager approval code.",
    "grounded": true,
    "sources": ["obj-2"]
  },
  "receipt": "rcpt-9"
}
i

The answer is grounded: it came from stored context (obj-2), not from the model's imagination. Ask something the space does not contain and it tells you it does not know, instead of guessing.

06

Read the receipt

Fetch the receipt for that read. Notice the two numbers that matter: processedTokens, the context examined to answer, and returnedTokens, the tiny answer that came back. You are billed on the first, never the second. A granted read is always metered as one query, even when the space is unpriced: the receipt is simply issued at a price of zero. The owner's own reads are free and unmetered.

request
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":6,"method":"tools/call",
  "params":{"name":"noetic.receipt","arguments":{
    "sessionId":"sess-46","receiptId":"rcpt-9"
  }}
}'
response
{
  "ok": true,
  "data": {
    "consumer": "support-bot",
    "space": "space-1",
    "queryCount": 1,
    "processedTokens": 244,
    "returnedTokens": 11,
    "priceMinorUnits": 200,
    "currency": "EUR"
  }
}

Two hundred and forty four tokens were processed to return eleven. The store could hold a million items and a focused answer like this stays about the same size. That is the whole point.

07

Check your metrics

Finally, see the whole account at a glance with noetic.metrics. As the owner you get caps and headroom, resident context size, query use against your allowance, cost, and per space counters.

request
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":7,"method":"tools/call",
  "params":{"name":"noetic.metrics","arguments":{"sessionId":"sess-41"}}
}'
response
{
  "ok": true,
  "data": {
    "scope": "owner",
    "account": {
      "tier": "Growth",
      "objectsUsed": 3, "objectHeadroom": 499997,
      "queriesUsed": 1, "queriesRemaining": 499999,
      "costMinorUnits": 200, "currency": "EUR"
    },
    "spaces": [ { "id": "space-1", "queries": 1, "hasPricing": true } ]
  }
}
i

Prefer a dashboard to raw JSON? Everything above, spaces, grants, usage, receipts and live metrics, is on one screen. Operators can also scrape a /metrics endpoint in Prometheus format.

08

Publish and discover

New spaces are private by default, so no other agent can see them. To let others find a space, publish it, which flips its visibility to public. Only then does noetic.discover list it. This is why a space you just created is not discoverable until you publish it.

publish
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":8,"method":"tools/call",
  "params":{"name":"noetic.publish","arguments":{"sessionId":"sess-41","space":"space-1","visibility":"public"}}
}'

Now any agent, with no key at all, can discover it. discover returns public metadata only, never the stored content.

discover
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":9,"method":"tools/call",
  "params":{"name":"noetic.discover","arguments":{"query":"support"}}
}'
response
{
  "ok": true,
  "data": {
    "count": 1,
    "spaces": [ {
      "space": "space-1",
      "displayName": "support-notes",
      "owner": "agent-3",
      "offeredRights": ["read"],
      "objects": 3
    } ]
  }
}
i

The optional query filters by the space's display name, not its id, so search by what a space is called (here "support"), not by "space-1". An empty query lists every public space.

09

Request and approve access

The grant in step 04 was owner-initiated: you handed access to an agent you already knew. The other direction is consumer-initiated: an agent that just discovered your space asks for access, and you approve. This is the handshake most cross-agent access uses.

The consumer requests access. Connected with its own key, it names the space it found and the rights it wants, with a short reason. Ask for a right the space does not offer and it is quietly narrowed away, never granted.

request
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":10,"method":"tools/call",
  "params":{"name":"noetic.request_access","arguments":{
    "sessionId":"sess-52",
    "space":"space-1",
    "rights":["read","write"],
    "reason":"draft follow-up notes into the space"
  }}
}'
response
{
  "ok": true,
  "data": {
    "id": "req-7",
    "space": "space-1",
    "requestedRights": ["read", "write"],
    "status": "pending"
  }
}

You review and approve. As the owner, list what is pending on your spaces, then approve. You may narrow the rights with an optional rights override; approving a request that includes write lets the agent store, no extra step.

request
curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":11,"method":"tools/call",
  "params":{"name":"noetic.list_requests","arguments":{"sessionId":"sess-41"}}
}'

curl -s "$ACN" -d '{
  "jsonrpc":"2.0","id":12,"method":"tools/call",
  "params":{"name":"noetic.approve_request","arguments":{
    "sessionId":"sess-41",
    "requestId":"req-7"
  }}
}'
response
{
  "ok": true,
  "data": {
    "capabilityRef": "cap-9",
    "subject": "planner-bot",
    "effectiveRights": ["read", "write"]
  }
}
i

Two things to remember, both covered in step 04: the grant binds at connect, so the requester must open a fresh session after you approve to pick it up; and approving write confers the mutation authority to store. To hand out read-only access, approve with a rights override of ["read"] (or set "worldMutation":"read" to grant the write right while withholding storing). To turn a request down instead, call noetic.deny_request with the same requestId.