Skip to content

Discovery

Service introspection and capability discovery

Extension URN: urn:forrst:ext:discovery


The discovery extension provides service introspection functions that enable clients to discover what a server supports. This includes lightweight capability checks, full schema introspection, and reusable schema definitions.

This extension provides two functions:

FunctionDescription
urn:cline:forrst:ext:discovery:fn:capabilitiesLightweight capability summary
urn:cline:forrst:ext:discovery:fn:describeFull service schema introspection

Discovery functions SHOULD be used for:

  • Initial client-server handshake
  • Protocol version compatibility checking
  • Dynamic client generation
  • API exploration and documentation
  • Feature detection before making calls

urn:cline:forrst:ext:discovery:fn:capabilities

Section titled “urn:cline:forrst:ext:discovery:fn:capabilities”

Returns a lightweight summary of service capabilities without full schema details.

Request:

{
"protocol": { "name": "forrst", "version": "0.1.0" },
"id": "req_caps",
"call": {
"function": "urn:cline:forrst:ext:discovery:fn:capabilities",
"version": "1.0.0"
}
}

Response:

{
"protocol": { "name": "forrst", "version": "0.1.0" },
"id": "req_caps",
"result": {
"service": "my-api",
"protocolVersions": ["0.1.0"],
"functions": [
"users.list",
"users.get",
"orders.create"
],
"extensions": [
{ "urn": "urn:forrst:ext:async", "version": "1.0.0" },
{ "urn": "urn:forrst:ext:caching", "version": "1.2.0" }
],
"limits": {
"maxRequestSize": 1048576,
"rateLimit": 1000
}
}
}

Result Fields:

FieldTypeRequiredDescription
servicestringYesService identifier
protocolVersionsarrayYesSupported Forrst protocol versions
functionsarrayYesAvailable function names
extensionsarrayNoEnabled extensions with URNs and versions
limitsobjectNoService limits (rate limits, max sizes)

Extension Object Fields:

FieldTypeRequiredDescription
urnstringYesExtension URN
versionstringYesSupported extension version

urn:cline:forrst:ext:discovery:fn:describe

Section titled “urn:cline:forrst:ext:discovery:fn:describe”

Returns the complete Forrst Discovery document with full schema introspection.

Request (Full Service):

{
"protocol": { "name": "forrst", "version": "0.1.0" },
"id": "req_describe",
"call": {
"function": "urn:cline:forrst:ext:discovery:fn:describe",
"version": "1.0.0"
}
}

Request (Single Function):

{
"protocol": { "name": "forrst", "version": "0.1.0" },
"id": "req_describe_fn",
"call": {
"function": "urn:cline:forrst:ext:discovery:fn:describe",
"version": "1.0.0",
"arguments": {
"function": "users.list",
"version": "1.0.0"
}
}
}

Arguments:

FieldTypeRequiredDescription
functionstringNoSpecific function to describe
versionstringNoSpecific version (with function)

Response (Full Service):

