Skip to content
/ slink Public

A tool for calling XRPC APIs, automatically generated from Lexicon.

License

Notifications You must be signed in to change notification settings

agentio/slink

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

slink

slink is a command line tool for calling APIs described with Lexicon.

slink's API-calling functions are automatically generated by slink itself, and slink can be used to generate Go client libraries and CLIs for arbitrary Lexicon descriptions. With an optional manifest, generated code can be limited to only what is needed to support specific functions and records.

slink stores no state in local files; all configuration (including auth tokens) is instead read from environment variables. Using these variables, slink can be configured to make direct calls to XRPC services and slink can also connect to remote services through a proxy such as IO which handles routing and authentication.

Installing slink

To install slink on any system with Go installed:

  1. clone the repo.
  2. copy the lexicons directory to the root of the repo.
  3. run make all. This will generate XRPC command handlers and a CLI in the gen directory. It then builds everything to create slink.

Using slink

It's this easy to use slink to call XRPC APIs:

% SLINK_HOST=https://inkcap.us-east.host.bsky.network slink call com.atproto.server describe-server
{
  "availableUserDomains": [
    ".inkcap.us-east.host.bsky.network"
  ],
  "contact": {},
  "did": "did:web:inkcap.us-east.host.bsky.network",
  "inviteCodeRequired": true,
  "links": {
    "privacyPolicy": "https://bsky.social/about/support/privacy-policy",
    "termsOfService": "https://bsky.social/about/support/tos"
  }
}

