Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Circle MCP Server — Environment Configuration
#
# Copy this file to .env and fill in your values.
# The .env file is gitignored and must never be committed.

# Required: Your Circle Admin API token
# Obtain from: Circle Admin > Settings > API
CIRCLE_API_TOKEN=***REDACTED***

# Optional: Circle API base URL (defaults to https://app.circle.so)
# Only change this if you have a custom Circle deployment.
# CIRCLE_BASE_URL=https://app.circle.so
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
validate:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm

- name: Install dependencies
run: npm ci

- name: Typecheck
run: npm run typecheck

- name: Build
run: npm run build

- name: Smoke tests
run: npx tsx test/smoke.ts
25 changes: 19 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
# Local development (server repo is separate)
app/

# Secrets
.env
.env.*
!.env.example

# Node
node_modules/
dist/
build/

# Local development (docs and samples that should stay out)
app/
artifacts/samples/
**/artifacts/samples/

# Test evidence (may contain token prefixes and live data)
test/evidence/

# Smithery build artifacts
.smithery/
circle-mcp.mcpb

# OS
.DS_Store
Thumbs.db

# Samples may contain PII
artifacts/samples/
**/artifacts/samples/
# IDE
.vscode/
.idea/
*.swp
*.swo
27 changes: 27 additions & 0 deletions .mcpbignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Source code and development files
src/
test/
tsconfig.json
.github/

# Type declarations (not needed at runtime)
dist/*.d.ts
dist/**/*.d.ts

# Smithery-specific files
smithery.yaml
smithery-config-schema.json
.smithery/
SMITHERY_READINESS.md

# Deployment configs for other platforms
railway.json

# Development documentation
CONTRIBUTING.md
CHANGELOG.md
docs/

# Environment files
.env
.env.example
121 changes: 121 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Changelog

All notable changes to this project will be documented in this file.

Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.3.0] — 2026-03-11

Safe Content Operations release. Three write tools enabling post creation, post updates, and comment creation — the first mutation capabilities in the server.

### Added

- **circle_create_post** — Create a new post in a specified space (name, body, space_id required; optional status, slug, is_comments_enabled, skip_notifications, user_email)
- **circle_update_post** — Update an existing post by ID (post_id required; all other fields optional). Note: published posts cannot be reverted to draft status
- **circle_create_comment** — Create a comment on a post (post_id, body required; optional user_email). Known 401 limitation with admin API tokens — permission-aware error handling included
- Safe mutation infrastructure: `mutate<T>()` method with zero-retry policy, separate from read path
- `buildMutationResponse()` envelope for consistent write tool output
- Permission-aware error handling for comment creation (401/403 → actionable workaround message)
- HTTP request type schemas (`CreatePostRequest`, `UpdatePostRequest`, `CreateCommentRequest`) with Zod validation
- MCP write tool annotations: `readOnlyHint: false`, `destructiveHint: false` on all write tools
- 38 new offline tests (95 total), covering mutation infrastructure, schemas, handlers, and error formatting

### Implementation Qualities

- No-retry policy for mutations — `mutate<T>()` has zero retry to prevent duplicate writes
- Flat endpoint pattern (`POST /api/admin/v2/posts`, not nested) — live-proven against Circle API
- Flat payload pattern (no resource key wrapper) — live-proven against Circle API
- `idempotentHint: true` on update, `idempotentHint: false` on create operations
- Comment creation includes graceful degradation: 401 returns structured workaround guidance instead of raw error
- All write tool schemas use `.describe()` for agent discoverability
- `body` field empty on mutation responses is documented — use GET after mutation for populated body

### Known Limitations

- All v0.1.0 and v0.2.0 limitations still apply
- Comment creation (`circle_create_comment`) returns 401 with admin API tokens — a Circle API permission restriction, not a server bug
- Published posts cannot be reverted to draft status via `circle_update_post` (Circle returns 400)
- Mutation responses return `body: ""` — the API does not populate `body` on write responses. Use `circle_get_post` after mutation for full content
- No delete/archive operations — v0.3.0 is non-destructive by design
- No file/image upload support
- No event/live-stream management
- No member role or permission modification tools

---

## [0.2.0] — 2026-03-11

Community Intelligence release. Seven new read-only tools expanding coverage to comments, topics, community metadata, space groups, and two derived analytics tools.

### Added

- **circle_list_comments** — List comments on a post with pagination
- **circle_get_comment** — Retrieve a single comment by numeric ID
- **circle_list_topics** — List topics (tags) in the community with pagination
- **circle_get_community** — Retrieve community-level metadata (name, slug, settings)
- **circle_list_space_groups** — List space groups with their contained space IDs
- **circle_detect_unanswered_posts** — Scan posts with zero comments to surface unanswered questions (derived, multi-call)
- **circle_community_health** — Point-in-time health snapshot: space count, post count, member count, top spaces by activity (derived, multi-call)
- Zod `.strict()` input validation on all 7 new tool schemas
- `structuredContent` with `computation` metadata on derived tools for transparency
- Live validation script (`test/live-v020.ts`) with machine-readable evidence output
- 21 new offline tests (57 total), 7 new live tests (19 total)