{
"forrst": "0.1.0",
"discovery": "0.1",
"info": {
"title": "Event Management API",
"version": "1.0.0",
"description": "API for managing events, venues, and registrations",
"termsOfService": "https://example.com/terms",
"contact": {
"name": "API Support",
"url": "https://example.com/support",
"email": "api@example.com"
},
"license": {
"name": "Proprietary",
"url": "https://example.com/license"
}
},
"servers": [
{
"name": "production",
"url": "https://{region}.api.example.com/forrst",
"summary": "Production API server",
"description": "Main production environment with full SLA guarantees",
"variables": {
"region": {
"default": "us-east",
"enum": ["us-east", "us-west", "eu-west", "ap-south"],
"description": "Geographic region for the API endpoint"
}
},
"extensions": [
{ "urn": "urn:forrst:ext:async", "version": "1.0.0" },
{ "urn": "urn:forrst:ext:caching", "version": "1.2.0" },
{ "urn": "urn:forrst:ext:query", "version": "1.0.0" }
]
}
],
"functions": [
{
"name": "events.list",
"version": "1.0.0",
"stability": "stable",
"summary": "List all events",
"description": "Returns a paginated list of events. Supports filtering by status and date range. Results are ordered by start date ascending.",
"tags": [
{ "$ref": "#/components/tags/Events" }
],
"arguments": [
{ "$ref": "#/components/contentDescriptors/StatusFilter" },
{ "$ref": "#/components/contentDescriptors/Pagination" }
],
"result": {
"name": "events",
"summary": "List of events",
"schema": {
"type": "array",
"items": { "$ref": "#/components/schemas/EventResource" }
}
},
"errors": [
{ "$ref": "#/components/errors/Unauthorized" }
],
"query": {
"filters": {
"allowed": ["status", "starts_at", "venue_id"],
"operators": ["eq", "neq", "gt", "lt", "in"]
},
"sorts": {
"allowed": ["starts_at", "name", "created_at"],
"default": { "field": "starts_at", "direction": "asc" }
},
"pagination": {
"strategies": ["offset", "cursor"],
"defaultSize": 25,
"maxSize": 100
}
},
"examples": [
{ "$ref": "#/components/examplePairings/ListPublishedEvents" }
],
"extensions": [
{ "urn": "urn:forrst:ext:caching", "ttl": 300 }
]
},
{
"name": "events.get",
"version": "1.0.0",
"stability": "stable",
"summary": "Get a single event by ID",
"description": "Retrieves detailed information about a specific event including its venue.",
"tags": [
{ "$ref": "#/components/tags/Events" }
],
"arguments": [
{ "$ref": "#/components/contentDescriptors/EventId" }
],
"result": {
"name": "event",
"summary": "The requested event",
"schema": { "$ref": "#/components/schemas/EventResource" }
},
"errors": [
{ "$ref": "#/components/errors/NotFound" },
{ "$ref": "#/components/errors/Unauthorized" }
],
"links": [
{ "$ref": "#/components/links/GetEventVenue" }
],
"examples": [
{ "$ref": "#/components/examplePairings/GetSingleEvent" }
],
"extensions": [
{ "urn": "urn:forrst:ext:caching", "ttl": 60 }
]
},
{
"name": "events.create",
"version": "1.0.0",
"stability": "stable",
"summary": "Create a new event",
"sideEffects": [
"sends_email",
"creates_audit_log"
],
"simulations": [
{
"name": "success",
"description": "Event created successfully",
"input": { "name": "Demo Event", "starts_at": "2024-12-01T10:00:00Z" },
"output": { "id": "evt_demo_001", "name": "Demo Event", "status": "draft" }
}
]
},
{
"name": "events.legacy_create",
"version": "1.0.0",
"stability": "deprecated",
"summary": "Create event (legacy)",
"deprecated": {
"reason": "Use events.create instead",
"sunset": "2025-06-30"
},
"discoverable": false
}
],
"components": {
"contentDescriptors": {
"EventId": {
"name": "id",
"summary": "Event identifier",
"required": true,
"schema": { "type": "string", "format": "uuid" }
},
"VenueId": {
"name": "venue_id",
"summary": "Venue identifier",
"required": true,
"schema": { "type": "string", "format": "uuid" }
},
"StatusFilter": {
"name": "status",
"summary": "Filter by event status",
"required": false,
"schema": { "type": "string", "enum": ["draft", "published", "cancelled"] }
},
"Pagination": {
"name": "pagination",
"summary": "Pagination parameters",
"required": false,
"schema": { "$ref": "#/components/schemas/PaginationParams" }
}
},
"schemas": {
"EventResource": {
"type": "object",
"required": ["id", "name", "starts_at"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"name": { "type": "string", "maxLength": 255 },
"description": { "type": "string" },
"status": { "type": "string", "enum": ["draft", "published", "cancelled"] },
"starts_at": { "type": "string", "format": "date-time" },
"ends_at": { "type": "string", "format": "date-time" },
"venue": { "$ref": "#/components/schemas/VenueResource" },
"created_at": { "type": "string", "format": "date-time" },
"updated_at": { "type": "string", "format": "date-time" }
}
},
"VenueResource": {
"type": "object",
"required": ["id", "name"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"name": { "type": "string" },
"address": { "type": "string" },
"capacity": { "type": "integer", "minimum": 0 }
}
},
"PaginationParams": {
"type": "object",
"properties": {
"page": { "type": "integer", "minimum": 1, "default": 1 },
"per_page": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 }
}
}
},
"errors": {
"NotFound": {
"code": "NOT_FOUND",
"message": "The requested resource was not found"
},
"Unauthorized": {
"code": "UNAUTHORIZED",
"message": "Authentication required"
},
"ValidationError": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed"
}
},
"examples": {
"PublishedEvent": {
"name": "Published Conference",
"summary": "A typical published event",
"value": {
"id": "evt_01H8X3Y4Z5A6B7C8D9E0F1G2H3",
"name": "Tech Conference 2024",
"status": "published",
"starts_at": "2024-09-15T09:00:00Z",
"ends_at": "2024-09-15T18:00:00Z"
}
},
"DraftEvent": {
"name": "Draft Event",
"summary": "An event still in draft status",
"value": {
"id": "evt_02I9Y4Z5A6B7C8D9E0F1G2H3I4",
"name": "Planning Meeting",
"status": "draft",
"starts_at": "2024-10-01T14:00:00Z"
}
}
},
"examplePairings": {
"ListPublishedEvents": {
"name": "List published events",
"summary": "Retrieve all published events",
"params": [
{
"name": "status filter",
"value": "published"
}
],
"result": {
"name": "Published events list",
"value": [
{
"id": "evt_01H8X3Y4Z5A6B7C8D9E0F1G2H3",
"name": "Tech Conference 2024",
"status": "published",
"starts_at": "2024-09-15T09:00:00Z"
}
]
}
},
"GetSingleEvent": {
"name": "Get event by ID",
"summary": "Retrieve a specific event",
"params": [
{
"name": "event id",
"value": "evt_01H8X3Y4Z5A6B7C8D9E0F1G2H3"
}
],
"result": {
"name": "Event details",
"value": {
"id": "evt_01H8X3Y4Z5A6B7C8D9E0F1G2H3",
"name": "Tech Conference 2024",
"status": "published",
"starts_at": "2024-09-15T09:00:00Z",
"ends_at": "2024-09-15T18:00:00Z",
"venue": {
"id": "ven_01A2B3C4D5E6F7G8H9I0J1K2L3",
"name": "Convention Center",
"capacity": 5000
}
}
}
}
},
"links": {
"GetEventVenue": {
"name": "Get venue details",
"summary": "Retrieve the venue for this event",
"function": "venues.get",
"params": {
"venue_id": "$result.venue.id"
}
},
"ListEventAttendees": {
"name": "List attendees",
"summary": "Retrieve attendees for this event",
"function": "attendees.list",
"params": {
"event_id": "$result.id"
}
}
},
"tags": {
"Events": {
"name": "Events",
"summary": "Event management functions",
"description": "Functions for creating, reading, updating, and deleting events."
},
"Venues": {
"name": "Venues",
"summary": "Venue management functions",
"description": "Functions for managing event venues and locations."
},
"Attendees": {
"name": "Attendees",
"summary": "Attendee management functions",
"description": "Functions for managing event registrations and attendees."
}
}
}
}