You just need to specify the host to be called with the SLINK_HOST environment variable (be sure to include the https:// or http:// prefix).

export SLINK_HOST=$YOUR_PDS_URL

With that, you can use slink to make unauthenticated calls.

$ slink call com.atproto.sync list-repos
{
  "cursor": "...",
  "repos": [
    {
      "active": true,
      "did": "did:plc:...",
      "head": "...",
      "rev": "..."
    },
    {
      "active": true,
      "did": "did:plc:...",
      "head": "...",
      "rev": "..."
    }
  ]
}

Use the slink built-in help to see what is possible:

$ slink call
Call XRPC methods

Usage:
  slink call [command]

Available Commands:
  app.bsky.actor            Call XRPC methods under app.bsky.actor
  app.bsky.ageassurance     Call XRPC methods under app.bsky.ageassurance
  app.bsky.bookmark         Call XRPC methods under app.bsky.bookmark
  app.bsky.contact          Call XRPC methods under app.bsky.contact
  app.bsky.draft            Call XRPC methods under app.bsky.draft
  app.bsky.feed             Call XRPC methods under app.bsky.feed
  app.bsky.graph            Call XRPC methods under app.bsky.graph
  app.bsky.labeler          Call XRPC methods under app.bsky.labeler
  app.bsky.notification     Call XRPC methods under app.bsky.notification
  app.bsky.unspecced        Call XRPC methods under app.bsky.unspecced
  app.bsky.video            Call XRPC methods under app.bsky.video
  chat.bsky.actor           Call XRPC methods under chat.bsky.actor
  chat.bsky.convo           Call XRPC methods under chat.bsky.convo
  chat.bsky.moderation      Call XRPC methods under chat.bsky.moderation
  com.atproto.admin         Call XRPC methods under com.atproto.admin
  com.atproto.identity      Call XRPC methods under com.atproto.identity
  com.atproto.label         Call XRPC methods under com.atproto.label
  com.atproto.lexicon       Call XRPC methods under com.atproto.lexicon
  com.atproto.moderation    Call XRPC methods under com.atproto.moderation
  com.atproto.repo          Call XRPC methods under com.atproto.repo
  com.atproto.server        Call XRPC methods under com.atproto.server
  com.atproto.sync          Call XRPC methods under com.atproto.sync
  com.atproto.temp          Call XRPC methods under com.atproto.temp
  tools.ozone.communication Call XRPC methods under tools.ozone.communication
  tools.ozone.hosting       Call XRPC methods under tools.ozone.hosting
  tools.ozone.moderation    Call XRPC methods under tools.ozone.moderation
  tools.ozone.safelink      Call XRPC methods under tools.ozone.safelink
  tools.ozone.server        Call XRPC methods under tools.ozone.server
  tools.ozone.set           Call XRPC methods under tools.ozone.set
  tools.ozone.setting       Call XRPC methods under tools.ozone.setting
  tools.ozone.signature     Call XRPC methods under tools.ozone.signature
  tools.ozone.team          Call XRPC methods under tools.ozone.team
  tools.ozone.verification  Call XRPC methods under tools.ozone.verification

Flags:
  -h, --help   help for call

Use "slink call [command] --help" for more information about a command.

$ slink call com.atproto.sync
Call XRPC methods under com.atproto.sync

Usage:
  slink call com.atproto.sync [command]

Available Commands:
  get-blob                 Get a blob associated with a given account. Returns the full blob as original...
  get-blocks               Get data blocks from a given repo, by CID. For example, intermediate MST node...
  get-checkout             DEPRECATED - please use com.atproto.sync.getRepo instead
  get-head                 DEPRECATED - please use com.atproto.sync.getLatestCommit instead
  get-host-status          Returns information about a specified upstream host, as consumed by the serve...
  get-latest-commit        Get the current commit CID & revision of the specified repo. Does not require...
  get-record               Get data blocks needed to prove the existence or non-existence of record in t...
  get-repo                 Download a repository export as CAR file. Optionally only a 'diff' since a pr...
  get-repo-status          Get the hosting status for a repository, on this server. Expected to be imple...
  list-blobs               List blob CIDs for an account, since some repo revision. Does not require aut...
  list-hosts               Enumerates upstream hosts (eg, PDS or relay instances) that this service cons...
  list-repos               Enumerates all the DID, rev, and commit CID for all repos hosted by this serv...
  list-repos-by-collection Enumerates all the DIDs which have records with the given collection NSID.
  notify-of-update         Notify a crawling service of a recent update, and that crawling should resume...
  request-crawl            Request a service to persistently crawl hosted repos. Expected use is new PDS...

Flags:
  -h, --help   help for com.atproto.sync

Use "slink call com.atproto.sync [command] --help" for more information about a command.

To make authenticated calls, use SLINK_AUTH to specify the authentication header. To make calls as a PDS admin, set SLINK_AUTH to the Basic Auth credentials for the admin.

export SLINK_AUTH="Basic $(echo -n "admin:$ADMIN_PASSWORD" | base64)"

Now you can make calls as the PDS admin.

$ slink call com.atproto.admin get-invite-codes
{
  "codes": [
    {
      "available": 1,
      "code": "...",
      "createdAt": "...",
      "createdBy": "admin",
      "forAccount": "admin"
    },
    ...
  ]
  "cursor": "..."
}

To make calls as a PDS user, set SLINK_AUTH to a Bearer token for the user. Here's one way to do that:

export SLINK_AUTH="Bearer $(slink call com.atproto.server create-session --identifier $HANDLE --password $PASSWORD | jq .accessJwt -r)"

With this, you can make calls as the user.

$ slink call com.atproto.server get-session
{
  "active": true,
  "did": "did:plc:...",
  "email": "...",
  "emailConfirmed": true,
  "handle": "..."
}

Using slink with a sidecar proxy

slink can be configured to use a sidecar proxy like IO. This moves authentication and routing to the sidecar and can allow credential owners to keep their secrets secure while allowing these secrets to be used to call specific (allow-listed) XRPC methods.

If the sidecar proxy listens on a TCP socket, configuration is trivial: just set SLINK_HOST to the port where the proxy is listening. If the sidecar proxy listens on a Unix domain socket, it's also really easy: set SLINK_HOST to unix: followed by the socket name, e.g.

export SLINK_HOST=unix:@io-calling-pds

Here @io-calling-pds is the name of a Linux abstract socket that a sidecar provides for calling a PDS.

Limiting slink to a subset of Lexicon descriptions

See the make manifest make target for an example build of slink that only supports the specific functions and records in the sample-manifest.json file. When you provide a manifest, slink automatically finds all the lexicon dependencies of the symbols in the manifest and generates only what is needed for these generated implementations to work. While this might not make sense for slink itself, it's a great way to generate a dependency-minimized client library for use in a Lexicon-based application.

Copyright

Copyright 2026, Agent IO (Tim Burks).

License

slink is released under the AGPL.

Warning!

slink is pre-release software. It could change in significant ways, so before depending on it, get in touch!

-- Tim Burks @timburks.me | @agent.io

About

A tool for calling XRPC APIs, automatically generated from Lexicon.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published