### Implementation Qualities

- All 13 tools share consistent annotations (`readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`)
- Derived tools aggregate multiple API calls with transparent `computation` metadata
- "Unanswered" heuristic (`comments_count === 0`) documented and caveated in tool description
- Community health snapshot is point-in-time, not historical trending — properly caveated
- MCP runtime handshake confirms v0.2.0 and 13-tool listing

### Known Limitations

- All v0.1.0 limitations still apply
- `circle_detect_unanswered_posts` uses `comments_count === 0` as heuristic — may not account for deleted comments
- `circle_community_health` is a point-in-time snapshot, not a trend — no historical comparison
- `circle_get_community` may return `url: "undefined"` for communities without a custom domain (Circle API data issue)

---

## [0.1.0] — 2026-03-11

Initial release. Six read-only tools for querying a Circle.so community via the Admin API v2.

### Added

- **circle_list_spaces** — List spaces with pagination and sorting (7 sort options)
- **circle_get_space** — Retrieve a single space by numeric ID
- **circle_list_posts** — List posts with filtering by space, status, and text search
- **circle_get_post** — Retrieve a single post by numeric ID (includes full TipTap body)
- **circle_list_members** — List community members with status filtering
- **circle_search** — Search across the community (returns lightweight summary objects)
- MCP stdio transport for Claude Desktop and MCP Inspector integration
- Zod `.strict()` input validation on all 6 tool schemas
- Response truncation guard at 100,000 characters with structured truncation notices
- `structuredContent` in all tool responses (never truncated, machine-parseable)
- Retry with exponential backoff for transient failures (429, 500, 502, 503)
- `Retry-After` header support on 429 responses
- Error normalization with actionable messages for all HTTP status codes
- Fail-fast environment validation (`CIRCLE_API_TOKEN` required at startup)
- 36 offline smoke tests covering schemas, response builder, truncation, and error handling
- 12 live smoke tests against the Circle API
- Claude Desktop integration documentation (production + development configs)

### Implementation Qualities

- Zero external HTTP dependencies — uses Node.js native `fetch` (Node 18+)
- Strict TypeScript with no `any` types
- Consistent tool annotations (`readOnlyHint`, `idempotentHint`, `destructiveHint`, `openWorldHint`)
- All tools share `buildToolResponse()` for consistent output shape
- MCP SDK compatibility verified via `tools/list` JSON-RPC handshake

### Known Limitations

- Read-only: no create, update, or delete operations
- No cumulative rate-limit tracking (individual 429s handled by retry)
- Search returns summary objects, not full resources
- Page-based pagination only (no cursor pagination)
- TipTap body always included in list posts responses (use smaller `per_page` to manage size)
- No streaming support
15 changes: 8 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@

Thanks for your interest in Circle MCP.

## Where to Contribute
## Where to contribute

- **Server code, tools, and tests** — contribute to [circle-mcp-server](https://github.com/iamnortey/circle-mcp-server). See its [CONTRIBUTING.md](https://github.com/iamnortey/circle-mcp-server/blob/main/CONTRIBUTING.md).
- **Documentation fixes** — open a PR in this repository.
- **Server code, tools, and tests** — open a PR in this repository against `main`. Source lives under `src/`, tests under `test/`.
- **Documentation fixes** — open a PR with the doc change.

## Documentation Changes
## Code changes

1. Fork the repo and create a branch from `main`.
2. Make your changes. Keep PRs focused.
3. Open a pull request with a clear description.
3. Run `npm run validate` (typecheck + build + smoke tests) before pushing.
4. Open a pull request with a clear description.

## Reporting Issues
## Reporting issues

Open an issue at [github.com/iamnortey/circle-mcp-server/issues](https://github.com/iamnortey/circle-mcp-server/issues) for server bugs. For documentation issues, open an issue in this repo.
Open an issue at [github.com/iamnortey/circle-mcp/issues](https://github.com/iamnortey/circle-mcp/issues) for bugs (server or documentation).

## Security

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ Log in to your Circle community as an admin. Go to **Settings** > **API** > **Ge
### 2. Clone and build

```bash
git clone https://github.com/iamnortey/circle-mcp-server.git
cd circle-mcp-server
git clone https://github.com/iamnortey/circle-mcp.git
cd circle-mcp
npm install && npm run build
```

Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ I will acknowledge receipt within 48 hours and aim to provide a fix or mitigatio

## Scope

This policy covers the documentation and configuration in this repository. For vulnerabilities in the Circle MCP Server code itself, report to the [server repository](https://github.com/iamnortey/circle-mcp-server/security).
This policy covers the source code, configuration, and documentation in this repository. Report vulnerabilities to the email above or via [GitHub Security Advisories](https://github.com/iamnortey/circle-mcp/security/advisories).
Loading
Loading