Note: The describe function returns an unwrapped response (no protocol envelope) as per the Forrst Discovery specification.


The Info Object provides metadata about the API.

Info Object Fields:

FieldTypeRequiredDescription
titlestringYesHuman-readable API name
versionstringYesAPI version (semantic versioning recommended)
descriptionstringNoDetailed API description (supports Markdown)
termsOfServicestringNoURL to terms of service
contactContact ObjectNoContact information
licenseLicense ObjectNoLicense information
FieldTypeRequiredDescription
namestringNoContact name or team
urlstringNoURL to contact page or documentation
emailstringNoContact email address
FieldTypeRequiredDescription
namestringYesLicense name (e.g., “MIT”, “Proprietary”)
urlstringNoURL to full license text

The Server Object describes an API endpoint where requests can be sent.

Server Object Fields:

FieldTypeRequiredDescription
namestringYesServer identifier (e.g., “production”, “staging”)
urlstringYesBase URL for API requests (supports URL templating)
summarystringNoBrief server description
descriptionstringNoDetailed explanation (supports Markdown)
variablesMap[string, Server Variable]NoURL template variables
extensionsarrayNoSupported extensions with versions

Used for URL templating when the server URL contains variables like {region}.

FieldTypeRequiredDescription
defaultstringYesDefault value for the variable
enum[string]NoAllowed values for the variable
descriptionstringNoExplanation of the variable

URL Templating Example:

{
"servers": [{
"name": "production",
"url": "https://{region}.api.example.com/{version}/forrst",
"variables": {
"region": {
"default": "us-east",
"enum": ["us-east", "us-west", "eu-west", "ap-south"],
"description": "Geographic region"
},
"version": {
"default": "v1",
"description": "API version prefix"
}
}
}]
}

