ChatGPTClaudeGrok / X / CursorGemini

DSH plugin Typert RPC: lookup, descriptor and gateway

Plugin DevelopmentPublished 2026-10-21Author: DeepSeek Plugin Market
DSH pluginDeepSeek HarnessTypertAPI Gatewayremote calls
DSH Typert RPC has three layers: LookupMap declares objects, InvocationDescriptor encodes args, and Gateway authorizes resources. Cancel is out-of-band.

Typert remote calls are not “JSON-ify a method name and arguments”; they are a three-layer type contract: declarations decide which host objects are addressable, descriptors decide how parameters and results are encoded, and the Gateway decides who may call and which resources they may touch. Mixing the layers produces “works locally, fails remotely with lookup unavailable” or “a cancellation signal in args breaks the codec”.

DeepSeek Harness: Declarations: which objects are addressable

Remote calls cannot pass object references; every object needs a wire identity, and LookupMap and ContextMap are that declaration. Two maps:(source)

  1. TypertLookupMap — associates a host object type with a wire identity. Expected: a parameter is recognized as a lookup, not an ordinary object.
  2. TypertContextMap — associates a scoped context category with a wire identity. Expected: a method can select a context receiver.
  3. Declaration merging — business object packages extend the empty maps, and generated descriptors reference the keys. Expected: host and client builds see the same declaration.

After a lookup resolver unloads, the registry keeps the wire declaration. SRC discovery still classifies the parameter as a lookup and fails because it is unavailable; it never accepts the wire value as an ordinary object. That is “fail rather than mis-accept”.

DeepSeek Harness: Descriptors: how arguments and results are encoded

InvocationDescriptor is local reflection, not a wire message; requests send only the endpoint and named args. Key fields:(source)

FieldPurpose
service / namespace / methodlocate the method
parametersordered business parameters with wire names and codecs
invocationdirect or context receiver
scopeoptional context projection
uplinkcodec for client-to-host stream items
cancellationreserved out-of-band signal parameter
resultcodec for the unary result or each stream item

Strict codecs carry a generated schema factory; SRC codecs only require JSON-safe input and do not restore structural types. A unary result codec can provide encode() for byte-bearing subtrees and decode() to validate native bytes; pure JSON results need no byte handling.

Cancellation is an out-of-band carrier signal injected after business parameters, never in args. Do not put signal into the descriptor’s parameter list as a normal input.

DeepSeek Harness: Calls: methods, streams, and cancellation

createTypertRemoteInfo returns a lazy class instance; the method index references descriptors, and callers get a remote method with input/invoke rather than a raw function. Three capabilities:(source)

  1. Unary call — mode omitted; invoke sends one request and returns the result. Expected: parameters encode by descriptor.
  2. Stream call — mode: 'stream'; the host returns RemoteStream<Out, In>. Expected: the client gets a RemoteStreamHandle with send, end, and dispose.
  3. Context receiver — a method that only uses a context receiver stays in the descriptor and scope declarations. Expected: no extra business parameter.

method.input(options?) accepts only strict?: boolean and returns a cached TypertRemoteValue; it does not change host dispatch or result. Reading metadata or schema never initiates a network call.

DeepSeek Harness: A minimal declaration example

Declare the lookup first and let generated descriptors reference it; do not hand-write wire fields. Structure:(source)

ts
declare module '@deepseek-ai/dsh-typert-protocol' {
  interface TypertLookupMap {
    'my-service/session': Session
  }
}

The generator emits a TypertLookupDefinition with key, parameter, wire, and host/wire type symbols; a runtime provider resolves the wire value back to a live object. The method exposes only named args, and cancellation is injected after business parameters.

If the lookup resolver unloads, the registry keeps the wire declaration and later calls fail as unavailable instead of accepting the wire value as a normal object.

DeepSeek Harness: Permissions and resources

Typert access control lives in the Gateway and resource policy, not inside the method. Key points:(source)

  • Principal is fixed — PeerScope fixes the principal at creation in host code; no wire field can set it. Expected: a caller cannot claim another identity.
  • Resource declaration — @Remote({ resources }) or @RemoteScope(key, { resources }) reads resource identity; then lookup parameters or scope Context, then defaults in typert.resources.
  • Global resource — a call that touches no resource uses the built-in global. Expected: identity-less resources still need policy.
  • Only non-owner calls are checked — a policy must bind a role on every resource.

