> ## Documentation Index
> Fetch the complete documentation index at: https://pdsx.zzstoatzz.io/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Server

> integrate pdsx with AI agents via the model context protocol

pdsx includes an MCP (model context protocol) server that exposes atproto record operations to AI agents like Claude Code, Cursor, and other MCP-compatible clients.

## hosted instance

the easiest way to get started - no installation required:

```bash theme={null}
# add to claude code (read-only access)
claude mcp add-json pdsx '{"type": "http", "url": "https://pdsx-by-zzstoatzz.fastmcp.app/mcp"}'
```

this gives your AI agent access to read public atproto data immediately.

### adding authentication

for write operations (create, update, delete), add your credentials:

```bash theme={null}
claude mcp add-json pdsx '{
  "type": "http",
  "url": "https://pdsx-by-zzstoatzz.fastmcp.app/mcp",
  "headers": {
    "x-atproto-handle": "your.handle",
    "x-atproto-password": "your-app-password"
  }
}'
```

<Warning>
  use an [app password](https://bsky.app/settings/app-passwords), not your account password. app passwords can be revoked individually if compromised.
</Warning>

### custom PDS

if you're running your own PDS (personal data server), add the PDS URL header:

```bash theme={null}
claude mcp add-json pdsx '{
  "type": "http",
  "url": "https://pdsx-by-zzstoatzz.fastmcp.app/mcp",
  "headers": {
    "x-atproto-handle": "your.handle",
    "x-atproto-password": "your-app-password",
    "x-atproto-pds-url": "https://your-pds.example.com"
  }
}'
```

<Note>
  when reading public data from other users, pdsx automatically discovers their PDS - you don't need to configure anything. the `x-atproto-pds-url` header is only needed for write operations to your own account on a custom PDS.
</Note>

## local/self-hosted

run the MCP server locally for development or self-hosting:

```bash theme={null}
# install with mcp extra
uv add pdsx[mcp]

# run in stdio mode
ATPROTO_HANDLE=your.handle ATPROTO_PASSWORD=your-app-password pdsx-mcp
```

or use uvx without installing:

```bash theme={null}
uvx --from 'pdsx[mcp]' pdsx-mcp
```

### configure claude code for local server

```bash theme={null}
claude mcp add pdsx -- pdsx-mcp
```

with authentication via environment:

```bash theme={null}
claude mcp add pdsx --env ATPROTO_HANDLE=your.handle --env ATPROTO_PASSWORD=your-app-password -- pdsx-mcp
```

## available tools

the MCP server exposes five tools for record operations:

| tool            | auth required       | description                  |
| --------------- | ------------------- | ---------------------------- |
| `list_records`  | only without `repo` | list records in a collection |
| `get_record`    | only without `repo` | get a specific record by URI |
| `create_record` | always              | create a new record          |
| `update_record` | always              | update an existing record    |
| `delete_record` | always              | delete a record              |

### read operations

read operations work without authentication when you specify a `repo`:

```
list_records(collection="app.bsky.feed.post", repo="zzstoatzz.io", limit=10)
get_record(uri="at://did:plc:.../app.bsky.feed.post/abc123")
```

without a `repo` parameter, the server reads from your authenticated account.

### write operations

write operations always require authentication:

```
create_record(collection="app.bsky.feed.post", record={"text": "hello from pdsx!"})
update_record(uri="app.bsky.feed.post/abc123", updates={"text": "updated text"})
delete_record(uri="app.bsky.feed.post/abc123")
```

## PDS discovery

pdsx automatically discovers the correct PDS for any user. when you query records from `repo="zzstoatzz.io"`, it:

1. resolves the handle to a DID
2. looks up the DID document
3. extracts the PDS endpoint
4. queries that PDS directly

this means you can read records from users on any PDS - including self-hosted instances - without any configuration.

## common collections

here are the most commonly used collections:

| collection               | description  | rkey format                 |
| ------------------------ | ------------ | --------------------------- |
| `app.bsky.feed.post`     | posts/skeets | tid (e.g., `3m4ryxwq5dt2i`) |
| `app.bsky.actor.profile` | user profile | always `self`               |
| `app.bsky.feed.like`     | likes        | tid                         |
| `app.bsky.feed.repost`   | reposts      | tid                         |
| `app.bsky.graph.follow`  | follows      | tid                         |
| `app.bsky.graph.list`    | lists        | tid                         |

## prompts

the MCP server includes built-in prompts for guidance:

* `usage_guide` - general usage instructions
* `create_post_guide` - how to create posts with rich text

## resources

the server exposes one resource:

* `pdsx://me` - shows your authenticated identity (handle and DID)

## example workflows

### reading someone's recent posts

```
list_records(
  collection="app.bsky.feed.post",
  repo="jay.bsky.team",
  limit=5
)
```

### getting a user's bio

```
get_record(
  uri="app.bsky.actor.profile/self",
  repo="zzstoatzz.io"
)
```

### creating a post

```
create_record(
  collection="app.bsky.feed.post",
  record={"text": "posted via pdsx MCP!"}
)
```

### updating your bio

```
update_record(
  uri="app.bsky.actor.profile/self",
  updates={"description": "new bio text"}
)
```

## troubleshooting

### "authentication required"

you're trying to perform an operation that needs credentials:

* write operations (create, update, delete) always need auth
* read operations without `repo` parameter need auth

add credentials via headers (hosted) or environment variables (local).

### empty results for custom PDS users

if you're getting empty results when querying a user on a self-hosted PDS, ensure you're using a recent version of pdsx. older versions didn't automatically discover custom PDS endpoints.

### "could not find repo"

the handle or DID couldn't be resolved. check:

* the handle is spelled correctly
* the account exists and isn't deleted
* your network can reach the PDS

## what's next

* [configure for writes](/guides/configure-for-writes) - set up authentication
* [read any repository](/guides/read-repositories) - explore public data with the CLI
* [addressing](/concepts/addressing) - understand AT-URIs and record addressing
