TypeScript client SDK for Deside MCP integrations.
@desideapp/mcp-sdk is the shared protocol helper for TypeScript apps and
agent runtimes that need to connect to Deside's MCP endpoint. It handles MCP
session bootstrap, OAuth 2.0 + PKCE with Solana wallet proof, token refresh, and
typed wrappers for the current Deside MCP tool surface.
The MCP endpoint and tool contract remain the source of truth. This SDK is a client helper, not a separate protocol.
- Install
- Usage
- Related Surfaces
- Signer Contract
- Tools
- Authentication
- Agent Identity Selection
- Directory Lookup
- Development
- Package Boundary
- Publishing
- Contributing
- License
npm install @desideapp/mcp-sdkRequirements:
- Node.js 20 or newer
- a Solana wallet/keypair capable of signing plaintext challenge messages
- an OAuth redirect URI registered by the calling integration flow
import { DesideMcpSdk, type DesideSigner } from "@desideapp/mcp-sdk";
const signer: DesideSigner = {
getAddress: () => walletAddress,
signMessage: async (message) => signMessageWithYourWallet(message),
};
const sdk = new DesideMcpSdk({
oauthRedirectUri: "https://agent.example.com/callback",
});
await sdk.connect(signer);
const identity = await sdk.getMyIdentity(signer);
const conversations = await sdk.listConversations(signer);
const agentIdentities = await sdk.listMyAgentIdentities(signer);Tool arguments intentionally match the MCP contract shape. That means tool
payload fields use snake_case, for example to_wallet, conv_id,
before_seq, agent_ref, and link_id.
Framework adapters can wrap this SDK with a more idiomatic surface, but this package stays close to the public MCP tool contract.
Deside has three public MCP integration surfaces:
| Surface | Use it for | Source |
|---|---|---|
| MCP endpoint and docs | Protocol source of truth, auth flow, tool schemas, notifications, and errors | docs.deside.io/mcp/mcp and DesideApp/deside-docs |
| Agent Skill | Agent Skills-compatible runtimes that need operational instructions for Deside MCP | deside-messaging in DesideApp/deside-docs |
| TypeScript SDK | TypeScript apps or agents that want client helpers | this package |
When behavior or schemas differ, treat the MCP tools reference in
deside-docs as canonical and update this SDK to match it.
The SDK is framework-agnostic and expects a signer with this shape:
type DesideSigner = {
getAddress(): string | Promise<string>;
signMessage(message: string): Promise<string | { signature: string }>;
};Rules:
getAddress()must return the Solana wallet used for MCP authentication.signMessage()must sign the exact plaintext OAuth wallet challenge.- The SDK normalizes base58, hex, and base64 signatures internally.
- Adapters are responsible for bridging their runtime wallet to this contract.
For agent identity context, the signing wallet should be the owner/control
wallet for the agent identity. Source-provided agentWallet fields are metadata
unless that source and Deside explicitly define them as the controlling wallet.
The SDK exposes wrappers for the current Deside MCP tool surface:
| Wrapper | MCP tool | Scope |
|---|---|---|
sendDm |
send_dm |
dm:write |
readDms |
read_dms |
dm:read |
markDmRead |
mark_dm_read |
dm:read |
listConversations |
list_conversations |
dm:read |
getUserInfo |
get_user_info |
dm:read |
getMyIdentity |
get_my_identity |
dm:read |
listMyAgentIdentities |
list_my_agent_identities |
dm:read |
selectAgentIdentity |
select_agent_identity |
dm:read |
prepareAgentIdentityLink |
prepare_agent_identity_link |
dm:write |
createAgentIdentityLink |
create_agent_identity_link |
dm:write |
revokeAgentIdentityLink |
revoke_agent_identity_link |
dm:write |
searchAgents |
search_agents |
dm:read |
All MCP tools require authentication. The default SDK OAuth scope is:
dm:read dm:write
The SDK performs the practical Deside MCP client flow:
- Open an MCP session with
initialize. - Send
notifications/initialized. - Register an OAuth client when needed.
- Run OAuth 2.0 authorization code + PKCE.
- Sign the Deside wallet challenge with the provided Solana signer.
- Exchange the authorization code for OAuth tokens.
- Call MCP tools with
Authorization: Bearer <access_token>and the MCP session id.
The SDK stores OAuth token material in memory per SDK instance. Persisting token state, coordinating multiple processes, or integrating custom storage is the adapter's responsibility.
Default endpoint:
https://mcp.deside.io/mcp
Most authenticated wallets do not need an explicit agent selection step.
Deside requires explicit MCP agent selection only when the authenticated owner/control wallet controls two or more backed canonical agents in the same registry/source. In that case, the wallet alone is ambiguous.
For headless or programmatic OAuth, pass the desired agent reference before authentication:
const sdk = new DesideMcpSdk({
oauthRedirectUri: "https://agent.example.com/callback",
agentRef: "agent-slug-or-catalog-id-or-source-entry-id",
});The SDK sends that value to the MCP server as OAuth agent_ref. If the wallet
is ambiguous and no agentRef is provided, connect() throws
DesideAgentSelectionRequiredError with the server-provided selectionUrl,
candidates, and links.
For an already authenticated MCP session, use:
const identities = await sdk.listMyAgentIdentities(signer);
await sdk.selectAgentIdentity(signer, {
agent_ref: "agent-slug-or-catalog-id-or-source-entry-id",
});Owner-signed links can be used to remember explicit same-owner declarations without merging canonical agents:
const challenge = await sdk.prepareAgentIdentityLink(signer, {
primary_agent_catalog_id: "primary-catalog-id",
agent_catalog_ids: ["primary-catalog-id", "related-catalog-id"],
label: "production agent",
});
const message = (challenge as { message: string }).message;
const signed = await signer.signMessage(message);
await sdk.createAgentIdentityLink(signer, {
primary_agent_catalog_id: "primary-catalog-id",
agent_catalog_ids: ["primary-catalog-id", "related-catalog-id"],
label: "production agent",
signed_message: message,
signature: typeof signed === "string" ? signed : signed.signature,
});To remove a stored owner declaration:
await sdk.revokeAgentIdentityLink(signer, {
link_id: "link-id",
});Revoking a link prevents future selection by that link. It does not erase the historical fact that the owner/control wallet once made the declaration.
searchAgents is an authenticated lookup over visible Deside directory agents.
It is intentionally narrow:
await sdk.searchAgents(signer, { wallet: "OwnerWallet...", limit: 10 });
await sdk.searchAgents(signer, { name: "xona", limit: 10, offset: 0 });It accepts either wallet or name, plus bounded pagination. It does not expose
category, capability, service, ranking, analytics, bulk export, or paid API
filters.
Public anonymous directory access belongs to Deside's public API and web surfaces, not to unauthenticated MCP tools.
Install dependencies:
npm installRun local checks:
npm run typecheck
npm run buildRun the smoke harness:
npm run smokeSmoke files:
Required smoke env vars:
SOLANA_PRIVATE_KEYDESIDE_OAUTH_REDIRECT_URI
Optional smoke env vars:
DESIDE_TO_WALLETDESIDE_TEXTDESIDE_SEARCH_WALLETDESIDE_SEARCH_NAMEDESIDE_MCP_BASE_URLDESIDE_OAUTH_SCOPEDESIDE_OAUTH_CLIENT_NAMEDESIDE_AGENT_REF
Production note:
- for production OAuth,
DESIDE_OAUTH_REDIRECT_URIshould usehttps://
@desideapp/mcp-sdk is the shared protocol base for TypeScript integrations.
Framework-specific packages sit above it, for example:
- GOAT adapters
- Solana Agent Kit adapters
- ElizaOS adapters
This package should not absorb framework-specific runtime code, UI/widgets, product dashboards, billing APIs, or broad directory API functionality.
Before publishing:
npm run build
npm run typecheck
npm run smoke
npm publish --access publicThe package publishes:
distREADME.mdLICENSE
While an adapter is under local development, it may temporarily depend on
@desideapp/mcp-sdk via link:. Before external publication or upstream PR,
switch the adapter to a real semver dependency on @desideapp/mcp-sdk.
Issues and pull requests should be opened in the main Deside repository.
Keep changes aligned with the MCP endpoint contract. If a tool shape changes, update the server, public MCP docs, SDK wrapper, smoke coverage, and package README together.
MIT (c) DESIDE