If the method can modify data, declare resource kinds before discussing roles; otherwise the Gateway can only treat it as global.

DeepSeek Harness: Three integration forms

Direct unary methods, context receivers, and remote streams increase in complexity. Three:(source)

  1. Direct unary method — simplest, good for CRUD and queries. Expected: arguments and results are JSON or declared lookups.
  2. Context receiver — for methods that need a scoped context. Expected: the receiver derives from Context, not business parameters.
  3. Remote stream — for continuous push or bidirectional traffic. Expected: the client holds the handle and is responsible for end or dispose.

A stream handle that is neither iterated nor disposed keeps the host stream alive. When the carrier disconnects, iteration fails and the handle ends.

Choosing a codec

Pure JSON, byte-bearing subtrees, and strict structure need different codecs. Three:

  1. Pure JSON — no byte handling or client decode; use a normal codec. Expected: arguments and results are lossless JSON.
  2. Byte-bearing subtree — a unary result uses encode() to project bytes into attachments and decode() to validate native bytes. Expected: Uint8Array does not degrade into a plain object.
  3. Strict structure — a strict codec carries the generated schema factory. Expected: the receiver validates the declared structure.

SRC codecs only enforce JSON-safe input and do not restore structural types; do not rely on SRC alone when you need type guarantees.

DeepSeek Harness FAQ

Why does a call work locally but fail remotely with lookup unavailable? Remote calls find objects by wire identity. If the resolver is unloaded or unregistered, SRC refuses to treat the wire value as an ordinary object. Confirm both the declaration and the runtime resolver.

Can I pass a Uint8Array directly as a parameter? Only with codec support for byte subtrees. Unary results can use encode()/decode(); do not assume bytes survive with pure JSON.

Does the uplink enter the parameter list for a stream? No. The uplink is read through RemoteInvocation.uplink(), and the descriptor declares its codec separately.

The short version: Typert works when declaration, description, and authorization each hold; putting cancellation or object references into args breaks one of them.

ChatGPTClaudeGrok / X / CursorGemini

FAQ

What do TypertLookupMap and TypertContextMap solve?

DeepSeek Harness: lookupMap associates a host object type with a wire identity so a remote call can find the live object by identity. ContextMap associates a scoped context category with a wire identity so a call can select a receiver context. Both are extended by declaration merging.

Is a Typert descriptor a wire message?

DeepSeek Harness: no. InvocationDescriptor is local reflection information. Host and consumer builds generate corresponding descriptors, but the request sends only the endpoint and named args, not the descriptor itself.

How is a Typert call cancelled?

DeepSeek Harness: cancellation is an out-of-band carrier signal injected after the business parameters; it never enters args. Business arguments stay clean, and cancellation is not mistaken for a normal input.

What happens after a lookup resolver unloads?

DeepSeek Harness: the registry keeps the wire declaration. SRC discovery still classifies that parameter as a lookup and fails because it is unavailable, rather than accepting the wire value as an ordinary object.

Where is Typert access control enforced?

DeepSeek Harness: in dsh-api-remote-access. A non-owner call is allowed only when the principal kind’s policy binds a role containing the endpoint action on every accessed resource. The Gateway reads resource identity from @Remote resources or the default typert.resources.

Related Terms

TypertLookupMap
TypertLookupMap is a merge-extensible map associating a host object type with its wire identity. Generated descriptors reference these keys, and a runtime provider resolves the live object.— DeepSeek Harness reference - Typert remote calls
InvocationDescriptor
InvocationDescriptor is the local reflection description of one exported method call, including id, service, method, parameters, codecs, result codec, and optional uplink or cancellation. It is not a wire message.— DeepSeek Harness reference - Typert remote calls
RemoteStream
RemoteStream is one remote stream on the host side. The host iterates it as AsyncIterable<Out>, while In marks the client-to-host uplink type; the client receives a RemoteStreamHandle.— DeepSeek Harness reference - Typert remote calls
PeerScope
PeerScope is one peer’s session on a host, containing id, connection-lifetime context, fixed principal, cancellation signal, and interaction capability. Remote streams end with the peer.— DeepSeek Harness reference - Typert remote calls

Sources