Skip to content
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ To use an existing database, set `DATABASE_URL` in `.env` and skip the Docker st
- **Hosted MCP connectors (24):** click **Enable** in the console. Connany registers an OAuth client with the provider (RFC 7591), using a public client with PKCE or a confidential client as the provider requires.
- **GitHub:** create a GitHub App and enter its Client ID, Client Secret and App slug in the console. Users also install the App and choose repositories.

The list is also available to agents through `GET /v1/connectors` (enabled connectors with localized categories and descriptions, `lang=en|zh-CN`).
The list is also available to agents through `GET /v1/connectors` (enabled connectors with localized categories and descriptions, `lang=en|zh-CN|zh-HK`).

After enabling a connector, click **Sync tool catalog** on its card once: upstream MCP servers list tools only to signed-in users, so you authorize with your own account and Connany keeps only the tool definitions. Users must still authorize their own accounts. GitHub repository access also requires installing the App and selecting repositories. See the [connector setup guide (Chinese)](docs/connector-setup.md).

Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ npm run dev # 或:make dev
- **托管 MCP 连接器(24 个):** 后台点「启用」即可。Connany 按平台要求自动注册 OAuth 客户端(RFC 7591),使用公开客户端 + PKCE 或带密钥的机密客户端。
- **GitHub:** 创建 GitHub App,在后台填写 Client ID、Client Secret 和 App slug;用户还需安装 App 并选择仓库。

Agent 也可以通过 `GET /v1/connectors` 获取已启用的连接器,包含多语言的分类和说明(`lang=en|zh-CN`)。
Agent 也可以通过 `GET /v1/connectors` 获取已启用的连接器,包含多语言的分类和说明(`lang=en|zh-CN|zh-HK`)。

启用连接器后,在卡片上点一次「同步工具目录」:上游 MCP 只向已登录用户提供工具列表,所以用你自己的账号授权一次,Connany 只保存工具定义。用户仍需授权自己的账号;GitHub 仓库访问还需要安装 App 并选择仓库。详见 [连接器配置](docs/connector-setup.md)。