Clients resolve the URL by substituting variables with their values (or defaults).


The Components Object holds reusable definitions that can be referenced throughout the discovery document. All component types support the Reference Object pattern using $ref.

JSON Schema definitions for data types. Follows JSON Schema Draft 7 specification.

{
"components": {
"schemas": {
"EventResource": {
"type": "object",
"required": ["id", "name"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"name": { "type": "string" },
"venue": { "$ref": "#/components/schemas/VenueResource" }
}
}
}
}
}

Schema Object Fields: Any valid JSON Schema Draft 7 fields.


Reusable descriptions for function arguments and results. Avoids duplication when the same parameter appears across multiple functions.

{
"components": {
"contentDescriptors": {
"EventId": {
"name": "id",
"summary": "Event identifier",
"description": "The unique identifier for an event",
"required": true,
"schema": { "type": "string", "format": "uuid" }
},
"Pagination": {
"name": "pagination",
"summary": "Pagination parameters",
"required": false,
"schema": { "$ref": "#/components/schemas/PaginationParams" }
}
}
}
}

Content Descriptor Fields:

FieldTypeRequiredDescription
namestringYesParameter name as used in function calls
schemaSchema ObjectYesJSON Schema type definition
summarystringNoBrief description
descriptionstringNoDetailed description (supports Markdown)
requiredbooleanNoWhether the parameter is required (default: false)
deprecatedbooleanNoMarks parameter as deprecated

Usage in functions:

{
"functions": [{
"name": "events.get",
"arguments": [
{ "$ref": "#/components/contentDescriptors/EventId" }
]
}]
}

Reusable error definitions that can be referenced from function error arrays.

{
"components": {
"errors": {
"NotFound": {
"code": "NOT_FOUND",
"message": "The requested resource was not found",
"data": {
"type": "object",
"properties": {
"resource_type": { "type": "string" },
"resource_id": { "type": "string" }
}
}
}
}
}
}

Error Object Fields:

FieldTypeRequiredDescription
codestringYesMachine-readable error code
messagestringYesHuman-readable error message
dataSchema ObjectNoSchema for additional error context

Reusable example values that match the schema of a Content Descriptor or Schema Object.

{
"components": {
"examples": {
"PublishedEvent": {
"name": "Published Conference",
"summary": "A typical published event",
"description": "Example of a fully configured event ready for attendees",
"value": {
"id": "evt_01H8X3Y4Z5A6B7C8D9E0F1G2H3",
"name": "Tech Conference 2024",
"status": "published",
"starts_at": "2024-09-15T09:00:00Z"
}
}
}
}
}

Example Object Fields:

FieldTypeRequiredDescription
namestringNoCanonical identifier
summarystringNoBrief description
descriptionstringNoDetailed explanation (supports Markdown)
valueanyNoEmbedded literal example
externalValuestringNoURL to external example (mutually exclusive with value)

Request-response pairs demonstrating complete function invocations. Links argument examples to expected results.

{
"components": {
"examplePairings": {
"GetSingleEvent": {
"name": "Get event by ID",
"summary": "Retrieve a specific event",
"description": "Demonstrates fetching an event with all related data",
"params": [
{ "name": "event id", "value": "evt_01H8X3Y4Z5A6B7C8D9E0F1G2H3" }
],
"result": {
"name": "Event details",
"value": {
"id": "evt_01H8X3Y4Z5A6B7C8D9E0F1G2H3",
"name": "Tech Conference 2024",
"status": "published"
}
}
}
}
}
}

Example Pairing Fields:

FieldTypeRequiredDescription
namestringYesIdentifier for the pairing
summarystringNoBrief description
descriptionstringNoDetailed explanation (supports Markdown)
params[Example Object]YesArray of parameter examples
resultExample ObjectNoExpected response (omit for notification-style calls)

Usage in functions:

{
"functions": [{
"name": "events.get",
"examples": [
{ "$ref": "#/components/examplePairings/GetSingleEvent" }
]
}]
}

Design-time links that describe relationships between functions. Enables clients to discover related operations.

{
"components": {
"links": {
"GetEventVenue": {
"name": "Get venue details",
"summary": "Retrieve the venue for this event",
"function": "venues.get",
"params": {
"venue_id": "$result.venue.id"
}
}
}
}
}

Link Object Fields:

