MCP
Your store declaration, derived into MCP tools. Holds the API key — never import this from browser code.
Generated from @cosmoops/connect-sdk/mcp's TypeScript source and its own doc comments - see Reference for the other entry points. Regenerated on every deploy; don't hand-edit.
Interfaces
Interface: ConnectMcpSignatureVerdict
Properties
| Property | Type | Description |
|---|---|---|
valid | boolean | - |
version | "v1" | "v2" | null | Which scheme verified. null when nothing did. |
nonce | string | null | The signed nonce - present only for a verified v2, since v1 does not sign it and an unsigned value is worth nothing as a replay key. |
timestamp | number | null | The signed timestamp, when the request verified. |
Interface: McpSignaturePayloadV2Input
Properties
| Property | Type | Description |
|---|---|---|
timestamp | number | The header's t, unix seconds. |
nonce | string | The header's n, 32 lowercase hex characters. |
method | string | - |
url | string | URL | The request URL as your server received it; only pathname + search is signed. |
authorization | string | null | undefined | The raw Authorization header value (e.g. "Bearer …"), or null when absent. |
rawBody | string | - |
Interface: McpToolDescriptor
One entry of an MCP tools/list response.
Properties
| Property | Type | Description |
|---|---|---|
name | string | - |
title | string | - |
description | string | - |
inputSchema | Record<string, unknown> | - |
annotations | { readOnlyHint: boolean; destructiveHint: boolean; idempotentHint: boolean; } | - |
annotations.readOnlyHint | boolean | - |
annotations.destructiveHint | boolean | - |
annotations.idempotentHint | boolean | - |
_meta? | McpToolMeta | See mcpToolMeta. Absent unless something is declared. |
Interface: McpToolMeta
The _meta Connect reads from a tool definition.
Indexable
[key: string]: unknownProperties
| Property | Type |
|---|---|
cosmoops.com/foundational? | boolean |
Interface: StoreDataPort
The subset of ConnectClient["data"] a toolset uses.
Structural rather than the concrete class so this module pulls in neither the transport nor the key-holding client, and so a test can pass a recording double without a network seam of its own.
Methods
get()
get(input: {
workspaceId?: string;
collection: string;
id: string;
asUser?: string;
}): Promise<StoreDocument>;Parameters
| Parameter | Type |
|---|---|
input | { workspaceId?: string; collection: string; id: string; asUser?: string; } |
input.workspaceId? | string |
input.collection | string |
input.id | string |
input.asUser? | string |
Returns
Promise<StoreDocument>
query()
query(input: {
workspaceId?: string;
collection: string;
filters?: StoreQueryFilter[];
orderBy?: StoreOrderBy;
limit?: number;
cursor?: string | null;
asUser?: string;
}): Promise<{
items: StoreDocument[];
nextCursor: string | null;
}>;Parameters
| Parameter | Type |
|---|---|
input | { workspaceId?: string; collection: string; filters?: StoreQueryFilter[]; orderBy?: StoreOrderBy; limit?: number; cursor?: string | null; asUser?: string; } |
input.workspaceId? | string |
input.collection | string |
input.filters? | StoreQueryFilter[] |
input.orderBy? | StoreOrderBy |
input.limit? | number |
input.cursor? | string | null |
input.asUser? | string |
Returns
Promise<{
items: StoreDocument[];
nextCursor: string | null;
}>
aggregate()
aggregate(input: {
workspaceId?: string;
collection: string;
aggregations: StoreAggregation[];
filters?: StoreQueryFilter[];
asUser?: string;
}): Promise<{
values: Record<string, number | null>;
}>;Parameters
| Parameter | Type |
|---|---|
input | { workspaceId?: string; collection: string; aggregations: StoreAggregation[]; filters?: StoreQueryFilter[]; asUser?: string; } |
input.workspaceId? | string |
input.collection | string |
input.aggregations | StoreAggregation[] |
input.filters? | StoreQueryFilter[] |
input.asUser? | string |
Returns
Promise<{
values: Record<string, number | null>;
}>
create()
create(input: {
workspaceId?: string;
collection: string;
data: Record<string, unknown>;
id?: string;
asUser?: string;
}): Promise<StoreDocument>;Parameters
| Parameter | Type |
|---|---|
input | { workspaceId?: string; collection: string; data: Record<string, unknown>; id?: string; asUser?: string; } |
input.workspaceId? | string |
input.collection | string |
input.data | Record<string, unknown> |
input.id? | string |
input.asUser? | string |
Returns
Promise<StoreDocument>
update()
update(input: {
workspaceId?: string;
collection: string;
id: string;
data: Record<string, unknown>;
asUser?: string;
}): Promise<StoreDocument>;Parameters
| Parameter | Type |
|---|---|
input | { workspaceId?: string; collection: string; id: string; data: Record<string, unknown>; asUser?: string; } |
input.workspaceId? | string |
input.collection | string |
input.id | string |
input.data | Record<string, unknown> |
input.asUser? | string |
Returns
Promise<StoreDocument>
delete()
delete(input: {
workspaceId?: string;
collection: string;
id: string;
asUser?: string;
}): Promise<void>;Parameters
| Parameter | Type |
|---|---|
input | { workspaceId?: string; collection: string; id: string; asUser?: string; } |
input.workspaceId? | string |
input.collection | string |
input.id | string |
input.asUser? | string |
Returns
Promise<void>
Interface: StoreTool
One derived tool: the wire definition, and the call behind it.
Shaped so listTools/callTool can be answered without this module knowing
what transport is in front of it - see the note on createStoreToolset.
Properties
| Property | Type |
|---|---|
name | string |
title | string |
description | string |
inputSchema | JsonSchema |
annotations | { readOnlyHint: boolean; destructiveHint: boolean; idempotentHint: boolean; } |
annotations.readOnlyHint | boolean |
annotations.destructiveHint | boolean |
annotations.idempotentHint | boolean |
Methods
execute()
execute(args: Record<string, unknown>): Promise<unknown>;Parameters
| Parameter | Type |
|---|---|
args | Record<string, unknown> |
Returns
Promise<unknown>
Interface: StoreToolset
Properties
| Property | Modifier | Type | Description |
|---|---|---|---|
tools | readonly | readonly StoreTool[] | The derived tools, if you would rather register them yourself. |
Methods
listTools()
listTools(): {
tools: McpToolDescriptor[];
};Returns
{
tools: McpToolDescriptor[];
}tools
tools: McpToolDescriptor[];callTool()
callTool(name: string, args: Record<string, unknown>): Promise<McpToolResult>;Parameters
| Parameter | Type |
|---|---|
name | string |
args | Record<string, unknown> |
Returns
Promise<McpToolResult>
Interface: StoreToolsetOptions
Properties
| Property | Type | Description |
|---|---|---|
collections | readonly StoreCollectionDeclaration[] | The application's own declaration - the same array seeded to Application.storeSchema. |
data | StoreDataPort | - |
asUser | string | (() => string | Promise<string>) | The end user's Connect session token. Every call is made on their behalf. A function is resolved per call, for a toolset outliving one session. |
workspaceId? | string | Omit for an application-scoped collection; required for a workspace-scoped one. |
writes? | StoreToolWrites | - |
prefix? | string | Prepended to every tool name, for a server mounting more than one source. |
include? | readonly string[] | Collections to derive from. Defaults to every declared data collection. |
foundational? | readonly string[] | Tool names (as listed, prefix included) to declare foundational - offered by Connect's workspace assistant on every turn, whatever the question. Connect honours at most four per application; pick the entry points (search, summary) the other tools take ids from. See MCP_FOUNDATIONAL_META_KEY. |
Type Aliases
Type Alias: JsonSchema
type JsonSchema = Record<string, unknown>;A JSON Schema object, as the MCP tools/list response carries it.
Type Alias: McpToolResult
type McpToolResult = {
content: {
type: "text";
text: string;
}[];
isError?: boolean;
};An MCP tools/call result.
A type alias rather than an interface, and that is load-bearing rather
than a style choice. The MCP SDK types a request handler's return as a union
whose members carry an index signature ([x: string]: unknown); an interface
is not assignable to such a type, while a type alias is - TypeScript grants
the implicit index signature only to the latter. Declared as an interface,
the four-line wiring in this file's own example does not compile, and the
caller is pushed into a cast at exactly the boundary where a cast hides
shape errors.
Properties
content
content: {
type: "text";
text: string;
}[];type
type: "text";text
text: string;isError?
optional isError?: boolean;Type Alias: StoreToolWrites
type StoreToolWrites = "none" | "create" | "all";How much of the write surface to derive.
Defaults to "none". A toolset is usually handed to a model driving somebody
else's conversation, and the blast radius of a derived delete on every
collection is not something to acquire by default - opting in is one word,
and discovering it by accident is not recoverable.
Type Alias: VerifyConnectMcpSignatureInput
type VerifyConnectMcpSignatureInput = {
header: string | null | undefined;
rawBody: string;
method: string;
url: string | URL;
authorization: string | null | undefined;
toleranceSeconds?: number;
requireV2?: boolean;
now?: Date;
} &
| {
signingKey: string;
apiKey?: never;
}
| {
apiKey: string;
signingKey?: never;
};Type Declaration
header
header: string | null | undefined;The Connect-Signature header, or null when absent.
rawBody
rawBody: string;The raw body - verify before parsing, never re-serialise. "" for a GET.
method
method: string;url
url: string | URL;request.url, exactly as your server received it.
authorization
authorization: string | null | undefined;The raw Authorization header value, or null when absent.
toleranceSeconds?
optional toleranceSeconds?: number;Default 300. A timestamp this far from now, either way, fails.
requireV2?
optional requireV2?: boolean;Refuse a header that verifies only as v1.
now?
optional now?: Date;Variables
Variable: MCP_FOUNDATIONAL_META_KEY
const MCP_FOUNDATIONAL_META_KEY: "cosmoops.com/foundational" = "cosmoops.com/foundational";The _meta key that marks a tool foundational: Connect's workspace
assistant offers it on every turn, before ranking the rest of a workspace's
application tools against the question.
Connect keeps only this key of a tool's _meta, honours it only as a literal
true, and caps it at four tools per application - so mark the entry points
(search, summary, "what's next"), not everything.
Functions
Function: createStoreToolset()
function createStoreToolset(options: StoreToolsetOptions): StoreToolset;Parameters
| Parameter | Type |
|---|---|
options | StoreToolsetOptions |
Returns
Function: deriveMcpSigningKey()
function deriveMcpSigningKey(apiKey: string): string;The key Connect signs your MCP requests with, from the API key you hold.
Parameters
| Parameter | Type |
|---|---|
apiKey | string |
Returns
string
Function: deriveStoreTools()
function deriveStoreTools(options: StoreToolsetOptions): StoreTool[];Every tool one declaration yields, in a stable order.
Parameters
| Parameter | Type |
|---|---|
options | StoreToolsetOptions |
Returns
Function: mcpSignaturePayloadV2()
function mcpSignaturePayloadV2(input: McpSignaturePayloadV2Input): string;The exact string v2 is an HMAC of. Exported so a signer and a verifier can
be checked against each other byte for byte.
Parameters
| Parameter | Type |
|---|---|
input | McpSignaturePayloadV2Input |
Returns
string
Function: mcpToolMeta()
function mcpToolMeta(options: {
foundational?: boolean;
}): {
_meta?: McpToolMeta;
};The _meta field for a hand-written tool definition, to spread into it:
{ name: "search_crm", title, description, inputSchema, annotations, ...mcpToolMeta({ foundational: true }) }Emits nothing when there is nothing to declare, so a definition that sets no option is byte-for-byte what it was.
Parameters
| Parameter | Type |
|---|---|
options | { foundational?: boolean; } |
options.foundational? | boolean |
Returns
{
_meta?: McpToolMeta;
}_meta?
optional _meta?: McpToolMeta;Function: verifyConnectMcpSignature()
function verifyConnectMcpSignature(input: VerifyConnectMcpSignatureInput): ConnectMcpSignatureVerdict;Whether a request is Connect's.
- A header carrying any
v2is decided byv2alone: av1beside a failingv2is not consulted, because that is exactly the shape of a signed request replayed with another member's bearer. - A header with no
v2verifies onv1, unlessrequireV2. - Every candidate is compared in constant time with no early exit, so the time taken does not say which key matched.
Never says why it refused - reporting "bad timestamp" separately from "bad signature" tells a prober which half of a forgery to keep working on.
Parameters
| Parameter | Type |
|---|---|
input | VerifyConnectMcpSignatureInput |