Expand Down
2 changes: 1 addition & 1 deletion docs/agent-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const { categories, data: connectors } = await connany.connectors({ lang: 'zh-CN
// [{ name: 'notion', title: 'Notion', description: '页面、数据库与工作区搜索', avatar_url: 'https://…/connectors/notion/avatar.svg', tools_synced_at: … }, …]
```

对应 `GET /v1/connectors?lang=zh-CN`,只返回管理员已启用的连接器。`categories` 是这些连接器所属的分类(按推荐顺序),可以用来分组展示;分类名称和连接器描述按 `lang` 返回中文或英文,不传时按 `Accept-Language`,默认英文。用 `title`、`description` 和 `avatar_url` 渲染「连接账号」入口(`avatar_url` 可直接放进 `<img>`)。如果想在用户连接之前介绍某个连接器能做什么,可以读工具目录 `connany.toolCatalog({ connector: 'notion' })`(`GET /v1/tools?connector=notion`)。
对应 `GET /v1/connectors?lang=zh-CN`,只返回管理员已启用的连接器。`categories` 是这些连接器所属的分类(按推荐顺序),可以用来分组展示;分类名称和连接器描述按 `lang` 返回英文(`en`)、简体中文(`zh-CN`)或香港繁体中文(`zh-HK`),不传时按 `Accept-Language`,默认英文。用 `title`、`description` 和 `avatar_url` 渲染「连接账号」入口(`avatar_url` 可直接放进 `<img>`)。如果想在用户连接之前介绍某个连接器能做什么,可以读工具目录 `connany.toolCatalog({ connector: 'notion' })`(`GET /v1/tools?connector=notion`)。

### 2.2 创建授权会话,把链接交给用户

Expand Down
2 changes: 1 addition & 1 deletion docs/api.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Returns the connectors an administrator has enabled, with their categories, read

| Query parameter | Type | Description |
| --- | --- | --- |
| lang | string, optional | Language of returned text: en or zh-CN. Without it the Accept-Language header decides; English otherwise |
| lang | string, optional | Language of returned text: en, zh-CN or zh-HK (Traditional Chinese, Hong Kong). Without it the Accept-Language header decides: zh-TW, zh-MO and zh-Hant return zh-HK, other Chinese tags return zh-CN; English otherwise |

Request example:

Expand Down
2 changes: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ JSON 请求使用 Content-Type: application/json,请求体上限 32 KB。每

| Query 参数 | 类型 | 说明 |
| --- | --- | --- |
| lang | string,可选 | 返回文字的语言:en 或 zh-CN。不传时按请求头 Accept-Language 选择,都没有时为英文 |
| lang | string,可选 | 返回文字的语言:en、zh-CN 或 zh-HK(香港繁体中文)。不传时按请求头 Accept-Language 选择:zh-TW、zh-MO、zh-Hant 返回 zh-HK,其他中文返回 zh-CN,都没有时为英文 |

请求示例:

Expand Down
11 changes: 9 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"dependencies": {
"@hono/node-server": "^2.1.1",
"hono": "^4.13.9",
"opencc-js": "^1.4.2",
"pg": "^8.23.0",
"zod": "^4.6.5"
},
Expand Down
85 changes: 53 additions & 32 deletions public/admin-i18n.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/admin.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 11 additions & 5 deletions public/docs.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
(() => {
const language = document.documentElement.lang;
const messages = {
'zh-CN': {copied:'已复制',selected:'已选中,请手动复制',failed:'复制失败,请下载 Markdown'},
'zh-HK': {copied:'已複製',selected:'已選取,請手動複製',failed:'複製失敗,請下載 Markdown'},
en: {copied:'Copied',selected:'Text selected. Copy it manually.',failed:'Copy failed. Download the Markdown instead.'}
};
const t = key => (messages[language] || messages.en)[key];
const picker = document.querySelector('#docs-language');
const url = new URL(location.href);
if (!url.searchParams.has('lang')) {
try { if(localStorage.getItem('connany.language')==='zh-CN'){url.searchParams.set('lang','zh-CN');location.replace(url);return;} } catch {}
try { const saved=localStorage.getItem('connany.language');if(['zh-CN','zh-HK'].includes(saved)){url.searchParams.set('lang',saved);location.replace(url);return;} } catch {}
}
picker?.addEventListener('change',()=>{
try { localStorage.setItem('connany.language',picker.value); } catch {}
Expand All @@ -13,15 +19,15 @@
document.querySelectorAll('[data-copy-code]').forEach(button => button.addEventListener('click',async()=>{
const code=button.closest('.docs-code').querySelector('pre code');
const status=document.getElementById('copy-status');
try { await navigator.clipboard.writeText(code.textContent);status.textContent=language==='zh-CN'?'已复制':'Copied'; }
catch { const range=document.createRange();range.selectNodeContents(code);getSelection().removeAllRanges();getSelection().addRange(range);status.textContent=language==='zh-CN'?'已选中,请手动复制':'Text selected. Copy it manually.'; }
try { await navigator.clipboard.writeText(code.textContent);status.textContent=t('copied'); }
catch { const range=document.createRange();range.selectNodeContents(code);getSelection().removeAllRanges();getSelection().addRange(range);status.textContent=t('selected'); }
clearTimeout(timer);timer=setTimeout(()=>status.textContent='',2500);
}));
document.querySelectorAll('[data-copy-target]').forEach(button => button.addEventListener('click',async()=>{
const source=document.getElementById(button.dataset.copyTarget);
const status=document.getElementById('copy-status');
try { await navigator.clipboard.writeText(source.value);status.textContent=language==='zh-CN'?'已复制':'Copied'; }
catch { status.textContent=language==='zh-CN'?'复制失败,请下载 Markdown':'Copy failed. Download the Markdown instead.'; }
try { await navigator.clipboard.writeText(source.value);status.textContent=t('copied'); }
catch { status.textContent=t('failed'); }
clearTimeout(timer);timer=setTimeout(()=>status.textContent='',2500);
}));
const links=[...document.querySelectorAll('.docs-layout>nav a')];
Expand Down
2 changes: 1 addition & 1 deletion sdk/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class Connany {
return result as T;
}
/** Enabled connectors and their categories. Descriptions and category titles follow `lang` (default English). */
connectors(options: { lang?: 'en' | 'zh-CN' } = {}) {
connectors(options: { lang?: 'en' | 'zh-CN' | 'zh-HK' } = {}) {
return this.request<{ categories: { name: ConnectorCategory; title: string }[]; data: { name: ConnectorName; title: string; category: ConnectorCategory; description: string; avatar_url: string; tools_synced_at: string | null }[] }>(`/v1/connectors${options.lang ? `?${new URLSearchParams({ lang: options.lang })}` : ''}`);
}
/** Tools the user can use now through an authorized connection. Use this in agent conversations. */
Expand Down
Loading