FieldTypeRequiredDescription
namestringYesCanonical link identifier
summarystringNoBrief description
descriptionstringNoDetailed explanation (supports Markdown)
functionstringNoTarget function name
paramsMap[string, any]NoParameters for target function
serverServer ObjectNoAlternative server for the linked function

Runtime Expressions:

The params map supports runtime expressions that reference values from the current result:

ExpressionDescription
$resultThe entire result object
$result.fieldA specific field from the result
$result.nested.fieldNested field access

Usage in functions:

{
"functions": [{
"name": "events.get",
"links": [
{ "$ref": "#/components/links/GetEventVenue" },
{ "$ref": "#/components/links/ListEventAttendees" }
]
}]
}

Metadata tags for logical grouping and documentation organization.

{
"components": {
"tags": {
"Events": {
"name": "Events",
"summary": "Event management functions",
"description": "Functions for creating, reading, updating, and deleting events.",
"externalDocs": {
"description": "Event API Guide",
"url": "https://docs.example.com/events"
}
}
}
}
}

Tag Object Fields:

FieldTypeRequiredDescription
namestringYesTag identifier
summarystringNoBrief description
descriptionstringNoDetailed explanation (supports Markdown)
externalDocsExternal Docs ObjectNoLink to extended documentation

External Docs Object Fields:

FieldTypeRequiredDescription
descriptionstringNoDescription of the external resource
urlstringYesURL to the documentation

Usage in functions:

{
"functions": [{
"name": "events.list",
"tags": [
{ "$ref": "#/components/tags/Events" }
]
}]
}

Structured resource type definitions with attributes, relationships, and capabilities. More expressive than raw schemas — designed for domain entities with rich metadata.

Resource Object Fields:

FieldTypeRequiredDescription
typestringYesResource type identifier (e.g., “events”, “users”)
attributesMap[string, Attribute]YesAttribute definitions keyed by name
descriptionstringNoHuman-readable resource description
relationshipsMap[string, Relationship]NoRelationship definitions keyed by name
metaJSON SchemaNoSchema for resource-level metadata

Describes a single resource attribute with capabilities.

FieldTypeRequiredDescription
schemaJSON SchemaYesType definition and validation rules
descriptionstringNoAttribute purpose and usage
filterablebooleanNoCan be used in filter expressions (default: false)
filterOperators[string]NoSupported operators when filterable
sortablebooleanNoCan be used for sorting (default: false)
sparsebooleanNoCan be excluded via sparse fieldsets (default: true)
deprecatedDeprecated ObjectNoDeprecation information

Describes a relationship to another resource type.

FieldTypeRequiredDescription
resourcestringYesRelated resource type name
cardinalitystringYes"one" or "many"
descriptionstringNoRelationship purpose
filterablebooleanNoCan filter parent by relationship (default: false)
includablebooleanNoCan be included in responses (default: true)
nested[string]NoTraversable nested relationship names
{
"components": {
"resources": {
"events": {
"type": "events",
"description": "Calendar events with venues and attendees",
"attributes": {
"id": {
"schema": { "type": "string", "format": "uuid" },
"filterable": true,
"filterOperators": ["eq", "in"],
"sparse": false
},
"name": {
"schema": { "type": "string", "maxLength": 255 },
"description": "Event display name",
"filterable": true,
"filterOperators": ["eq", "like"],
"sortable": true
},
"starts_at": {
"schema": { "type": "string", "format": "date-time" },
"filterable": true,
"filterOperators": ["eq", "gt", "lt", "gte", "lte"],
"sortable": true
},
"status": {
"schema": { "type": "string", "enum": ["draft", "published", "cancelled"] },
"filterable": true,
"filterOperators": ["eq", "in"]
}
},
"relationships": {
"venue": {
"resource": "venues",
"cardinality": "one",
"description": "Event location",
"includable": true
},
"attendees": {
"resource": "users",
"cardinality": "many",
"description": "Registered attendees",
"includable": true,
"filterable": true,
"nested": ["profile"]
}
}
}
}
}
}

Any component can be referenced using the $ref keyword with a JSON Pointer:

{ "$ref": "#/components/schemas/EventResource" }
{ "$ref": "#/components/contentDescriptors/EventId" }
{ "$ref": "#/components/errors/NotFound" }
{ "$ref": "#/components/examples/PublishedEvent" }
{ "$ref": "#/components/examplePairings/GetSingleEvent" }
{ "$ref": "#/components/links/GetEventVenue" }
{ "$ref": "#/components/tags/Events" }
{ "$ref": "#/components/resources/events" }

