cited-cli 0.3.3__tar.gz → 0.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cited_cli-0.3.3 → cited_cli-0.3.4}/PKG-INFO +4 -4
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/pyproject.toml +1 -1
- cited_cli-0.3.4/packages/core/src/cited_core/__init__.py +1 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/README.md +5 -0
- cited_cli-0.3.4/packages/mcp/SKILL.md +54 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/pyproject.toml +2 -2
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/tools/audit.py +37 -9
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/tools/auth.py +29 -8
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/tools/business.py +29 -7
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/tools/job.py +5 -1
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/tools/recommend.py +21 -5
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/tools/solution.py +17 -4
- {cited_cli-0.3.3 → cited_cli-0.3.4}/pyproject.toml +4 -4
- {cited_cli-0.3.3 → cited_cli-0.3.4}/scripts/deploy-mcp.sh +179 -32
- {cited_cli-0.3.3 → cited_cli-0.3.4}/scripts/release.sh +4 -2
- cited_cli-0.3.3/packages/core/src/cited_core/__init__.py +0 -1
- {cited_cli-0.3.3 → cited_cli-0.3.4}/.github/workflows/ci.yml +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/.github/workflows/release.yml +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/.gitignore +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/CLAUDE.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/DEMO.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/FUTURE.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/LICENSE +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/README.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/TEST_RUNBOOK.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/.claude-plugin/marketplace.json +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/.claude-plugin/plugin.json +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/.mcp.json +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/CLAUDE_DESKTOP_SETUP.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/agents/geo-analyst.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/commands/audit.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/commands/recommend.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/commands/status.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/settings.json +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/skills/business-setup/SKILL.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/skills/geo-audit/SKILL.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/cited-plugins/skills/geo-recommend/SKILL.md +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/src/cited_core/api/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/src/cited_core/api/client.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/src/cited_core/api/endpoints.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/src/cited_core/auth/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/src/cited_core/auth/oauth_server.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/src/cited_core/auth/store.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/src/cited_core/config/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/src/cited_core/config/constants.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/src/cited_core/config/manager.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/core/src/cited_core/errors.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/Dockerfile +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/__main__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/auth_provider.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/context.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/remote.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/server.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/tools/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/packages/mcp/src/cited_mcp/tools/_helpers.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/scripts/cleanup_dev.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/scripts/dev-install.sh +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/__main__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/api/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/api/client.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/api/endpoints.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/app.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/auth/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/auth/oauth_server.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/auth/store.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/agent.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/analytics.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/audit.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/auth.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/business.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/config_cmd.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/hq.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/job.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/mcp_cmd.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/named_audit.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/recommend.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/commands/solution.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/config/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/config/constants.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/config/manager.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/context.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/server.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/tools/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/tools/_helpers.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/tools/audit.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/tools/auth.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/tools/business.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/tools/job.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/tools/recommend.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/mcp/tools/solution.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/output/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/output/formatter.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/output/progress.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/output/tables.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/utils/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/utils/errors.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/src/cited_cli/utils/interactive.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/__init__.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/conftest.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/test_api_client.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/test_auth.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/test_config.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/test_live_pipeline.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/test_mcp_server.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/test_mcp_tools.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/test_output.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/test_pipeline.py +0 -0
- {cited_cli-0.3.3 → cited_cli-0.3.4}/tests/test_version.py +0 -0
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cited-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: CLI for the Cited GEO platform
|
|
5
5
|
Author-email: Cited <support@youcited.com>
|
|
6
6
|
License-Expression: LicenseRef-Proprietary
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Python: >=3.11
|
|
9
|
-
Requires-Dist: cited-core>=0.3.
|
|
9
|
+
Requires-Dist: cited-core>=0.3.4
|
|
10
10
|
Requires-Dist: rich>=13.0.0
|
|
11
11
|
Requires-Dist: typer>=0.15.0
|
|
12
12
|
Provides-Extra: dev
|
|
13
|
-
Requires-Dist: cited-mcp>=0.3.
|
|
13
|
+
Requires-Dist: cited-mcp>=0.3.4; extra == 'dev'
|
|
14
14
|
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
15
15
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
16
16
|
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
17
17
|
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
18
18
|
Provides-Extra: mcp
|
|
19
|
-
Requires-Dist: cited-mcp>=0.3.
|
|
19
|
+
Requires-Dist: cited-mcp>=0.3.4; extra == 'mcp'
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
|
|
22
22
|
# Cited CLI
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.4"
|
|
@@ -101,6 +101,7 @@ cited-mcp-remote
|
|
|
101
101
|
|------|-------------|
|
|
102
102
|
| `check_auth_status` | Check current authentication status |
|
|
103
103
|
| `login` | Authenticate via browser OAuth flow |
|
|
104
|
+
| `logout` | Clear stored authentication token |
|
|
104
105
|
|
|
105
106
|
### Businesses
|
|
106
107
|
| Tool | Description |
|
|
@@ -194,6 +195,10 @@ ruff check packages/mcp/
|
|
|
194
195
|
mypy packages/mcp/src --ignore-missing-imports
|
|
195
196
|
```
|
|
196
197
|
|
|
198
|
+
## Privacy Policy
|
|
199
|
+
|
|
200
|
+
See our [Privacy Policy](https://youcited.com/privacy) for details on data collection, usage, storage, and third-party sharing.
|
|
201
|
+
|
|
197
202
|
## License
|
|
198
203
|
|
|
199
204
|
Proprietary — see [youcited.com](https://youcited.com) for terms.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cited
|
|
3
|
+
description: Audit, optimize, and monitor your business's visibility in AI-powered search engines
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cited — AI Search Visibility Platform
|
|
7
|
+
|
|
8
|
+
Cited helps businesses measure and improve how they appear in AI-powered search results from ChatGPT, Claude, Perplexity, and Gemini. Use these tools to run GEO (Generative Engine Optimization) audits, get actionable recommendations, and generate ready-to-deploy solutions.
|
|
9
|
+
|
|
10
|
+
## Core Workflow
|
|
11
|
+
|
|
12
|
+
The typical flow is: **Business Setup → Audit → Recommendations → Solutions**
|
|
13
|
+
|
|
14
|
+
### 1. Business Setup
|
|
15
|
+
- `check_auth_status` — Verify authentication and check plan limits
|
|
16
|
+
- `list_businesses` — See existing businesses
|
|
17
|
+
- `create_business` — Add a new business (requires name, website, description)
|
|
18
|
+
- `crawl_business` — Crawl the business website to gather data for analysis
|
|
19
|
+
|
|
20
|
+
### 2. Run an Audit
|
|
21
|
+
- `create_audit_template` — Define what questions to audit (e.g., "What is [business]?", "Best [industry] tools")
|
|
22
|
+
- `start_audit` — Launch the audit using a template
|
|
23
|
+
- `get_audit_status` — Poll until the audit completes (typically 2-4 minutes)
|
|
24
|
+
- `get_audit_result` — Retrieve visibility scores, citation rates, and competitor data
|
|
25
|
+
|
|
26
|
+
### 3. Generate Recommendations
|
|
27
|
+
- `start_recommendation` — Analyze audit results and generate improvement recommendations
|
|
28
|
+
- `get_recommendation_insights` — Get structured insights with question-level analysis, competitor head-to-head comparisons, and strengthening tips. Each insight includes `source_type` and `source_id` needed for the next step.
|
|
29
|
+
|
|
30
|
+
### 4. Create Solutions
|
|
31
|
+
- `start_solution` — Generate implementation artifacts (schema markup, content templates, outreach playbooks) for a specific insight
|
|
32
|
+
- `get_solution_result` — Retrieve the solution with downloadable artifacts
|
|
33
|
+
|
|
34
|
+
## Example Prompts
|
|
35
|
+
|
|
36
|
+
**Run a full GEO audit:**
|
|
37
|
+
> "List my businesses, then run a GEO audit on [business name]. When it's done, show me my visibility scores and which competitors are being cited instead of me."
|
|
38
|
+
|
|
39
|
+
**Competitive analysis:**
|
|
40
|
+
> "Run an audit on my business for these questions: 'Best CRM software for small business', 'Top sales automation tools', 'What is [my product]?'. Then generate recommendations and show me the head-to-head comparisons with my top competitors."
|
|
41
|
+
|
|
42
|
+
**Generate solutions:**
|
|
43
|
+
> "Look at my latest audit recommendations and generate solutions for the top 3 highest-risk insights. I want to see the schema markup and content changes I need to make."
|
|
44
|
+
|
|
45
|
+
**Monitor over time:**
|
|
46
|
+
> "Show me the health scores for my business and compare them to my last audit. What has improved and what still needs work?"
|
|
47
|
+
|
|
48
|
+
## Tips
|
|
49
|
+
|
|
50
|
+
- Always call `check_auth_status` first to verify authentication and plan limits
|
|
51
|
+
- Audits take 2-4 minutes — poll `get_audit_status` every 15 seconds
|
|
52
|
+
- Use `get_recommendation_insights` (not `get_recommendation_result`) for structured, actionable data
|
|
53
|
+
- Solutions have a concurrency limit of 3 — wait for one batch to complete before starting more
|
|
54
|
+
- Each insight's `source_type` and `source_id` map directly to `start_solution` parameters
|
|
@@ -4,14 +4,14 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cited-mcp"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.4"
|
|
8
8
|
description = "MCP server for the Cited GEO platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "LicenseRef-Proprietary"
|
|
11
11
|
requires-python = ">=3.11"
|
|
12
12
|
authors = [{ name = "Cited", email = "support@youcited.com" }]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"cited-core>=0.3.
|
|
14
|
+
"cited-core>=0.3.4",
|
|
15
15
|
"mcp>=1.26.0",
|
|
16
16
|
"PyJWT>=2.8.0",
|
|
17
17
|
]
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
5
|
from mcp.server.fastmcp import Context
|
|
6
|
+
from mcp.types import ToolAnnotations
|
|
6
7
|
|
|
7
8
|
from cited_core.api import endpoints
|
|
8
9
|
from cited_core.errors import CitedAPIError
|
|
@@ -11,7 +12,10 @@ from cited_mcp.server import mcp
|
|
|
11
12
|
from cited_mcp.tools._helpers import _api_error_response, _auth_check, _get_ctx
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
@mcp.tool(
|
|
15
|
+
@mcp.tool(
|
|
16
|
+
title="List Audit Templates",
|
|
17
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
18
|
+
)
|
|
15
19
|
async def list_audit_templates(
|
|
16
20
|
ctx: Context[Any, CitedContext, Any],
|
|
17
21
|
business_id: str | None = None,
|
|
@@ -34,7 +38,10 @@ async def list_audit_templates(
|
|
|
34
38
|
return _api_error_response(e)
|
|
35
39
|
|
|
36
40
|
|
|
37
|
-
@mcp.tool(
|
|
41
|
+
@mcp.tool(
|
|
42
|
+
title="Get Audit Template",
|
|
43
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
44
|
+
)
|
|
38
45
|
async def get_audit_template(ctx: Context[Any, CitedContext, Any], named_audit_id: str) -> Any:
|
|
39
46
|
"""Get a specific audit template by ID."""
|
|
40
47
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -48,7 +55,10 @@ async def get_audit_template(ctx: Context[Any, CitedContext, Any], named_audit_i
|
|
|
48
55
|
return _api_error_response(e)
|
|
49
56
|
|
|
50
57
|
|
|
51
|
-
@mcp.tool(
|
|
58
|
+
@mcp.tool(
|
|
59
|
+
title="Create Audit Template",
|
|
60
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False, openWorldHint=False),
|
|
61
|
+
)
|
|
52
62
|
async def create_audit_template(
|
|
53
63
|
ctx: Context[Any, CitedContext, Any],
|
|
54
64
|
name: str,
|
|
@@ -79,7 +89,10 @@ async def create_audit_template(
|
|
|
79
89
|
return _api_error_response(e)
|
|
80
90
|
|
|
81
91
|
|
|
82
|
-
@mcp.tool(
|
|
92
|
+
@mcp.tool(
|
|
93
|
+
title="Update Audit Template",
|
|
94
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
95
|
+
)
|
|
83
96
|
async def update_audit_template(
|
|
84
97
|
ctx: Context[Any, CitedContext, Any],
|
|
85
98
|
named_audit_id: str,
|
|
@@ -114,7 +127,10 @@ async def update_audit_template(
|
|
|
114
127
|
return _api_error_response(e)
|
|
115
128
|
|
|
116
129
|
|
|
117
|
-
@mcp.tool(
|
|
130
|
+
@mcp.tool(
|
|
131
|
+
title="Delete Audit Template",
|
|
132
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=True, idempotentHint=True, openWorldHint=False),
|
|
133
|
+
)
|
|
118
134
|
async def delete_audit_template(
|
|
119
135
|
ctx: Context[Any, CitedContext, Any], named_audit_id: str
|
|
120
136
|
) -> Any:
|
|
@@ -136,7 +152,10 @@ async def delete_audit_template(
|
|
|
136
152
|
return _api_error_response(e)
|
|
137
153
|
|
|
138
154
|
|
|
139
|
-
@mcp.tool(
|
|
155
|
+
@mcp.tool(
|
|
156
|
+
title="Start Audit",
|
|
157
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False, openWorldHint=False),
|
|
158
|
+
)
|
|
140
159
|
async def start_audit(
|
|
141
160
|
ctx: Context[Any, CitedContext, Any],
|
|
142
161
|
named_audit_id: str,
|
|
@@ -165,7 +184,10 @@ async def start_audit(
|
|
|
165
184
|
return _api_error_response(e)
|
|
166
185
|
|
|
167
186
|
|
|
168
|
-
@mcp.tool(
|
|
187
|
+
@mcp.tool(
|
|
188
|
+
title="Get Audit Status",
|
|
189
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
190
|
+
)
|
|
169
191
|
async def get_audit_status(ctx: Context[Any, CitedContext, Any], job_id: str) -> Any:
|
|
170
192
|
"""Check the status of a running audit job."""
|
|
171
193
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -177,7 +199,10 @@ async def get_audit_status(ctx: Context[Any, CitedContext, Any], job_id: str) ->
|
|
|
177
199
|
return _api_error_response(e)
|
|
178
200
|
|
|
179
201
|
|
|
180
|
-
@mcp.tool(
|
|
202
|
+
@mcp.tool(
|
|
203
|
+
title="Get Audit Results",
|
|
204
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
205
|
+
)
|
|
181
206
|
async def get_audit_result(ctx: Context[Any, CitedContext, Any], job_id: str) -> Any:
|
|
182
207
|
"""Get the results of a completed audit job."""
|
|
183
208
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -189,7 +214,10 @@ async def get_audit_result(ctx: Context[Any, CitedContext, Any], job_id: str) ->
|
|
|
189
214
|
return _api_error_response(e)
|
|
190
215
|
|
|
191
216
|
|
|
192
|
-
@mcp.tool(
|
|
217
|
+
@mcp.tool(
|
|
218
|
+
title="List Audits",
|
|
219
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
220
|
+
)
|
|
193
221
|
async def list_audits(
|
|
194
222
|
ctx: Context[Any, CitedContext, Any],
|
|
195
223
|
business_id: str | None = None,
|
|
@@ -5,6 +5,7 @@ from typing import Any
|
|
|
5
5
|
|
|
6
6
|
import anyio
|
|
7
7
|
from mcp.server.fastmcp import Context
|
|
8
|
+
from mcp.types import ToolAnnotations
|
|
8
9
|
|
|
9
10
|
from cited_core.api import endpoints
|
|
10
11
|
from cited_core.auth.oauth_server import OAuthCallbackServer
|
|
@@ -16,7 +17,10 @@ from cited_mcp.server import mcp
|
|
|
16
17
|
from cited_mcp.tools._helpers import _api_error_response, _auth_check, _get_ctx
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
@mcp.tool(
|
|
20
|
+
@mcp.tool(
|
|
21
|
+
title="Check Auth Status",
|
|
22
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
23
|
+
)
|
|
20
24
|
async def check_auth_status(ctx: Context[Any, CitedContext, Any]) -> Any:
|
|
21
25
|
"""Check if the user is authenticated and return their account info.
|
|
22
26
|
|
|
@@ -48,7 +52,10 @@ def _clear_session(cited_ctx: CitedContext, env: str) -> None:
|
|
|
48
52
|
cited_ctx.client._client.cookies.delete("advgeo_session")
|
|
49
53
|
|
|
50
54
|
|
|
51
|
-
@mcp.tool(
|
|
55
|
+
@mcp.tool(
|
|
56
|
+
title="Log In",
|
|
57
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False, openWorldHint=False),
|
|
58
|
+
)
|
|
52
59
|
async def login(
|
|
53
60
|
ctx: Context[Any, CitedContext, Any],
|
|
54
61
|
env: str | None = None,
|
|
@@ -101,14 +108,28 @@ async def login(
|
|
|
101
108
|
return {"success": True, "message": f"Logged in successfully (env: {target_env})"}
|
|
102
109
|
|
|
103
110
|
|
|
104
|
-
@mcp.tool(
|
|
111
|
+
@mcp.tool(
|
|
112
|
+
title="Log Out",
|
|
113
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
114
|
+
)
|
|
105
115
|
async def logout(ctx: Context[Any, CitedContext, Any]) -> Any:
|
|
106
116
|
"""Log out of Cited by clearing the stored authentication token.
|
|
107
117
|
|
|
108
|
-
|
|
109
|
-
|
|
118
|
+
In remote mode (HTTP transport), authentication is managed by the connector —
|
|
119
|
+
disconnect and reconnect to switch accounts. This tool is for stdio transport.
|
|
110
120
|
"""
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
lc: CitedContext = ctx.request_context.lifespan_context
|
|
122
|
+
|
|
123
|
+
# Remote mode: lifespan client has no token; auth is via OAuth connector
|
|
124
|
+
if not lc.client.token:
|
|
125
|
+
return {
|
|
126
|
+
"success": False,
|
|
127
|
+
"message": (
|
|
128
|
+
"Authentication is managed by your Claude connector. "
|
|
129
|
+
"To switch accounts, disconnect and reconnect the Cited connector."
|
|
130
|
+
),
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
env = lc.env
|
|
134
|
+
_clear_session(lc, env)
|
|
114
135
|
return {"success": True, "message": f"Logged out successfully (env: {env})"}
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
5
|
from mcp.server.fastmcp import Context
|
|
6
|
+
from mcp.types import ToolAnnotations
|
|
6
7
|
|
|
7
8
|
from cited_core.api import endpoints
|
|
8
9
|
from cited_core.errors import CitedAPIError
|
|
@@ -11,7 +12,10 @@ from cited_mcp.server import mcp
|
|
|
11
12
|
from cited_mcp.tools._helpers import _api_error_response, _auth_check, _get_ctx
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
@mcp.tool(
|
|
15
|
+
@mcp.tool(
|
|
16
|
+
title="List Businesses",
|
|
17
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
18
|
+
)
|
|
15
19
|
async def list_businesses(ctx: Context[Any, CitedContext, Any]) -> Any:
|
|
16
20
|
"""List all businesses for the authenticated user."""
|
|
17
21
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -23,7 +27,10 @@ async def list_businesses(ctx: Context[Any, CitedContext, Any]) -> Any:
|
|
|
23
27
|
return _api_error_response(e)
|
|
24
28
|
|
|
25
29
|
|
|
26
|
-
@mcp.tool(
|
|
30
|
+
@mcp.tool(
|
|
31
|
+
title="Get Business Details",
|
|
32
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
33
|
+
)
|
|
27
34
|
async def get_business(ctx: Context[Any, CitedContext, Any], business_id: str) -> Any:
|
|
28
35
|
"""Get details for a specific business by ID."""
|
|
29
36
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -35,7 +42,10 @@ async def get_business(ctx: Context[Any, CitedContext, Any], business_id: str) -
|
|
|
35
42
|
return _api_error_response(e)
|
|
36
43
|
|
|
37
44
|
|
|
38
|
-
@mcp.tool(
|
|
45
|
+
@mcp.tool(
|
|
46
|
+
title="Create Business",
|
|
47
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False, openWorldHint=False),
|
|
48
|
+
)
|
|
39
49
|
async def create_business(
|
|
40
50
|
ctx: Context[Any, CitedContext, Any],
|
|
41
51
|
name: str,
|
|
@@ -77,7 +87,10 @@ async def create_business(
|
|
|
77
87
|
return _api_error_response(e)
|
|
78
88
|
|
|
79
89
|
|
|
80
|
-
@mcp.tool(
|
|
90
|
+
@mcp.tool(
|
|
91
|
+
title="Update Business",
|
|
92
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
93
|
+
)
|
|
81
94
|
async def update_business(
|
|
82
95
|
ctx: Context[Any, CitedContext, Any],
|
|
83
96
|
business_id: str,
|
|
@@ -116,7 +129,10 @@ async def update_business(
|
|
|
116
129
|
return _api_error_response(e)
|
|
117
130
|
|
|
118
131
|
|
|
119
|
-
@mcp.tool(
|
|
132
|
+
@mcp.tool(
|
|
133
|
+
title="Delete Business",
|
|
134
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=True, idempotentHint=True, openWorldHint=False),
|
|
135
|
+
)
|
|
120
136
|
async def delete_business(ctx: Context[Any, CitedContext, Any], business_id: str) -> Any:
|
|
121
137
|
"""Delete a business and all its associated data.
|
|
122
138
|
|
|
@@ -138,7 +154,10 @@ async def delete_business(ctx: Context[Any, CitedContext, Any], business_id: str
|
|
|
138
154
|
return _api_error_response(e)
|
|
139
155
|
|
|
140
156
|
|
|
141
|
-
@mcp.tool(
|
|
157
|
+
@mcp.tool(
|
|
158
|
+
title="Crawl Business Website",
|
|
159
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False, openWorldHint=True),
|
|
160
|
+
)
|
|
142
161
|
async def crawl_business(ctx: Context[Any, CitedContext, Any], business_id: str) -> Any:
|
|
143
162
|
"""Start a crawl job for a business. Returns a job_id you can poll with get_job_status."""
|
|
144
163
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -150,7 +169,10 @@ async def crawl_business(ctx: Context[Any, CitedContext, Any], business_id: str)
|
|
|
150
169
|
return _api_error_response(e)
|
|
151
170
|
|
|
152
171
|
|
|
153
|
-
@mcp.tool(
|
|
172
|
+
@mcp.tool(
|
|
173
|
+
title="Get Health Scores",
|
|
174
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
175
|
+
)
|
|
154
176
|
async def get_health_scores(ctx: Context[Any, CitedContext, Any], business_id: str) -> Any:
|
|
155
177
|
"""Get GEO health scores for a business."""
|
|
156
178
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
5
|
from mcp.server.fastmcp import Context
|
|
6
|
+
from mcp.types import ToolAnnotations
|
|
6
7
|
|
|
7
8
|
from cited_core.api import endpoints
|
|
8
9
|
from cited_core.errors import CitedAPIError
|
|
@@ -17,7 +18,10 @@ _STATUS_ENDPOINTS = {
|
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
@mcp.tool(
|
|
21
|
+
@mcp.tool(
|
|
22
|
+
title="Get Job Status",
|
|
23
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
24
|
+
)
|
|
21
25
|
async def get_job_status(
|
|
22
26
|
ctx: Context[Any, CitedContext, Any],
|
|
23
27
|
job_id: str,
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
5
|
from mcp.server.fastmcp import Context
|
|
6
|
+
from mcp.types import ToolAnnotations
|
|
6
7
|
|
|
7
8
|
from cited_core.api import endpoints
|
|
8
9
|
from cited_core.errors import CitedAPIError
|
|
@@ -11,7 +12,10 @@ from cited_mcp.server import mcp
|
|
|
11
12
|
from cited_mcp.tools._helpers import _api_error_response, _auth_check, _get_ctx
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
@mcp.tool(
|
|
15
|
+
@mcp.tool(
|
|
16
|
+
title="Start Recommendations",
|
|
17
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False, openWorldHint=False),
|
|
18
|
+
)
|
|
15
19
|
async def start_recommendation(ctx: Context[Any, CitedContext, Any], audit_job_id: str) -> Any:
|
|
16
20
|
"""Start a recommendation job based on a completed audit.
|
|
17
21
|
|
|
@@ -31,7 +35,10 @@ async def start_recommendation(ctx: Context[Any, CitedContext, Any], audit_job_i
|
|
|
31
35
|
return _api_error_response(e)
|
|
32
36
|
|
|
33
37
|
|
|
34
|
-
@mcp.tool(
|
|
38
|
+
@mcp.tool(
|
|
39
|
+
title="Get Recommendation Status",
|
|
40
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
41
|
+
)
|
|
35
42
|
async def get_recommendation_status(ctx: Context[Any, CitedContext, Any], job_id: str) -> Any:
|
|
36
43
|
"""Check the status of a recommendation job."""
|
|
37
44
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -43,7 +50,10 @@ async def get_recommendation_status(ctx: Context[Any, CitedContext, Any], job_id
|
|
|
43
50
|
return _api_error_response(e)
|
|
44
51
|
|
|
45
52
|
|
|
46
|
-
@mcp.tool(
|
|
53
|
+
@mcp.tool(
|
|
54
|
+
title="Get Recommendation Results",
|
|
55
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
56
|
+
)
|
|
47
57
|
async def get_recommendation_result(ctx: Context[Any, CitedContext, Any], job_id: str) -> Any:
|
|
48
58
|
"""Get the full results of a completed recommendation job."""
|
|
49
59
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -55,7 +65,10 @@ async def get_recommendation_result(ctx: Context[Any, CitedContext, Any], job_id
|
|
|
55
65
|
return _api_error_response(e)
|
|
56
66
|
|
|
57
67
|
|
|
58
|
-
@mcp.tool(
|
|
68
|
+
@mcp.tool(
|
|
69
|
+
title="Get Recommendation Insights",
|
|
70
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
71
|
+
)
|
|
59
72
|
async def get_recommendation_insights(ctx: Context[Any, CitedContext, Any], job_id: str) -> Any:
|
|
60
73
|
"""Get actionable insights from a recommendation, with source_type and source_id for solutions.
|
|
61
74
|
|
|
@@ -96,7 +109,10 @@ async def get_recommendation_insights(ctx: Context[Any, CitedContext, Any], job_
|
|
|
96
109
|
return insights
|
|
97
110
|
|
|
98
111
|
|
|
99
|
-
@mcp.tool(
|
|
112
|
+
@mcp.tool(
|
|
113
|
+
title="List Recommendations",
|
|
114
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
115
|
+
)
|
|
100
116
|
async def list_recommendations(
|
|
101
117
|
ctx: Context[Any, CitedContext, Any], audit_job_id: str
|
|
102
118
|
) -> Any:
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
5
|
from mcp.server.fastmcp import Context
|
|
6
|
+
from mcp.types import ToolAnnotations
|
|
6
7
|
|
|
7
8
|
from cited_core.api import endpoints
|
|
8
9
|
from cited_core.errors import CitedAPIError
|
|
@@ -11,7 +12,10 @@ from cited_mcp.server import mcp
|
|
|
11
12
|
from cited_mcp.tools._helpers import _api_error_response, _auth_check, _get_ctx
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
@mcp.tool(
|
|
15
|
+
@mcp.tool(
|
|
16
|
+
title="Start Solution",
|
|
17
|
+
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False, openWorldHint=False),
|
|
18
|
+
)
|
|
15
19
|
async def start_solution(
|
|
16
20
|
ctx: Context[Any, CitedContext, Any],
|
|
17
21
|
recommendation_job_id: str,
|
|
@@ -42,7 +46,10 @@ async def start_solution(
|
|
|
42
46
|
return _api_error_response(e)
|
|
43
47
|
|
|
44
48
|
|
|
45
|
-
@mcp.tool(
|
|
49
|
+
@mcp.tool(
|
|
50
|
+
title="Get Solution Status",
|
|
51
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
52
|
+
)
|
|
46
53
|
async def get_solution_status(ctx: Context[Any, CitedContext, Any], job_id: str) -> Any:
|
|
47
54
|
"""Check the status of a solution generation job."""
|
|
48
55
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -54,7 +61,10 @@ async def get_solution_status(ctx: Context[Any, CitedContext, Any], job_id: str)
|
|
|
54
61
|
return _api_error_response(e)
|
|
55
62
|
|
|
56
63
|
|
|
57
|
-
@mcp.tool(
|
|
64
|
+
@mcp.tool(
|
|
65
|
+
title="Get Solution Results",
|
|
66
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
67
|
+
)
|
|
58
68
|
async def get_solution_result(ctx: Context[Any, CitedContext, Any], job_id: str) -> Any:
|
|
59
69
|
"""Get the results of a completed solution generation job."""
|
|
60
70
|
cited_ctx = _get_ctx(ctx)
|
|
@@ -66,7 +76,10 @@ async def get_solution_result(ctx: Context[Any, CitedContext, Any], job_id: str)
|
|
|
66
76
|
return _api_error_response(e)
|
|
67
77
|
|
|
68
78
|
|
|
69
|
-
@mcp.tool(
|
|
79
|
+
@mcp.tool(
|
|
80
|
+
title="List Solutions",
|
|
81
|
+
annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False),
|
|
82
|
+
)
|
|
70
83
|
async def list_solutions(
|
|
71
84
|
ctx: Context[Any, CitedContext, Any],
|
|
72
85
|
business_id: str | None = None,
|
|
@@ -4,14 +4,14 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cited-cli"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.4"
|
|
8
8
|
description = "CLI for the Cited GEO platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "LicenseRef-Proprietary"
|
|
11
11
|
requires-python = ">=3.11"
|
|
12
12
|
authors = [{ name = "Cited", email = "support@youcited.com" }]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"cited-core>=0.3.
|
|
14
|
+
"cited-core>=0.3.4",
|
|
15
15
|
"typer>=0.15.0",
|
|
16
16
|
"rich>=13.0.0",
|
|
17
17
|
]
|
|
@@ -20,13 +20,13 @@ dependencies = [
|
|
|
20
20
|
cited = "cited_cli.app:main"
|
|
21
21
|
|
|
22
22
|
[project.optional-dependencies]
|
|
23
|
-
mcp = ["cited-mcp>=0.3.
|
|
23
|
+
mcp = ["cited-mcp>=0.3.4"]
|
|
24
24
|
dev = [
|
|
25
25
|
"pytest>=8.0",
|
|
26
26
|
"respx>=0.21",
|
|
27
27
|
"ruff>=0.4",
|
|
28
28
|
"mypy>=1.10",
|
|
29
|
-
"cited-mcp>=0.3.
|
|
29
|
+
"cited-mcp>=0.3.4",
|
|
30
30
|
]
|
|
31
31
|
|
|
32
32
|
[tool.hatch.build.targets.wheel]
|