Context API
Access runtime MCP capabilities—logging, progress, resource access, sampling—inside any Hyperia tool, resource, or prompt.
When you decorate a Python function as a tool/resource/prompt, it executes inside an MCP request‑scope. Hyperia exposes that scope via the Context
object so your code can talk back to the client, stream progress, or even call the client’s LLM.
What Is Context
?
Context
?The object provides:
Logging – debug/info/warning/error back to the caller.
Progress reporting – live percentage updates for long tasks.
Resource access – read other resources on the server.
LLM sampling – let the client’s model generate text/images mid‑function.
Request meta – IDs, client origin, etc.
Advanced hooks – raw session objects and server instance when absolutely needed.
Injecting Context
Context
Add a parameter typed Context
anywhere in the signature. Hyperia will inject it.
from hyperia import Hyperia, Context
mcp = Hyperia("CtxDemo")
@mcp.tool()
async def process_file(uri: str, ctx: Context) -> str:
await ctx.info(f"Processing {uri}")
...
Rules
Parameter name doesn’t matter; the type hint does.
Omit it if you don’t need context.
Most methods are async; declare your function
async def
.Context
only exists during a request; calling methods outside raises errors. For unit tests you can type‑hintContext | None = None
.
Context in Resources & Prompts
@mcp.resource("resource://{user}/profile")
async def profile(user: str, ctx: Context):
return {"user": user, "request_id": ctx.request_id}
@mcp.prompt()
async def report(kind: str, ctx: Context) -> str:
return f"Please compile a {kind} report. ReqID: {ctx.request_id}"
Dependency Helper get_context()
get_context()
If a deep utility function can’t accept an extra param, retrieve the active context dynamically (server‑side only):
from hyperia.server.dependencies import get_context
async def helper():
ctx = get_context() # only valid inside a request
await ctx.debug("Helper called")
Calling get_context()
outside a request → RuntimeError
.
Capabilities
1. Logging
@mcp.tool()
async def analyse(data: list[float], ctx: Context):
await ctx.debug("Starting analysis")
avg = sum(data)/len(data) if data else 0
await ctx.info(f"Average={avg}")
return avg
ctx.debug(msg)
Verbose trace
ctx.info(msg)
Normal progress
ctx.warning(msg)
Non‑fatal issues
ctx.error(msg)
Errors
ctx.log(level, msg, logger_name=None)
Custom level/logger
2. Progress Reporting
@mcp.tool()
async def process(items: list[str], ctx: Context):
total = len(items)
for i, itm in enumerate(items):
await ctx.report_progress(i, total)
await asyncio.sleep(0.05)
await ctx.report_progress(total, total)
Signature: ctx.report_progress(progress: float, total: float | None = None)
.
Client must send a progressToken
or updates are ignored.
3. Resource Access
@mcp.tool()
async def summarise(uri: str, ctx: Context):
res = await ctx.read_resource(uri)
text = res[0].content if res else ""
...
Returns a list of ReadResourceContents
; usually read content
of first part.
4. LLM Sampling
@mcp.tool()
async def sentiment(text: str, ctx: Context):
resp = await ctx.sample(
messages=f"Classify the sentiment of: {text}",
system_prompt="Return only: positive, negative, or neutral.",
temperature=0.0,
)
return resp.text.strip().lower()
Signature: ctx.sample(messages, system_prompt=None, temperature=None, max_tokens=None)
→ returns TextContent
or ImageContent
.
5. Request Info
@mcp.tool()
async def info(ctx: Context):
return {"req": ctx.request_id, "client": ctx.client_id}
Advanced Accessors
@mcp.tool()
async def server_name(ctx: Context):
srv = ctx.Hyperia # server instance
return srv.name
Also available: ctx.session
, ctx.request_context
for low‑level operations (use sparingly).
HTTP Request (Starlette) (Server builds with ASGI)
ctx.get_http_request()
is deprecated → use hyperia.server.dependencies.get_http_request()
inside ASGI stacks if needed.
Server Behaviour Flags
Duplicate Context Injection
Context itself does not have duplication rules, but note you can configure duplicate tools/resources/prompts via on_duplicate_*
settings at server init as shown in earlier chapters.
Last updated