References can be used anywhere the corresponding object type is expected:

  • arguments[] accepts Content Descriptor or Reference
  • result accepts Content Descriptor or Reference
  • errors[] accepts Error Object or Reference
  • examples[] accepts Example Pairing or Reference
  • links[] accepts Link Object or Reference
  • tags[] accepts Tag Object or Reference
  • resources can be referenced for result type documentation

Functions describe individual API operations. This section details all available fields.

Function Object Fields:

FieldTypeRequiredDescription
namestringYesUnique function identifier
versionstringYesSemantic version of this function
stabilitystringNoStability level: experimental, stable, deprecated
summarystringNoBrief one-line description
descriptionstringNoDetailed explanation (supports Markdown)
argumentsarrayNoFunction parameters (Content Descriptor or Reference)
resultContent DescriptorNoReturn value specification
errorsarrayNoPossible errors (Error Object or Reference)
tagsarrayNoLogical grouping (Tag Object or Reference)
linksarrayNoRelated functions (Link Object or Reference)
examplesarrayNoUsage examples (Example Pairing or Reference)
queryQuery CapabilitiesNoSupported query operations (filters, sorts, pagination)
sideEffects[string]NoDeclared side effects (e.g., “sends_email”, “triggers_webhook”)
deprecatedDeprecated ObjectNoDeprecation information with reason and sunset date
discoverablebooleanNoWhether function appears in discovery (default: true)
simulations[Simulation Scenario]NoPredefined scenarios for sandbox/demo mode
extensionsarrayNoExtension-specific configuration
externalDocsExternal DocsNoLink to extended documentation

Rich deprecation information with migration guidance and removal timeline.

FieldTypeRequiredDescription
reasonstringNoWhy deprecated and what to use instead
sunsetstringNoRemoval date in ISO 8601 format (e.g., “2025-12-31”)
{
"deprecated": {
"reason": "Use users.create instead",
"sunset": "2025-06-30"
}
}

Array of strings declaring effects the function may cause. Helps clients understand what actions a function triggers beyond returning data.

{
"sideEffects": [
"sends_email",
"triggers_webhook",
"creates_audit_log",
"invalidates_cache"
]
}

Common side effect values:

  • sends_email - Sends email notifications
  • sends_sms - Sends SMS messages
  • triggers_webhook - Fires webhook callbacks
  • creates_audit_log - Records audit trail entries
  • invalidates_cache - Clears cached data
  • schedules_job - Queues background jobs
  • external_api_call - Calls third-party APIs

Controls whether a function appears in discovery responses. Defaults to true.

Set to false to hide internal or deprecated functions from standard client discovery while keeping them callable for backward compatibility.

{
"name": "internal.migrate_legacy_data",
"discoverable": false
}

Describes what query operations a function supports for filtering, sorting, pagination, field selection, and relationship inclusion.

Query Capabilities Object Fields:

FieldTypeRequiredDescription
filtersFilters CapabilityNoFiltering configuration
sortsSorts CapabilityNoSorting configuration
fieldsFields CapabilityNoSparse fieldset configuration
relationshipsRelationships CapabilityNoRelationship inclusion configuration
paginationPagination CapabilityNoPagination configuration
FieldTypeRequiredDescription
allowed[string]NoFilterable field names
operators[string]NoSupported operators (eq, neq, gt, gte, lt, lte, in, like)
maxConditionsintegerNoMaximum filter conditions per request
FieldTypeRequiredDescription
allowed[string]NoSortable field names
maxFieldsintegerNoMaximum sort fields per request
defaultSort DefaultNoDefault sort order
FieldTypeRequiredDescription
allowed[string]NoSelectable field names
default[string]NoFields returned when none specified
FieldTypeRequiredDescription
allowed[string]NoIncludable relationship names
maxDepthintegerNoMaximum nesting depth
FieldTypeRequiredDescription
strategies[string]NoSupported strategies: offset, cursor, page
defaultSizeintegerNoDefault page size
maxSizeintegerNoMaximum page size
{
"name": "events.list",
"query": {
"filters": {
"allowed": ["status", "starts_at", "venue_id"],
"operators": ["eq", "neq", "gt", "lt", "in"]
},
"sorts": {
"allowed": ["starts_at", "name", "created_at"],
"default": { "field": "starts_at", "direction": "asc" }
},
"pagination": {
"strategies": ["offset", "cursor"],
"defaultSize": 25,
"maxSize": 100
}
}
}

Predefined input/output pairs for sandbox and demo modes. Unlike examples (documentation), simulations are executable — clients can invoke functions in simulation mode to receive predictable responses without affecting real data.

Simulation Scenario Object Fields:

FieldTypeRequiredDescription
namestringYesScenario identifier (e.g., “success”, “not_found”)
inputobjectYesArguments that trigger this scenario
outputanyNoSuccess response (mutually exclusive with error)
errorError ObjectNoError response (mutually exclusive with output)
descriptionstringNoWhat this scenario demonstrates
metadataobjectNoAdditional response metadata (timing, headers)

Use Cases:

  • API explorers and interactive documentation
  • Client SDK testing without backend dependencies
  • Demo environments with predictable behavior
  • Integration testing with known responses
{
"name": "users.create",
"simulations": [
{
"name": "success",
"description": "User successfully created",
"input": {
"email": "demo@example.com",
"name": "Demo User"
},
"output": {
"id": "usr_demo_001",
"email": "demo@example.com",
"name": "Demo User",
"created_at": "2024-01-15T10:30:00Z"
}
},
{
"name": "duplicate_email",
"description": "Email already registered",
"input": {
"email": "existing@example.com",
"name": "Another User"
},
"error": {
"code": "VALIDATION_ERROR",
"message": "Email already exists",
"data": { "field": "email" }
}
}
]
}

Extensions can be declared at two levels:

Declared in servers[].extensions, these indicate which extensions the server supports globally:

{
"servers": [
{
"name": "production",
"url": "https://api.example.com/forrst",
"extensions": [
{ "urn": "urn:forrst:ext:async", "version": "1.0.0" },
{ "urn": "urn:forrst:ext:caching", "version": "1.2.0" }
]
}
]
}

Declared in functions[].extensions, these indicate which extensions a specific function supports with optional configuration:

{
"functions": [
{
"name": "events.list",
"extensions": [
{ "urn": "urn:forrst:ext:caching", "ttl": 300 },
{ "urn": "urn:forrst:ext:query", "operators": ["eq", "gt", "lt", "in"] },
{ "urn": "urn:forrst:ext:async" }
]
}
]
}

Extension Declaration Fields:

FieldTypeRequiredDescription
urnstringYesExtension URN
versionstringNoExtension version (inherits from server if omitted)
*anyNoExtension-specific configuration

Function-level extensions inherit the version from server-level if not specified. Additional fields are extension-specific configuration (e.g., ttl for caching, operators for query).


Servers implementing the discovery extension SHOULD:

  1. Register all discoverable functions in the capabilities list
  2. Include accurate protocol version information
  3. Document all enabled extensions with versions
  4. Define reusable schemas in components.schemas
  5. Provide service limits when applicable

Servers MAY customize:

  • Which functions appear in capabilities
  • What limits are reported
  • Extension metadata and configuration
  • Schema granularity (fine-grained vs coarse)

┌──────────┐ ┌────────────────┐
│ Client │ │ Server │
└────┬─────┘ └───────┬────────┘
│ │
│ capabilities │
│──────────────────▶│
│ │
│ {functions, ...} │
│◀──────────────────│
│ │
│ describe(fn) │
│──────────────────▶│
│ │
│ {schema...} │
│◀──────────────────│
│ │
│ actual call │
│──────────────────▶│
└───────────────────┘
// Check if async is supported before using it
{
"protocol": { "name": "forrst", "version": "0.1.0" },
"id": "req_check",
"call": {
"function": "urn:cline:forrst:ext:discovery:fn:capabilities",
"version": "1.0.0"
}
}
// Response shows async is available with version
{
"result": {
"extensions": [
{ "urn": "urn:forrst:ext:async", "version": "1.0.0" }
]
}
}

Clients can use the describe response to generate typed clients:

  1. Fetch full service description
  2. Parse components.schemas to generate model classes
  3. Parse functions to generate method signatures
  4. Resolve $ref pointers to link models to functions
// Describe response enables generating:
// - EventResource class with typed properties
// - events.list() method returning EventResource[]
// - events.get(id: string) method returning EventResource